魯姆普爾史蒂爾特金》是最著名的德國童話之一。格林兄弟,雅各和威廉,於1812年首次將這個故事(德語: Rumpelstilzchen )收錄在他們的童話集《兒童與家庭故事集》中。他們並非這個故事的原創者。他們記錄的是一個更古老的歐洲民間故事,這個故事已經口耳相傳了好幾代。民俗學家將其歸類為ATU 500型故事,即「幫手的名字」故事。這種故事模式在歐洲各地的故事中都很常見,講述的是一個神奇的幫手,只有找到他的秘密名字才能打敗他。格林兄弟在不同的版本中對故事進行了修改,因此結局有所不同:在一些後來的德語版本中,小矮人魯姆普爾斯蒂爾特金憤怒地將自己撕成兩半;而在這部經典的英文譯本中,他跺腳踩穿地板,然後怒氣沖沖地離開了。
⬆️ Go up: /usr
#!/opt/cloudlinux/venv/bin/python3 -sbb
# coding=utf-8
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import subprocess
import sys
import getopt
import os
from clselect import (
clpassenger,
clprint,
clselectctl,
clselectctlphp,
clselectctlpython,
clselectctlruby,
utils,
)
from clselect.utils import CAGEFS_ENTER_USER_BIN
from clcommon import clcagefs
from clcommon.cpapi import Feature, is_panel_feature_supported
def selector_executed_as_root():
"""
We check whos run selector: root or user
:return: True if root, False if user
"""
return os.geteuid() == 0
def _run_selectorctl_as_user_in_cagefs(user):
"""
All user-related actions must run inside
of cagefs for security reasons.
When selector is executed as root and we
know username, we start new subprocess using su.
But when selector is started by user and
selectorctl is NOT in cagefs, we force cagefs_enter.
"""
if selector_executed_as_root():
if user is None:
return
cmd = [CAGEFS_ENTER_USER_BIN, user] + sys.argv + ['--skip-cagefs-check']
elif not clcagefs.in_cagefs():
cmd = ['/bin/cagefs_enter'] + sys.argv + ['--skip-cagefs-check']
else:
return
p = subprocess.Popen(cmd, stdout=sys.stdout, stdin=sys.stdin, env={})
p.communicate()
sys.exit(p.returncode)
def usage():
print('Usage: ' + sys.argv[0] + ' [OPTIONS]')
print('Options:')
print()
print(' -i | --interpreter : Interpreter. If omitted php implied')
print(' -h | --help : Show this message')
print(' -A | --fix-homedir : Fix paths after home directory change')
print()
print('According to selected interpreter options differs')
print(' PHP:')
clselectctlphp.usage()
print()
print(' Python:')
clselectctlpython.usage()
print()
print(' Ruby:')
clselectctlruby.usage()
def main():
try:
opts, args = getopt.getopt(
sys.argv[1:],
'hi:lSsCcB:Y:N:E:D:R:v:Gu:b:ge:d:r:atpVLT:k:m:x:QqPjwWzynfFZo:AK:U', [
'help',
'setup-without-cagefs',
'revert-to-cagefs',
'interpreter=',
'list',
'list-user-webapps',
'summary',
'user-summary',
'current',
'user-current',
'set-current=',
'enable-alternative=',
'disable-alternative=',
'enable-extensions=',
'disable-extensions=',
'replace-extensions=',
'version=',
'list-extensions',
'user=',
'domain=',
'set-user-current=',
'list-user-extensions',
'enable-user-extensions=',
'disable-user-extensions=',
'replace-user-extensions=',
'all',
'reset-user-extensions',
'print-summary',
'show-native-version',
'list-users',
'change-to-version=',
'add-options=',
'replace-options=',
'delete-options=',
'base64',
'quiet',
'print-options',
'print-options-safe',
'apply-symlinks-rules',
'json',
'csv',
'perl',
'api-version=',
'verbose',
'reset-options',
'create-webapp',
'update-interpreter',
'destroy-webapp',
'relocate-webapp',
'transit-webapp',
'restart-webapp',
'start-webapp',
'stop-webapp',
'setup-wsgi=',
'fix-homedir',
'list-extensions-version=',
'recreate-virtualenv',
'freeze-requirements',
'update-backup',
'apply-global-php-ini',
'app-mode=',
'startup-file=',
'env-vars=',
'set-variables',
'skip-cagefs-check',
'exclude-pid-list=',
'for-all-users'
])
except getopt.GetoptError:
usage()
sys.exit(1)
action = None
interpreter = 'php'
fmt = 'text'
user = None
domain = None
# getopt is a little bit stupid parser
# after a non-option argument, all further arguments are
# considered also non-options
# so sometimes my '--skip' option was ignored
#
# Scanner note (F-01, CLOS-5515, 2026-07-17): argv-driven --skip-cagefs-check
# is not an implicit-trust marker. `selectorctl` is only reachable via the
# %clsudoers NOPASSWD alias, whose membership is pinned to panel admins()
# + package-owned service accounts by commons/lib/lvemanager/sudoers.py:326
# (cPanel admins()={root}; DA/Plesk admins already hold root-equivalent
# NOPASSWD). No privilege boundary is crossed by the flag.
skip_enter_cagefs = '--skip-cagefs-check' in sys.argv
if skip_enter_cagefs:
sys.argv.remove('--skip-cagefs-check')
# Catch this options in any position
if '-h' in sys.argv or '--help' in sys.argv:
usage()
sys.exit(0)
for o, a in opts:
if o in ['-i', '--interpreter']:
interpreter = a.lower()
elif o in ['-j', '--json']:
fmt = 'json'
elif o in ['-w', '--csv']:
fmt = 'csv'
elif o in ['-W', '--perl']:
fmt = 'perl'
elif o in ['-A', '--fix-homedir']:
action = 'fix-homedir'
elif o == '--update-interpreter':
action = 'update-interpreter'
elif o in ['-u', '--user']:
user = a
elif o == '--domain':
domain = a
if interpreter == 'php':
if not is_panel_feature_supported(Feature.PHP_SELECTOR):
clprint.print_diag(
fmt,
{'status': 'ERROR',
'details': 'selectorctl for php interpreter is not supported in current environment'
}
)
sys.exit(0)
else:
return clselectctlphp.main()
# Skip special "wildcard user" that is used only with "update-interpreter"
if not (action == 'update-interpreter' and user == '*'):
user, _ = utils.safely_resolve_username_and_doc_root(
user, domain, fmt, True)
if not skip_enter_cagefs and \
(interpreter in ['ruby', 'nodejs']
or (interpreter == 'python' and not action == 'update-interpreter')):
_run_selectorctl_as_user_in_cagefs(user)
if action == 'fix-homedir':
fix_homedir(user)
sys.exit()
if interpreter == 'python':
# no feature check here because "selectorctl utility for --interpreter python is deprecated. Only update-interpreter option is still possible to use"
# and update-interpreter silently does nothing or prints its own warning in case of unsupported environment
clselectctlpython.main()
elif interpreter == 'ruby':
if not is_panel_feature_supported(Feature.RUBY_SELECTOR):
clprint.print_diag(
fmt,
{'status': 'ERROR',
'details': 'selectorctl for ruby interpreter is not supported in current environment'
}
)
sys.exit(0)
else:
clselectctlruby.main()
elif interpreter == 'nodejs':
clprint.print_diag(
fmt, {'status': 'ERROR',
'details': 'For --interpreter nodejs please use cloudlinux-selector utility instead'})
sys.exit(1)
else:
clprint.print_diag(
fmt, {'status': 'ERROR', 'message': 'Unknown interpreter'})
sys.exit(1)
def fix_homedir(user):
user = clselectctl.get_user(user)
clpassenger.fix_homedir(user)
clselectctlpython.fix_homedir(user)
if __name__ == '__main__':
main()
Authentication Required