§ öÒjÅËãó —ddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl mZmZmZmZmZddlmZddlmZddlZd d lmZd d lmZd d lmZdd lmZm Z d dl!m"Z"d dlm#Z#ddlm$Z$ddl%m&Z&ddl'm(Z(m)Z)m*Z*ddl+m,Z,m-Z-m.Z. ddl/m0Z0ddl1m2Z2ddl3m4Z4m5Z5m6Z6ddl7m8Z8n#e9$rd„Z4YnwxYw ddl3m:Z:n#e9$rd„Z:YnwxYw ddl;mZ>n#e9$rd„ZYnwxYwGd„de¦«Z?dS) é)Úprint_function)Úabsolute_import)ÚdivisionN)Ú configparser)ÚS_IRUSRÚS_IWUSRÚS_IRGRPÚS_IROTHÚS_ISREG)Ú iteritems)ÚPathé)ÚClSelect)ÚClSelectExcept)Úmultiphp_sync_client)ÚClPwdÚ clcaptain)Úclprint)Úutils)Úclcagefs)ÚExternalProgramFailed)ÚdocrootÚ domain_ownerÚ userdomains)ÚNoDomainÚ NoPanelUserÚ NotSupported)ÚBASEDIR)Úget_user_prefix)Úis_ea4_enabledÚread_cpanel_ea4_php_confÚconfigure_alt_php)Úda_change_user_php_inicó—dS©NF©©ÚargsÚkwargss úL/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/cluserselect.pyr r ,s€Øˆuó)Únative_website_targetscó—iS©Nr&r's r*r,r,8s€Øˆ r+)Úget_website_id)Úload_user_configcó—dSr.r&)Ú_s r*úr3?s€˜t€r+cóº—eZdZdZdZej¦«rendZdZdZ d5d„Z d6d „Z d „Z d7d „Z d8d„Zd9d„Zd9d„Zd„Zd„Zd„Zd„Zd„Zd„Z d:d„Zd:d„Zdedefd„Zd9d„Zd„Zd„Zd„Zd „Zd!„Z d"„Z!d;d#„Z"dÚ ClUserSelectz /var/cagefsz /usr/selectorz'/usr/share/cagefs-skeleton/usr/selectorz/etc/cagefs/excludez.cl.selector/selector.pathNcó\—tj¦«s!tj d¦«sdS|D]ô}|j |¦«}tj |jd¦«}tj |¦«s”|  |¦«} tj |¦«n.#ttf$r}tj||¦«‚d}~wwxYw t  |¦«ŒÕ#t  |¦«wxYwŒõdS)zý Creates flags mod_lsapi_reset_me in users' home directories in order to recreate CRIU images when php version/extensions/options have changed For details see LVEMAN-1210 :param users: list of usernames (strings) z/var/run/mod_lsapi/criu.enabledNÚmod_lsapi_reset_me)rÚ in_cagefsÚosÚpathÚisfileÚ_clpwdÚget_pw_by_nameÚjoinÚpw_dirÚ _change_uidrÚwriteÚOSErrorrrÚUnableToSaveDatar5Ú _restore_uid)ÚselfÚusersÚuserÚpwr:Úprevious_user_dataÚes r*Úclean_crui_imageszClUserSelect.clean_crui_imagesJs:€õÔ!Ñ#Ô#ð ­B¬G¯NªNÐ;\Ñ,]Ô,]ð Ø ˆFØð Bð BˆDØ”×+Ò+¨DÑ1Ô1ˆBÝ”7—<’< ¤ Ð+?Ñ@Ô@ˆDÝ”7—>’> $Ñ'Ô'ð BØ%)×%5Ò%5°dÑ%;Ô%;Ð"ðBÝ”O DÑ)Ô)Ð)Ð)øÝÕ!6Ð7ðCðCðCÝ(Ô9¸$ÀÑBÔBÐBøøøøðCøøøð*õ!×-Ò-Ð.@ÑAÔAÐAÐAø•L×-Ò-Ð.@ÑAÔAÐAÐAøøøð Bð Bð Bs*Â-CÃD ÃC-ÃC(Ã(C-Ã-D Ä D(Tc ó–—tj t¦«s;t j¦«s(t d¦«|rtjd¦«ndS|rut¦«rgt¦«}|rW |d}|  d¦«s(t d¦«|rtjd¦«ndSn#t$rYnwxYwt|||dtj¦«dk|¬ ¦«}|r|rtjd¦«|s®t�§t!t|j¦«j¦«} t'|j¦«} n#t(t*f$rg} YnwxYw| D]O\} } | | vrŒ t|| |j| ¦«p|| dtj¦«dk|¬ ¦«ŒP|S) z† Switch symlink for alt php. Create .cagefs directory if not created Rerurn True if error has occured úERROR: CageFS not installed.rTÚdefaultzea-phpzlERROR: system default PHP version is alt-php. PHP Selector is disabled. Use cPanel MultiPHP manager instead.Fr)Ú write_logÚ drop_permÚconfigure_multiphp)r9r:Úisdirrrr8ÚprintÚsysÚexitr r!Ú startswithÚKeyErrorr"Úgeteuidr0ÚsetÚpw_nameÚenabled_websitesrrrÚ_website_selected_version) rEÚversionrHÚ document_rootÚ exit_on_errorrQÚconfÚ default_phpÚerrorÚisolated_domainsÚtarget_domainsÚdomainÚdomain_docroots r*Úswitch_symlink_for_alt_phpz'ClUserSelect.switch_symlink_for_alt_phpbs1€õ Œw�}Š}�WÑ%Ô%ð ­hÔ.@Ñ.BÔ.Bð Ý Ð0Ñ 1Ô 1Ð 1Øð Ý”˜‘ ” � � à�tà ð ¥.Ñ"2Ô"2ð Ý+Ñ-Ô-ˆDØð ðà"& y¤/�Kà&×1Ò1°(Ñ;Ô;ð(Ýð]ñôðð)ð(ÝœH Q™KœK˜K˜Kà#' 4øøÝðððØ�Dðøøøõ"Ø �˜ØÝ”z‘|”| qÒ(Ø1ð  ñ ô ˆð ð �]ð Ý ŒH�Q‰KŒKˆKðð& Õ!1Ð!=Ý"Õ#3°B´JÑ#?Ô#?Ô#PÑQÔQÐ ð  $Ý!,¨R¬ZÑ!8Ô!8��øÝ¥Ð.ð $ð $ð $Ø!#���ð $øøøð+9ð ð Ñ&�˜ØÐ!1Ð1Ð1Øõ$"ØØ×2Ò2°2´:¸~ÑNÔNÐYÐRYØ"Ø#Ý!œz™|œ|¨qÒ0Ø'9ð ñôðððˆ s%ÂACà CÃCÅ EÅE4Å3E4có¦—|jr#td¦«tjd¦«t j¦«dkr#td¦«tjd¦«| ¦«}t|¦«D]H\}}td|¦«|j  |¦«}|  ||dd¬¦«ŒIdS)NzPERROR: this option does not work in "single user" mode (when CageFS is disabled)rrzERROR: root privileges requiredzProcessing userF)r_rQ) Úwithout_cagefsrSrTrUr9rXÚget_user_version_mapr r<r=rg)rEÚusers_vers_dictrGr]rHs r*Úapply_symlinks_rulesz!ClUserSelect.apply_symlinks_rules¸s×€Ø Ô ð Ý ÐdÑ eÔ eÐ eÝ ŒH�Q‰KŒKˆKÝ Œ:‰<Œ<˜1Ò Ð Ý Ð3Ñ 4Ô 4Ð 4Ý ŒH�Q‰KŒKˆKØ×3Ò3Ñ5Ô5ˆÝ& Ñ7Ô7ð hð h‰MˆD�'Ý Ð# TÑ *Ô *Ð *Ø”×+Ò+¨DÑ1Ô1ˆBØ × +Ò +¨G°RÀuÐafÐ +Ñ gÔ gÐ gÐ gð hð hr+Úphpcó —tj||¦«t¦«|_t ¦«|_|r ||_dSg|_dSr.)rÚ__init__rr<rYÚ_user_excludesÚexclude_pid_list)rEÚitemrqs r*rozClUserSelect.__init__ÅsP€ÝÔ˜$ Ñ%Ô%Ð%Ý‘g”gˆŒ Ý!™eœeˆÔØ ð 'Ø$4ˆDÔ !Ð !Ð !à$&ˆDÔ !Ð !Ð !r+FcóF—| |¦«| |¦«}|r`| ||¦«rJ| |t|¦«d¦«}tj |¦«r|}| ||¦«S)zl Returns alternative version for a user @param user: string @return: string r)Ú_check_user_in_cagefsÚ_compose_user_alt_pathÚwebsite_isolation_enabledrr9r:rRÚ_version_at_alt_path)rErGreÚshow_native_versionÚalt_pathÚ website_paths r*Ú get_versionzClUserSelect.get_versionÎsž€ð ×"Ò" 4Ñ(Ô(Ð(Ø×.Ò.¨tÑ4Ô4ˆð ð (�d×4Ò4°T¸6ÑBÔBð (Ø×6Ò6°t½WÀV¹_¼_ÈQÔ=OÑPÔPˆLÝŒw�}Š}˜\Ñ*Ô*ð (Ø'�Ø×(Ò(¨Ð3FÑGÔGÐGr+cól—tj |¦«s| |¦«Stj ||j¦«}tj |¦«s| |¦«S| tj|¦«|¦«S)axResolves the alternative a selector directory currently points at. Split out of ``get_version`` so the per-website scope can be read from a document root the caller already has, without re-resolving a domain through the panel API. ``alt_path`` is an account-level ``etc/cl.selector`` or a per-website ``etc/cl.selector/``. ) r9r:rRÚ_compose_native_infor>Ú_itemÚislinkÚ_version_for_link_targetÚreadlink)rEryrxÚ full_paths r*rwz!ClUserSelect._version_at_alt_pathãs”€õŒw�}Š}˜XÑ&Ô&ð BØ×,Ò,Ð-@ÑAÔAÐ AÝ”G—L’L ¨4¬:Ñ6Ô6ˆ ÝŒw�~Š~˜iÑ(Ô(ð BØ×,Ò,Ð-@ÑAÔAÐ AØ×,Ò,­R¬[¸Ñ-CÔ-CÐEXÑYÔYÐYr+c ó@‡‡‡—‰ |¦«}‰jr9‰js‰ ‰j¦«‰‰j‰jkr|St j ‰¦«‰jkr|S‰  ¦«Š ttˆˆˆfd„t‰  ¦«¦«¦«¦«d}|‰|d‰|d‰jfS#ttf$r|cYSwxYw)a,Resolves the alternative a primary ```` link target names. Split off from ``_version_at_alt_path`` so a caller holding a target it has already read can resolve *that* target instead of re-reading the link. The re-read is not equivalent: CageFS rewrites these links unlink-then-symlink, so a second look can find the link gone and answer ``native`` -- the reading for a selector directory that holds no selection -- where the target in hand still names the alternative the website ran. có>•—‰|d‰j‰kS)NÚdata)r~)ÚiÚ alternativesÚlink_dstrEs €€€r*r3z7ClUserSelect._version_for_link_target..sø€ ,¨q¤/°&Ô"9¸$¼*Ô"EÈÒ"Q€r+rr]r…)r}riÚ_native_contentsÚ_load_native_contentsr~r9r:ÚdirnameÚ SELECTOR_PATHÚget_all_alternatives_dataÚlistÚfilterÚkeysÚ IndexErrorrW)rErˆrxÚnativer]r‡s`` @r*r€z%ClUserSelect._version_for_link_targetòs8øøø€ð×*Ò*Ð+>Ñ?Ô?ˆØ Ô ð ØÔ(ð 7Ø×*Ò*¨4¬:Ñ6Ô6Ð6ؘ4Ô0°´Ô<Ò<Ð<Ø� Ý Œ7�?Š?˜8Ñ $Ô $¨Ô(:Ò :Ð :؈MØ×5Ò5Ñ7Ô7ˆ ð ÝÝÐQÐQÐQÐQÐQÐQÕTXÐYe×YjÒYjÑYlÔYlÑTmÔTmÑnÔnñôàôˆGð˜\¨'Ô2°9Ô=¸|ÈGÔ?TÐU[Ô?\Ð]aÔ]gÔ?hÐiÐ iøÝ�HÐ%ð ð ð ØˆMˆMˆMð øøøsÂA.DÄDÄDcó’—| ||¦«}tj ||j¦«}tj |¦«sdS tj|¦«}n#t$rYdSwxYwtj |¦«|j krdS|  |¦«dS)aÌPHP version a website has selected for itself, or None to follow the account-level one. Reads the website's own selector directory -- the very tree ``configure_alt_php`` is about to write ``link/conf`` into -- so the answer is what the website *runs*, which is what those symlinks have to agree with. The primary ```` link is the evidence of a per-domain selection: ``_set_version`` creates it for a per-domain set, and CageFS re-creates it on its own sweep. Its absence (no directory at all, or a directory holding only the cPanel-MultiPHP ``ea-*`` aliases that an account-level save writes there) means the website has made no selection, so the account-level version is the right input. So does a primary link routed through ``/usr/selector`` -- see below: that encoding resolves to the account's own selection rather than pinning anything, so such a website follows the account too. CLOS-3932 made per-domain PHP Selector default-on for every isolated website, so isolation alone no longer implies a selection -- which is why this has to be asked per website rather than inferred. Nr) rur9r:r>r~rr�rBr‹rŒr€)rErGr^ryÚlinkrˆs r*r\z&ClUserSelect._website_selected_versionsÅ€ð*×.Ò.¨t°]ÑCÔCˆÝŒw�|Š|˜H d¤jÑ1Ô1ˆÝŒw�~Š~˜dÑ#Ô#ð Ø�4ð Ý”{ 4Ñ(Ô(ˆHˆHøÝð ð ð ð�4�4ð øøøõ Œ7�?Š?˜8Ñ $Ô $¨Ô(:Ò :Ð :ð*�4ð×,Ò,¨XÑ6Ô6°qÔ9Ð9sÁA3Á3 BÂBcón—tj |¦«s•| |¦«} t j|¦«n.#t tf$r}tj ||¦«‚d}~wwxYw t  |¦«dS#t  |¦«wxYwdSr.) r9r:rRr@rÚmkdirrBrrrCr5rD)rEr:rGrIrJs r*Ú create_dirzClUserSelect.create_dir[sÀÝŒw�}Š}˜TÑ"Ô"ð >Ø!%×!1Ò!1°$Ñ!7Ô!7Ð ð >Ý” Ñ%Ô%Ð%Ð%øÝÕ2Ð3ð ?ð ?ð ?Ý$Ô5°d¸AÑ>Ô>Ð>øøøøð ?øøøð&õ×)Ò)Ð*<Ñ=Ô=Ð=Ð=Ð=ø• ×)Ò)Ð*<Ñ=Ô=Ð=Ð=øøøð >ð >s)¶A Á BÁ A6ÁA1Á1A6Á6BÂB2cóp—|j |¦«}tj ||j¦«}| |¦«}| ||¦«| d|dzd¬¦«| d|dzd¬¦«|  |¦«dS)z\ Creates additional directory and symlinks for use in "without CageFS" mode z ../php-cliz/phpT)Úcheck_existencez../phpz/php-cgiN) r<Ú get_homedirr9r:r>Ú SELECTOR2_DIRr@r—Ú_create_symlinkrD)rErGÚhomedirÚ path_in_homeÚcur_users r*Úcreate_selector_symlinksz%ClUserSelect.create_selector_symlinkses´€ð”+×)Ò)¨$Ñ/Ô/ˆÝ”w—|’| G¨TÔ-?Ñ@Ô@ˆ Ø×#Ò# DÑ)Ô)ˆØ �Š˜  dÑ+Ô+Ð+Ø ×Ò˜\¨<¸&Ñ+@ÐRVÐÑWÔWÐWØ ×Ò˜X |°jÑ'@ÐRVÐÑWÔWÐWØ ×Ò˜(Ñ#Ô#Ð#Ð#Ð#r+cóà—tj tj¦«rD |j d|j¦«S#tj ttf$rYdSwxYwdS)NÚversionsr’) r9r:r;rÚ DEFAULTS_PATHÚ_dhÚgetr~Ú ConfigParserÚErrorÚIOErrorrW)rEs r*Úget_default_versionz ClUserSelect.get_default_versionqsi€Ý Œ7�>Š>�(Ô0Ñ 1Ô 1ð ð Ø”x—|’| J°´ Ñ;Ô;Ð;øÝ Ô&­µÐ:ð ð ð Ø�x�xð øøøàˆxs«A Á A+Á*A+cóˆ—tj |j |¦«dd¦«} tj|¦«}n#t $rd}YnwxYw|�t|j¦«s*|  ||  ¦«¦«dS |  |¦«}|  ||  d|j ¦«¦«dS#tjt t"f$r<}t%dt'|¦«¦«t)jd¦«Yd}~dSd}~wwxYw)Nú .cl.selectorú defaults.cfgr¢z*Error while restoring settings from backupr)r9r:r>r<ršÚlstatrBr Úst_modeÚ set_versionr©Ú_get_default_config_handlerr¥r~r¦r§r¨rWrSÚstrrTrU)rErGÚuser_backup_pathÚstÚdhrJs r*Úset_version_from_backupz$ClUserSelect.set_version_from_backupys?€Ýœ7Ÿ<š<¨¬ ×(?Ò(?ÀÑ(EÔ(EÀ~ÐWeÑfÔfÐð Ý”Ð*Ñ+Ô+ˆBˆBøÝð ð ð ØˆBˆBˆBð øøøà ˆ:�W R¤ZÑ0Ô0ˆ:Ø × Ò ˜T 4×#;Ò#;Ñ#=Ô#=Ñ >Ô >Ð >Ð >Ð >ð Ø×5Ò5Ð6FÑGÔG�Ø× Ò   r§v¢v¨j¸$¼*Ñ'EÔ'EÑFÔFÐFÐFÐFøÝ Ô&­µÐ:ð ð ð ÝÐBÅCÈÁFÄFÑKÔKÐKÝ”˜‘ ” � � � � � � � øøøøð øøøs*»AÁ AÁAÂ#AC)Ã)EÄ1D<Ä<EcóR—|j |j›|›�d¦«sdSdS)aL" Checks if version is enabled, a version is considered "enabled" if there is no "state" option in the config. The presence of the "state" option always means it is disabled, regardless of its value. @param version: string @return: bool - True if version is enabled, False otherwise ÚstateTF)r¤Ú has_optionr~)rEr]s r*Ú_version_enabledzClUserSelect._version_enabled“s3€ðŒx×"Ò"¨T¬Z¨Z¸¸Ð#AÀ7ÑKÔKð Ø�4à�5r+c ó"—tj¦«dkr+| |¦«x}rtj|¦«‚| |¦«stjd|z¦«‚|rY t |¦«}n#t$rd}YnwxYw||krtjd|›d|›�¦«‚|  ||¦«|dkr*||  ¦«vrtj |¦«‚ | o$|dko|  |¦«d|k} n#t$rd} YnwxYw | rdntj|¦«} n.#tj$r} tjd| z¦«‚d} ~ wwxYw t#j|j|j |j |¦«¦«tj|||||¦«} tj|| ¬ ¦«n#tj|| ¬ ¦«wxYw|r| SdS) zz Sets alternative version for a users with the same uid @param user: string @return: None rz'Version %s is disabled by administratorNzDomain z does not belong to user r’FzPHP version was not changed: %s)Ú after_change)r9rXÚ"get_version_selection_disabled_msgrÚVersionModificationBlockedr¹rrÚSelectorExceptionÚ_require_website_isolationr�ÚNoSuchAlternativeVersionr{Ú ExceptionrÚrelease_for_changeÚHandBackFailedrÚapply_for_at_least_one_userÚ _set_versionr<Ú get_namesÚget_uidÚNoUserSelectorÚ notify_change) rErGr]reÚreturn_summaryrxr_ÚmessageÚownerÚstayingÚchangerJr…s r*r¯zClUserSelect.set_version¡sŽ€õ Œ:‰<Œ<˜1Ò Ð ¨T×-TÒ-TÐUYÑ-ZÔ-ZÐ"Z 'Ð Ý Ô;¸GÑDÔDÐ Dð×$Ò$ WÑ-Ô-ð qÝ Ô;ÐÔ*QÐRVÑ*WÔ*WˆFˆFøÝ#Ô2ð 7ð 7ð 7Ý Ô;Ø1°AÑ5ñ7ô7ð 7øøøøð 7øøøð JÝÔ4ØÔ!Ø” ×%Ò% d¤k×&9Ò&9¸$Ñ&?Ô&?Ñ@Ô@ÝÔ-ØØØØ#Øñ ô ˆDõ !Ô .¨tÀ&Ð IÑ IÔ IÐ IÐ IøÕ Ô .¨tÀ&Ð IÑ IÔ IÐ IÐ Iøøøà ð ØˆKð ð sIÁ2B BÂBÃ;(D$Ä$ D3Ä2D3Ä7EÅE;ÅE6Å6E;Å?AG0Ç0HcóÈ—|jr| |¦«}| |¦«d}|rt|¦«d}| ||¦«} t j | ¦«s4|js|r| | |¦«ntj |¦«‚|  ¦«} || vr|dkrtj |¦«‚|  | ¦«|j |¦«} |dk�r×|jr[|js| |j¦«t'|j¦«D]#\} } | | | dz| z||¦«Œ$�nÌ|rt+¦«ni}d}d}t j |j›d�|¦«}t j |¦«ro||vr ||}n(t j d|jz|¦«}t j | |¦«}| ||||¦«d }t j|j¦«D]Ž}|j|vrŒ | d ¦«r|rŒ$t j | |¦«}||vr ||}n%t j |j|¦«}| ||||¦«Œ�nWt'| |d ¦«D];\} }| |t j | | ¦«||¦«Œ<|jrt8 |¦«n/| || ||¬ ¦«| ||¦«|  |¦«| !||pd |¬¦«|r| "||¦«Sd S)zg Sets alternative version for a user @param user: string @return: None Úrr’ú/zphp.iniFz.etcz%s.etcTú.inir…)r^r_N)r^re)#rir@rtrrur9r:rRr—rrÈr�rÀÚ_remove_alternatives_linksr<r=r‰rŠr~r rœr,r>Ú NATIVE_PATHÚexistsrŒÚlistdirÚendswithr5rDrgÚ_switch_php_da_ispÚ_reload_processesÚ_backup_settingsÚ get_summary)rErGr]rerÊrxr_rIr^ryr‡rHrrÚ native_pathÚnative_targetsÚiniÚnew_ini_createdÚ new_ini_pathÚsrcÚdstÚfilenamer:s r*rÅzClUserSelect._set_versionès/€ð Ô ð 8Ø!%×!1Ò!1°$Ñ!7Ô!7Ð Ø ×"Ò" 4Ñ(Ô(Ð(؈ Ø ð /Ý# F™OœO¨AÔ.ˆMØ×.Ò.¨t°]ÑCÔCˆÝŒw�}Š}˜XÑ&Ô&ð :ØÔ"ð : fð :Ø—’ ¨$Ñ/Ô/Ð/Ð/å$Ô3°DÑ9Ô9Ð9Ø×5Ò5Ñ7Ô7ˆ Ø ˜,Ð &Ð &¨7°hÒ+>Ð+>Ý Ô9¸'ÑBÔBÐ BØ ×'Ò'¨Ñ1Ô1Ð1Ø Œ[× 'Ò '¨Ñ -Ô -ˆØ �hÒ Ñ ØÔ"ð( BØÔ,ð;Ø×.Ò.¨t¬zÑ:Ô:Ð:Ý)2°4Ô3HÑ)IÔ)Ið\ð\Ñ%�D˜+Ø×(Ò(¨°hÀ±nÀtÑ6KÈTÐSZÑ[Ô[Ð[Ð[ñ\ð>DÐ!KÕ!7Ñ!9Ô!9Ð!9È�Ø�Ø"'�Ý!œwŸ|š|¸Ô8HÐ8HÐ8HÐ,JÈCÑPÔP� Ý”7—>’> ,Ñ/Ô/ð+ؘnÐ,Ð,Ø,¨SÔ1˜˜å œgŸlšl¨8°dÔ6HÑ+HÈ#ÑNÔN˜Ýœ'Ÿ,š, x°Ñ5Ô5�CØ×(Ò(¨¨c°4¸ÑAÔAÐAØ&*�OÝ "¤ ¨4Ô+;Ñ <Ô <ð Bð B�HØ”z¨Ð1Ð1Ø Ø×(Ò(¨Ñ0Ô0ð!°_ð!Ø Ýœ'Ÿ,š, x°Ñ:Ô:�CØ >Ð1Ð1Ø,¨XÔ6˜˜å œgŸlšl¨4Ô+=¸xÑHÔH˜Ø×(Ò(¨¨c°4¸ÑAÔAÐAÐAð Bõ(¨ °WÔ(=¸fÔ(EÑFÔFð Xð X‘ ��dØ×$Ò$ T­2¬7¯<ª<¸À$Ñ+GÔ+GÈÈwÑWÔWÐWÐWà Ô ð 3Ý × %Ò %Ð&8Ñ 9Ô 9Ð 9Ð 9à × +Ò +¨G°RØ:GØ:Gð ,ñ Iô Ið Ið × #Ò # D¨'Ñ 2Ô 2Ð 2Ø ×Ò˜tÑ$Ô$Ð$Ø ×Ò˜d°-Ð2GÀ4ÐPVÐÑWÔWÐWà ð ?Ø×#Ò# DÐ*=Ñ>Ô>Ð >ð ?ð ?r+ÚusernameÚreturncón—|j |¦«}td|›d�¦«}| ¦«sdS | d¬¦«5}t j|¦«}| dd¦«cddd¦«S#1swxYwYdS#ttf$rYdSwxYw)aÒ Returns a message indicating that the selection of the PHP version is disabled for the user, based on the configuration file. Args: username (str): The username for which to check the configuration. Returns: str: The message indicating that version selection is disabled, or an empty string if the configuration file does not exist or does not contain the message. z!/var/cloudlinux/cl.selector/uids/z/version_selection_conf.jsonrÐzutf-8)ÚencodingÚversion_selection_disabled_msgN) r<rÇr rÕÚopenÚjsonÚloadr¥rBÚ ValueError)rEräÚuidÚ config_fileÚfÚ config_datas r*r¼z/ClUserSelect.get_version_selection_disabled_msg:s#€ðŒk×!Ò! (Ñ+Ô+ˆÝÐ`¸sÐ`Ð`Ð`ÑaÔaˆ Ø×!Ò!Ñ#Ô#ð Ø�2ð Ø×!Ò!¨7Ð!Ñ3Ô3ð M°qÝ"œi¨™lœl� Ø"—’Ð'GÈÑLÔLð Mð Mð Mð Mñ Mô Mð Mð Mð Mð Mð Mð Møøøð Mð Mð Mð Mð Mð Møõ�Ð$ð ð ð Ø�2�2ð øøøs6ÁBÁ*B BÂBÂBÂBÂBÂB4Â3B4có„—| |¦«| ¦«}| |¦«}dddddœi}t| ¦«¦«}| d¦«| |¦«d}|D]?}||vri||<| |¦«||d<d||d<d||d<Œ@ |j  d |j ¦«} n##tj tj f$rd} YnwxYw d|| d<d||d<n"#t$rtj| ¦«‚wxYw| d¦«||d<| d¦«| |d¦«g} t'|¦«D]z\} } t)|| d|| d|| df¦«sŒ<|  | || d|| d|| dff¦«Œ{t+| ¦«S) a' Returns a summary of available alternative versions for the given user. Only versions that are enabled, default, or selected are included. The label for the "native" version is replaced if show_native_version is True. @param user: str - Username inside CageFS. @param show_native_version: bool - Whether to replace the 'native' version label. @return: tuple of (str, (bool, bool, bool)) - Each entry contains the version name and a tuple with flags: (enabled, default, selected). r’TF)ÚenabledrNÚselectedrròrNrór¢)rtr�r}Úsortedr�Úappendr{r¹r¤r¥r~r¦ÚNoSectionErrorÚ NoOptionErrorrWrrÀÚpopÚremoveÚ enumerateÚanyÚtuple) rErGrxr‡Ú native_infoÚsummaryÚ alt_versionsÚselected_versionr]Údefault_versionÚresultÚidxÚvs r*rÛzClUserSelect.get_summarySs†€ð ×"Ò" 4Ñ(Ô(Ð(à×5Ò5Ñ7Ô7ˆ Ø×/Ò/Ð0CÑDÔDˆ ب¸%ÈUÐSÐSÐTˆÝ˜l×/Ò/Ñ1Ô1Ñ2Ô2ˆ Ø×Ò˜HÑ%Ô%Ð%Ø×+Ò+¨DÑ1Ô1°!Ô4Ðà#ð 1ð 1ˆGؘgÐ%Ð%Ø#%�˜Ñ Ø*.×*?Ò*?ÀÑ*HÔ*HˆG�GÔ ˜YÑ 'Ø*/ˆG�GÔ ˜YÑ 'Ø+0ˆG�GÔ ˜ZÑ (Ð (ð 'Ø"œhŸlšl¨:°t´zÑBÔBˆOˆOøÝÔ+­\Ô-GÐHð 'ð 'ð 'Ø&ˆOˆOˆOð 'øøøð KØ26ˆG�OÔ $ YÑ /Ø48ˆGÐ$Ô % jÑ 1Ð 1øÝð Kð Kð KÝ Ô9¸/ÑJÔJÐ Jð Køøøà")§+¢+¨hÑ"7Ô"7ˆ� ˜A”ÑØ×Ò˜HÑ%Ô%Ð%Ø×Ò˜K¨œNÑ+Ô+Ð+Øˆå  Ñ-Ô-ð gð g‰FˆC�ݘ œ  9Ô-¨w°q¬z¸)Ô/DÀgÈaÄjÐQ[ÔF\Ð]Ñ^Ô^ð Øà �MŠM˜1˜w qœz¨)Ô4°g¸a´jÀÔ6KÈWÐUVÌZÐXbÔMcÐdÐeÑ fÔ fÐ fÐ få�V‰}Œ}Ðsà C<Ã<DÄDÄ D7Ä7EcóV—| |¦«}||kr|dkp|dko|| ¦«v} tj}t dt |¦«|¦«D]}||||z…}|rdt ¦«fntj|¦«\}} | ||| ¦«tj ||¦«Œf#tj ||¦«wxYw|  |¦«tj ¦«dS#tj ¦«wxYw)z� Changes users of a supplied version to specified_version @param version: string @param current_version: string r’rN) Ú list_usersr�rÚ BULK_CHUNKÚrangeÚlenrYÚ release_bulkÚ_set_versions_suppressedÚend_bulkrKÚnotify_bulk_change) rEÚ new_versionÚcurrent_versionrFÚstaysÚ chunk_sizeÚstartÚchunkrÎÚrefuseds r*Úchange_to_versionzClUserSelect.change_to_version„sQ€ð —’ Ñ0Ô0ˆð  Ò/ÐK°KÀ8Ò4Kð]Ø ˜8Ò #Ð [¨ ¸4×;YÒ;YÑ;[Ô;[Ð([ð ð 6Ý-Ô8ˆJݘq¥# e¡*¤*¨jÑ9Ô9ð Að A�ؘe E¨JÑ$6Ð6Ô7�Ø38ð#B 4­©¬ - -Ý-Ô:¸5ÑAÔAñ �˜ðAØ×1Ò1°%¸ÀgÑNÔNÐNå(Ô1°%¸Ñ@Ô@Ð@Ð@øÕ(Ô1°%¸Ñ@Ô@Ð@Ð@øøøØ × "Ò " 5Ñ )Ô )Ð )õ !Ô 3Ñ 5Ô 5Ð 5Ð 5Ð 5øÕ Ô 3Ñ 5Ô 5Ð 5Ð 5øøøs$¿A"DÂ"CÂ9DÃC&Ã&DÄD(c óÀ—tj tj¦«}dtjtj< |D]„}||vr)t jddd|›dtj›�dœ¦«Œ/ | ||d¬¦«ŒI#t$r/}t jddt|¦«dœ¦«Yd }~Œ}d }~wwxYw |€,tj  tjd ¦«d S|tjtj<d S#|€+tj  tjd ¦«n|tjtj<wxYw) zÄset_version for each of a bulk move's accounts, without its per-account MultiPHP sync steps (see change_to_version). An account the sync could not step aside for keeps its version.Ú1ÚtextÚERRORzPHP version of zj was not changed: the MultiPHP Manager versions the MultiPHP sync set could not be handed back first; see )ÚstatusrËF)r_N) r9Úenvironr¥rÚ SUPPRESS_ENVrÚ print_diagÚLOG_PATHr¯rÁr±rø)rErFrrÚpreviousrGrJs r*r z%ClUserSelect._set_versions_suppressed¬s‘€õ”:—>’>Õ"6Ô"CÑDÔDˆØ8;�Œ Õ'Ô4Ñ5ð IØð Wð W�ؘ7�?�?ÝÔ& vØ") 'ð04¨t¨tÕ5IÔ5RÐ5Rð$Tð0Uð0UñVôVðVð ðWØ×$Ò$ T¨;ÀeÐ$ÑLÔLÐLÐLøÝ ðWðWðWÝÔ& v¸'ÍcÐRSÉfÌfÐ/UÐ/UÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøð WðÐÝ” —’Õ3Ô@À$ÑGÔGÐGÐGÐGà@H•” Õ/Ô<Ñ=Ð=Ð=øðÐÝ” —’Õ3Ô@À$ÑGÔGÐGÐGà@H•” Õ/Ô<Ñ=ÐHÐHÐHÐHs7Á1DÁ6BÂD CÂ%CÂ>DÃCÃDÄAEcóF—| ¦«}||vr||SgS)z8 Returns users of a certain alternative )Úget_version_user_map)rEr]r…s r*rzClUserSelect.list_usersÆs-€ð×(Ò(Ñ*Ô*ˆØ �dˆ?ˆ?ؘ”=Р؈ r+có¾—|jrddlm}|¦«gSt| ¦« | ¦«¦«¦«S)zF Returns all valid system users @return: list r)Úget_cpanel_user)riÚclselectctlphpr#rŽÚ_get_system_usersÚ differenceÚ_get_user_excludes)rEr#s r*Úlist_all_userszClUserSelect.list_all_usersÏsf€ð Ô ð 'Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7à#�OÑ%Ô%Ð&Ð &Ý�D×*Ò*Ñ,Ô,×7Ò7¸×8OÒ8OÑ8QÔ8QÑRÔRÑSÔSÐSr+có—t¦«}d|d<d|d<d|d<d}tj |¦« ddl}n3#t $r&t d¦«tjd¦«YnwxYwtj  tt|¦«|d¦«}tj  |d z¦«r"tj  |d z¦«s|  ||¦«dSdS) NrÚinitÚreinitÚverboseú/usr/share/cagefsrMrÚetcz /cl.selectorz /cl.php.d)ÚdictrTr:rõÚ cagefsctlÚ ImportErrorrSrUr9r>rrrÕÚcpetc_for_user)rErGÚconfigÚLIBDIRr0Úcagefs_etc_paths r*Úcagefs_copy_etczClUserSelect.cagefs_copy_etcÚs€Ý‘”ˆØˆˆv‰ØˆˆxÑØˆˆyÑØ$ˆÝ Œ�Š˜ÑÔÐð Ø Ð Ð Ð Ð øÝð ð ð Ý Ð0Ñ 1Ô 1Ð 1Ý ŒH�Q‰KŒKˆKˆKˆKð øøøõœ'Ÿ,š,¥wµÀÑ0EÔ0EÀtÈUÑSÔSˆÝŒw�~Š~˜o°Ñ>Ñ?Ô?ð 3ÅrÄwÇ~Â~ÐVeÐhsÑVsÑGtÔGtð 3Ø × $Ò $ T¨6Ñ 2Ô 2Ð 2Ð 2Ð 2ð 3ð 3sÁAÁ-A5Á4A5có¦—| ¦«}i}|D]7} | |d¦«d||<Œ##tj$rYŒ4wxYw|S)zH Returns user version map as dict @return: dict Fr)r(r{rÚ NotCageFSUser)rEÚ actual_usersr…rGs r*rjz!ClUserSelect.get_user_version_mapìsv€ð ×*Ò*Ñ,Ô,ˆ ØˆØ ð ð ˆDð Ø!×-Ò-¨d°EÑ:Ô:¸1Ô=��T‘ � øÝ!Ô/ð ð ð Ø�ð øøøàˆ sœ<¼AÁ Acóî—|p| ¦«}i}|D]Y} | ||d¦«d}||vrg||<|| |¦«ŒE#tj$rYŒVwxYw|S)zH Returns users grouped by version @return: dict Fr)r(r{rõrr8)rEÚ user_namesrer9r…rGr]s r*r!z!ClUserSelect.get_version_user_mapús¤€ð "Ð: T×%8Ò%8Ñ%:Ô%:ˆ ØˆØ ð ð ˆDð Ø×*Ò*¨4°¸Ñ?Ô?ÀÔB�Ø $��Ø$&�D˜‘MØ�W” ×$Ò$ TÑ*Ô*Ð*Ð*øÝ!Ô/ð ð ð Ø�ð øøøàˆ sžAA Á A2Á1A2c óŽ— |rbtj |¦«r/tj|¦«|krtj|¦«ndSt j|¦«tj||¦«dS#t$r=}|�|�tj |||¦«‚tj d|›d|›d|›d�¦«‚d}~wwxYw)zÝ Creates symlink from src to dst @param src: string @param dst: string @param user: string @param version: string @param check_existence: bool @return: None NzCannot create symlink from z to z (ú)) r9r:rr�ÚunlinkrÚremove_file_or_dirrÚsymlinkrÁrÚUnableToSetAlternativer¾)rárârGr]r™rJs r*rœzClUserSelect._create_symlink sì€ð oØð 2Ý”7—>’> #Ñ&Ô&ð2Ý”{ 3Ñ'Ô'¨3Ò.Ð.Ýœ  #™œ˜˜à˜åÔ,¨SÑ1Ô1Ð1Ý Ô ˜c 3Ñ 'Ô 'Ð 'Ð 'Ð 'øÝð oð oð oØÐ GÐ$7Ý$Ô;¸DÀ'È1ÑMÔMÐMÝ Ô2Ð2ÐadÐadÐadÐfiÐfiÐfiÐklÐklÐklÐ3mÑnÔnÐ nøøøøð oøøøs‚AA=Á)A=Á= CÂ8B?Â?Cc óÆ—|jr|jStj |j¦«st ¦«Stj|j¦«D]�}tj |j|¦«}|j t td„tj |¦«  ¦«¦«¦«¦«Œ‚|jS)zE Returns list of user excludes @return: list có*—| ¦«Sr.)Ústrip)Úxs r*r3z1ClUserSelect._get_user_excludes..2s€ 1§7¢7¡9¤9€r+) rpr9r:rRÚCAGEFS_EXCLUDErYrÖr>ÚupdateÚmaprÚread_file_as_stringÚ splitlines)rErrÚfull_item_paths r*r'zClUserSelect._get_user_excludes&sÉ€ð Ô ð 'ØÔ&Ð &ÝŒw�}Š}˜TÔ0Ñ1Ô1ð Ý‘5”5ˆLÝ”J˜tÔ2Ñ3Ô3ð ð ˆDÝœWŸ\š\¨$Ô*=¸tÑDÔDˆNØ Ô × &Ò &Ý•CÐ,Ð,­uÔ/HÈÑ/XÔ/X×/cÒ/cÑ/eÔ/eÑfÔfÑgÔgñ ô ð ð ðÔ"Ð"r+có²—|jrdStj¦«rdSd}tj |¦« ddl}n3#t$r&td¦«tj d¦«YnwxYw |  |¦«stj |¦«‚dS#t$r'td¦«tj d¦«YdSwxYw)z4 Check that cagefs enabled for user Nr-rrMrz;ERROR: CageFS version is unsupported. Please update CageFS.)rirr8rTr:rõr0r1rSrUÚis_user_enabledrr8ÚAttributeError)rErGr4r0s r*rtz"ClUserSelect._check_user_in_cagefs6s€ð Ô ð Ø ˆFå Ô Ñ Ô ð Ø ˆFà$ˆÝ Œ�Š˜ÑÔÐð Ø Ð Ð Ð Ð øÝð ð ð Ý Ð0Ñ 1Ô 1Ð 1Ý ŒH�Q‰KŒKˆKˆKˆKð øøøð Ø×,Ò,¨TÑ2Ô2ð 9Ý$Ô2°4Ñ8Ô8Ð8ð 9ð 9øåð ð ð Ý ÐOÑ PÔ PÐ PÝ ŒH�Q‰KŒKˆKˆKˆKˆKð øøøs$ÁAÁ-A6Á5A6Á:)B%Â%-CÃCcóN—|jst€dS|t|¦«jvS)a Is CloudLinux Isolates enabled for ``domain`` of ``user``? The per-website scope only exists for an isolated website: CageFS binds that website's ``cl.selector/`` and ``cl.php.d/`` over the account-level ones inside its namespace, and no other domain ever reads them. So this is the precondition for both reading and writing a per-domain setting. Reads ``enabled_websites`` from ``/var/clwebisolate/users//.json`` -- the same source the admin UI reports ``isolated`` from (`cloudlinux_cli._site_isolation_user`) and the same one the account-level sync loop in ``switch_symlink_for_alt_php`` already uses. ``cagefs.mp`` mounts that directory split-by-uid and the file is root: 0640, so the answer is the same for root and for the user inside the jail. Fails closed: in single-user mode (CageFS off) and without the cagefs package there is no isolated website at all. NF)rir0r[©rErGres r*rvz&ClUserSelect.website_isolation_enabledNs1€ð( Ô ð Õ"2Ð":Ø�5ØÕ)¨$Ñ/Ô/Ô@Ð@Ð@r+cób—|r*| ||¦«stj|¦«‚dSdS)aØGuard every per-domain WRITE. Raises before anything is touched. CLOS-7489: without this, a per-domain write on a non-isolated domain got half-way -- the per-website selector directory was created and reported back as the domain's version -- and then died on the ``~/.cagefs/websites/`` overlay that only isolate-enable creates. Refusing up front is what keeps "failed" and "recorded" from disagreeing. N)rvrÚWebsiteIsolationDisabledrPs r*r¿z'ClUserSelect._require_website_isolationfsN€ð ð B˜$×8Ò8¸¸vÑFÔFð BÝ Ô9¸&ÑAÔAÐ Að Bð Bð Bð Br+cóD—| ||r|jnd¦«dS)zÝ``Website``-object flavour of :meth:`_require_website_isolation`, for the extension and option writers, which carry the scope as a ``Website`` rather than a domain name. ``None`` is account scope. N)r¿re)rErGÚwebsites r*Ú_require_isolated_websitez&ClUserSelect._require_isolated_websitess+€ð ×'Ò'¨ÀÐ.Q¨g¬n¨nÈTÑRÔRÐRÐRÐRr+cóð—tj|¦«D]`}|j|vrŒ tj ||¦«}tj |¦«sŒLtj|¦«ŒadS)zg Removes all symlinks from directory @param path: string @return: None N)r9rÖr~r:r>rr>)rEr:rãr‚s r*rÓz'ClUserSelect._remove_alternatives_linkszsx€õ œ  4Ñ(Ô(ð !ð !ˆHØŒz Ð)Ð)ØÝœŸ š  T¨8Ñ4Ô4ˆIÝ”7—>’> )Ñ,Ô,ð ØÝ ŒI�iÑ Ô Ð Ð ð  !ð !r+cóœ—|jr|j |¦«}|dzSt|j |¦«¦«}d}|r|rt |¦«nd}t j¦«s0tj   |j |dd…|dd¦«nd}|r tj   ||¦«n|S)zz Composes and returns user alternative directory path @param user: string @return: string z /.cl.selectorrÐéþÿÿÿNr.z cl.selectorz/etc/cl.selector) rir<ršr±rÇr/rr8r9r:r>Ú CAGEFS_PATH)rErGr^r�ríÚdocument_root_idÚbases r*ruz#ClUserSelect._compose_user_alt_pathˆsÙ€ð Ô ð -Ø”k×-Ò-¨dÑ3Ô3ˆGؘ_Ñ,Ð ,Ý�$”+×%Ò% dÑ+Ô+Ñ,Ô,ˆØÐØ ð VØ@MÐU�~¨mÑ<Ô<Ð<ÐSUÐ õÔ%Ñ'Ô'ð $�BŒG�LŠL˜Ô)¨3¨r¨s¨s¬8°T¸5À-Ñ PÔ PÐ Pà#ð ð 8HÐQ�rŒw�|Š|˜DÐ"2Ñ3Ô3Ð3ÈTÐQr+cóv—|j ¦«}t| ¦«¦«S)zB Returns set of system users @return: set )r<Ú get_user_dictrYr�)rEÚ users_dicts r*r%zClUserSelect._get_system_users�s/€ð ”[×.Ò.Ñ0Ô0ˆ Ý�:—?’?Ñ$Ô$Ñ%Ô%Ð%r+có¸—tj |¦«r: tj|¦«dS#t$rt j|d¦«‚wxYwdS)z? Deletes file to be written if it is a symlink z'Cannot delete symlink while saving dataN)r9r:rr>rBrrC)Ú file_paths r*Ú_delete_if_symlinkzClUserSelect._delete_if_symlink¥sv€õ Œ7�>Š>˜)Ñ $Ô $ð lð lÝ” ˜)Ñ$Ô$Ð$Ð$Ð$øÝð lð lð lÝ$Ô5°iÐAjÑkÔkÐkð løøøð lð ls ¡7· Acó€—|j |¦«}|j}|j}t j¦«}t j¦«}||kr||fS t j|¦«t j|¦«tj ¦«||fS#t$r}tj ||¦«‚d}~wwxYw)z‡ Changes to another uid and returns tuple of previous euid and egid @param user: string @return: tuple N)r<r=Úpw_uidÚpw_gidr9rXÚgetegidÚsetegidÚseteuidÚsecureioÚset_capabilityrBrÚUnableToChangeToAnotherUser)rErGÚentryÚnew_uidÚnew_gidÚcur_euidÚcur_egidrJs r*r@zClUserSelect._change_uid±sÉ€ð ” ×*Ò*¨4Ñ0Ô0ˆØ”,ˆØ”,ˆÝ”:‘<”<ˆÝ”:‘<”<ˆØ �wÒ Ð Ø˜XÐ%Ð %ð FÝ ŒJ�wÑ Ô Ð Ý ŒJ�wÑ Ô Ð Ý Ô #Ñ %Ô %Ð %ؘXÐ%Ð %øÝð Fð Fð FÝ Ô<¸TÀ1ÑEÔEÐ Eøøøøð FøøøsÁ>B B=Â#B8Â8B=cóL—|dtj¦«kr†tjd¬¦« tj|d¦«tj|d¦«dS#t $r-}tjt|d¦«|¦«‚d}~wwxYwdS)zw Restores changed uid and gid to original ones @param uid_and_gid: tuple @return: None rT)ÚclearrN) r9rXrhrirfrgrBrrjr±)Ú uid_and_gidrJs r*rDzClUserSelect._restore_uidÆs­€ð �qŒ>�RœZ™\œ\Ò )Ð )Ý Ô #¨$Ð /Ñ /Ô /Ð /ð YÝ” ˜; qœ>Ñ*Ô*Ð*Ý” ˜; qœ>Ñ*Ô*Ð*Ð*Ð*øÝð Yð Yð YÝ$Ô@ÅÀ[ÐQRÄ^ÑATÔATÐVWÑXÔXÐXøøøøð Yøøøð *Ð )s´4A*Á* B!Á4(BÂB!có¢—| |¦«} |srArrr r ÚrenameÚchmodr¨r>) rErGÚ file_contentsr`ÚcreaterIÚfile_directoryrJr‹Ú temp_pathÚmasks r*Ú_write_to_filezClUserSelect._write_to_fileÖsW€ð"×-Ò-¨dÑ3Ô3Ðð& :Øð ¥"¤'§.¢.°Ñ";Ô";ð ØõH × %Ò %Ð&8Ñ 9Ô 9Ð 9Ð 9Ð 9ðG × #Ò # IÑ .Ô .Ð .ÝœWŸ_š_¨YÑ7Ô7ˆNõ”7—=’= Ñ0Ô0ð MðMÝ”O N¸È$ÐOÑOÔOÐOÐOøÝÕ!6Ð7ðMðMðMÝ(Ô9¸.È!ÑLÔLÐLøøøøðMøøøð à'­#­d¬j©l¬lÑ*;Ô*;Ñ;�ÝœGŸLšL¨¸ÑAÔA� Ý”  °]°]°]Ð+DÑEÔEÐEðÝ"¥WÑ,­wÑ6½Ñ@�DÝ”I˜i¨Ñ3Ô3Ð3Ý”H˜Y¨Ñ-Ô-Ð-Ð-øÝðððØ�Dðøøøøõ�WÕ&;Ð<ð Dð Dð DðÝ”w—~’~ iÑ0Ô0ð-Ýœ  )Ñ,Ô,Ð,øøðØ�DøøøÝ$Ô5°iÀÑCÔCÐCøøøøð  Døøøõ × %Ò %Ð&8Ñ 9Ô 9Ð 9Ð 9Ð 9ø�L× %Ò %Ð&8Ñ 9Ô 9Ð 9Ð 9øøøsŒ—!H2ÁAH2Â)CÃH2ÃC,ÃC'Ã'C,Ã,H2Ã0AF&Å A FÆH2Æ F#Æ H2Æ"F#Æ#H2Æ&HÆ>3G2Ç1HÇ2G6Ç4HÈHÈH2È2Icó6— tj¦«}td¦«D]8}| ¦«}|� |j |j¦«Œ8n#tj$rYnwxYw t¦«  |¦«}n#tj f$rYdSwxYw tj ¦«D]¿} ||  ¦«j |  ¦«jfvs0| ¦« |j¦«dkrŒh|j}n#tj$rYŒ�wxYw ||jvrt%j|t(j¦«Œ¯#t,f$rYŒ¼wxYwdS#t,t.f$rYdSwxYw)z& Reloads user process éNéÿÿÿÿ)ÚpsutilÚProcessrÚparentrqrõÚpidÚ NoSuchProcessrrÇÚNoSuchUserExceptionÚ process_iterÚuidsÚrealÚ effectiveÚnameÚfindr~r9ÚkillÚsignalÚSIGHUPrBr¨)rErGÚ next_parentr†ríÚprocr‡s r*rÙzClUserSelect._reload_processessà€ð Ý œ.Ñ*Ô*ˆKݘ1‘X”Xð ð �Ø)×0Ò0Ñ2Ô2� ØÐ*ØÔ)×0Ò0°´ÑAÔAÐAÐAàøøÝÔ#ð ð ð Ø ˆDð øøøð Ý‘'”'—/’/ $Ñ'Ô'ˆCˆCøÝÔ)Ð+ð ð ð à ˆFˆFð øøøð ÝÔ+Ñ-Ô-ð ð �ðØ 4§9¢9¡;¤;Ô#3°T·Y²Y±[´[Ô5JÐ"KÐKÐKÈtÏyÊyÉ{Ì{×O_ÒO_Ð`dÔ`jÑOkÔOkÐoqÒOqÐOqØ Øœ(�C�CøÝÔ+ðððØ�HðøøøðØ $Ô"7Ð7Ð7Ýœ ¥V¤]Ñ3Ô3Ð3øøÝ�zðððØ�Hðøøøð ð øõ�Ð!ð ð ð à ˆDˆDð øøøs‹‚AAÁA0Á/A0Á4!BÂB*Â)B*Â.FÃA$D1Ä(FÄ)D1Ä0FÄ1EÅFÅEÅFÅ(E0Å/FÅ0 E>Å;FÅ=E>Å>FÆFÆFcó—g} t|¦«}|D]I}| d¦«r2|d| d¦«…}| |¦«ŒJ| ¦«n#t t f$rYnwxYw|S)zH Get extension names from user extensions file comments z;---éz---)rérVÚrfindrõÚcloserBr¨)r:Ú extensionsrÞÚlineÚexts r*Ú_skim_over_extensionsz"ClUserSelect._skim_over_extensions+s¦€ðˆ ð Ý�t‘*”*ˆCØð +ð +�Ø—?’? 6Ñ*Ô*ð+ؘq 4§:¢:¨eÑ#4Ô#4Ð4Ô5�CØ×%Ò% cÑ*Ô*Ð*øØ �IŠI‰KŒKˆKˆKøÝ�Ð!ð ð ð Ø ˆDð øøøàÐs„A/A4Á4BÂBc óè—| |¦«t|¦«o|j }|rt|¦«nd}g}| ||¦«}t j t j | |¦«¦«d¦«}|r t j ||¦«}|  ¦«} t j |j   |¦«d¦«} |r t j | |¦«} t j  | ¦«s�|  |¦«} tj| ¦«nH#t t"f$r4} t$ | ¦«t)j| | ¦«‚d} ~ wwxYwt$ | ¦«t j | d¦«} t j  |¦«r*d|j›d| ||¬¦«d ›d �}n d|j›d �}| |¦«t3|  ¦«¦«D]¹}|jr |d z| d d¦«zdz}n8t j |d| d d¦«›�d¦«}| |¦«}| d|j›|›dd t3|¦«¦«›d �¦«Œº| |d  |¦«| ¦«dS)aê Scans all user settings and backups'em in homedir as INI file When ``document_root`` is given (an isolated per-domain config), the backup is written to the per-website ``~/.cl.selector//`` directory and reflects the per-website ``cl.php.d/`` inis, so ``cagefsctl`` regenerates the isolated config from it. Otherwise the account-level backup is written as before. Without this, per-domain extension changes were lost on ``cagefsctl --force-update`` (CLOS-4702). @param user: string @param document_root: str or None - domain docroot for the per-website backup @param domain: str or None - domain name, used to record its PHP version rÐzcl.php.dr«Nr¬z [versions] z = )rerrvz = native z/alt_phpú.rÒzalt-phpz alt_php.iniú[z ] modules = ú,)rtÚboolrir/rur9r:r>r‹r�r<ršrRr@rr–rBrr5rDrrCr~r{rõrôr�Úreplacerœr€)rErGr^reÚ per_websiteÚ website_idÚbackup_contentsÚ user_alt_pathÚ user_ext_pathr‡r²rIrJÚuser_backup_filer]ÚaltÚ curr_ext_pathr™s r*rÚzClUserSelect._backup_settings=sU€ð ×"Ò" 4Ñ(Ô(Ð(ݘ=Ñ)Ô)ÐE°$Ô2EÐ.Eˆ Ø6AÐI•^ MÑ2Ô2Ð2Àrˆ ؈Ø×3Ò3°D¸-ÑHÔHˆ õœŸ š ¥R¤W§_¢_°T×5PÒ5PÐQUÑ5VÔ5VÑ%WÔ%WÐYcÑdÔdˆ Ø ð DÝœGŸLšL¨¸ ÑCÔCˆMØ×5Ò5Ñ7Ô7ˆ Ýœ7Ÿ<š<¨¬ ×(?Ò(?ÀÑ(EÔ(EÀ~ÑVÔVÐØ ð JÝ!œwŸ|š|Ð,<¸jÑIÔIÐ ÝŒw�}Š}Ð-Ñ.Ô.ð :Ø!%×!1Ò!1°$Ñ!7Ô!7Ð ð KݔР0Ñ1Ô1Ð1Ð1øÝÕ2Ð3ð Kð Kð KÝ×)Ò)Ð*<Ñ=Ô=Ð=Ý$Ô5Ð6FÈÑJÔJÐJøøøøð Køøøõ × %Ò %Ð&8Ñ 9Ô 9Ð 9Ýœ7Ÿ<š<Ð(8¸.ÑIÔIÐÝ Œ7�=Š=˜Ñ 'Ô 'ð Bð BØ15´°°¸T×=MÒ=MÈdÐ[aÐ=MÑ=bÔ=bÐcdÔ=eÐ=eÐ=eÐfˆGˆGð Bð6:´Z°Z°ZÐAˆGØ×Ò˜wÑ'Ô'Ð'ݘ,×+Ò+Ñ-Ô-Ñ.Ô.ð oð oˆCØÔ"ð tØ -° Ñ :¸S¿[º[ÈÈbÑ=QÔ=QÑ QÐTZÑ Z� � å "¤§ ¢ ¨]¨]ÈCÏKÊKÐX[Ð]_ÑL`ÔL`ÐL`ÐNÑOÔOÐOÐOÐOsÅ-FÆGÆ/GÇGcó8—|jrdSt||¦«dSr.)rir#)rErGr]s r*rØzClUserSelect._switch_php_da_ispps(€Ø Ô ð Ø ˆFݘt WÑ-Ô-Ð-Ð-Ð-r+r.)NTT)rmNr%)F)NFFT)NN)NNF)T)5Ú__name__Ú __module__Ú __qualname__rYrŒrr8rÔrFr›rKrgrlror{rwr€r\r—r r©rµr¹r¯rÅr±r¼rÛrr rr(r6rjr!rœÚ staticmethodr'rtrvr¿rUrÓrur%rar@rDr€rÙrœrÚrØr&r+r*r5r5Csœ€€€€€Ø€KØ#€MØ#5 8Ô#5Ñ#7Ô#7Ðf�-�-Ð=f€KØ*€NØ0€MðBðBðBðBð0TðTðTðTðl hð hð hð'ð'ð'ð'ðHðHðHðHð* Zð Zð Zð Zððððð8K:ðK:ðK:ðZ>ð>ð>ð $ð $ð $ððððððð4 ð ð ðaeðEðEðEðEðNP?ðP?ðP?ðP?ðd¸3ðÀ3ððððð2/ð/ð/ð/ðb&6ð&6ð&6ðPIðIðIð4ððð Tð Tð Tð3ð3ð3ð$ ð ð ððððð"oðoðoðoð2#�l ?Ñ3Ô3€Oð#ð#ð#ð ððð0AðAðAð0 Bð Bð BðSðSðSð !ð !ð !ðRðRðRðRð*&ð&ð&ðlðlðlð&˜Ð&8Ñ9Ô9ÐðFðFðFð* Yð Yð Yð �<  Ñ-Ô-€Lð/:ð/:ð/:ð/:ðb"ð"ð"ðHððð )˜LÐ)>Ñ?Ô?Ðð1Pð1Pð1Pð1Pðf.ð.ð.ð.ð.r+r5)@Ú __future__rrrrêr9rTrwr‘rhÚ future.movesrr¦Ústatrrr r r Ú future.utilsr Úpathlibr r„ÚclselectrÚclselectexceptrrÐrÚclcommonrrÚ clselectprintrrrÚclcommon.utilsrÚclcommon.cpapirrrÚclcommon.cpapi.cpapiexceptionsrrrÚclcagefslib.constrÚclcagefslib.fsrÚclcagefslib.selector.configurer r!r"Úclcagefslib.selector.panel.dar#r1r,Ú#clcagefslib.webisolation.jail_utilsr/Úclcagefslib.webisolation.configr0r5r&r+r*úrÂs'ðð&Ð%Ð%Ð%Ð%Ð%Ø&Ð&Ð&Ð&Ð&Ð&ØÐÐÐÐÐØ € € € Ø € € € Ø € € € Ø € € € Ø € € € Ø€€€Ø5Ð5Ð5Ð5Ð5Ð5Ø<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ø"Ð"Ð"Ð"Ð"Ð"ØÐÐÐÐÐØ € € € àÐÐÐÐÐØ*Ð*Ð*Ð*Ð*Ð*Ø"Ð"Ð"Ð"Ð"Ð"Ø%Ð%Ð%Ð%Ð%Ð%Ð%Ð%Ø"Ð"Ð"Ð"Ð"Ð"ØÐÐÐÐÐØÐÐÐÐÐØ0Ð0Ð0Ð0Ð0Ð0Ø=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Ð=ØNÐNÐNÐNÐNÐNÐNÐNÐNÐNð Ø)Ð)Ð)Ð)Ð)Ð)Ø.Ð.Ð.Ð.Ð.Ð.ØjÐjÐjÐjÐjÐjÐjÐjÐjÐjØDÐDÐDÐDÐDÐDÐDøØðððð ððððð øøøð ðFÐEÐEÐEÐEÐEÐEøØðððððððððøøøðØBÐBÐBÐBÐBÐBØ@Ð@Ð@Ð@Ð@Ð@Ð@øØðððØ#�^€NØÐÐÐðøøøð p.ðp.ðp.ðp.ðp.�8ñp.ôp.ðp.ðp.ðp.s6ÂB3Â3B>Â=B>ÃC à CÃCà C%Ã% C2Ã1C2