§ À•¿jy·ãóþ—ddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl mZmZmZmZmZddlmZddlmZddlZd d lmZd d lmZdd lmZmZd d lm Z d dl!m"Z"ddlm#Z#ddl$m%Z%ddl&m'Z'm(Z(m)Z)ddl*m+Z+m,Z,m-Z- ddl.m/Z/ddl0m1Z1ddl2m3Z3m4Z4m5Z5ddl6m7Z7n#e8$rd„Z3YnwxYw ddl2m9Z9n#e8$rd„Z9YnwxYw ddl:m;Z;ddldS)é)Úprint_function)Úabsolute_import)ÚdivisionN)Ú configparser)ÚS_IRUSRÚS_IWUSRÚS_IRGRPÚS_IROTHÚS_ISREG)Ú iteritems)ÚPathé)ÚClSelect)ÚClSelectExcept)Ú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.pyrr+s€Øˆuó)Únative_website_targetscó—iS©Nr%r&s r)r+r+7s€Øˆ r*)Úget_website_id)Úload_user_configcó—dSr-r%)Ú_s r)úr2>s€˜t€r*có´—eZdZdZdZej¦«rendZdZdZ d4d„Z d5d „Z d „Z d6d „Z d7d„Zd8d„Zd8d„Zd„Zd„Zd„Zd„Zd„Zd„Z d9d„Zd9d„Zdedefd„Zd8d„Zd„Zd„Zd„Zd „Zd!„Z d:d"„Z!d;d#„Z"e#e"¦«Z"d$„Z$d%„Z%d&„Z&d'„Z'd(„Z(d)„Z)d4d*„Z*d+„Z+d,„Z,e#e,¦«Z,d-„Z-d.„Z.e#e.¦«Z.d’> $Ñ'Ô'ð 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)r8r9Úisdirrrr7ÚprintÚsysÚexitrr Ú startswithÚKeyErrorr!Úgeteuidr/ÚsetÚpw_nameÚenabled_websitesrrrÚ_website_selected_version) rDÚversionrGÚ document_rootÚ exit_on_errorrPÚconfÚ default_phpÚerrorÚisolated_domainsÚtarget_domainsÚdomainÚdomain_docroots r)Úswitch_symlink_for_alt_phpz'ClUserSelect.switch_symlink_for_alt_phpas1€õ Œ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^rP) Úwithout_cagefsrRrSrTr8rWÚget_user_version_mapr r;r<rf)rDÚusers_vers_dictrFr\rGs 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;rXÚ_user_excludesÚexclude_pid_list)rDÚitemrps r)rnzClUserSelect.__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_enabledrr8r9rQÚ_version_at_alt_path)rDrFrdÚ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/``. ) r8r9rQÚ_compose_native_infor=Ú_itemÚislinkÚ_version_for_link_targetÚreadlink)rDrxrwÚ full_paths r)rvz!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_dstrDs €€€r)r2z7ClUserSelect._version_for_link_target..sø€ ,¨q¤/°&Ô"9¸$¼*Ô"EÈÒ"Q€r*rr\r„)r|rhÚ_native_contentsÚ_load_native_contentsr}r8r9ÚdirnameÚ SELECTOR_PATHÚget_all_alternatives_dataÚlistÚfilterÚkeysÚ IndexErrorrV)rDr‡rwÚnativer\r†s`` @r)rz%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) rtr8r9r=r}r~r€rArŠr‹r)rDrFr]rxÚlinkr‡s r)r[z&ClUserSelect._website_selected_version sÅ€ð*×.Ò.¨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-) r8r9rQr?rÚmkdirrArrrBr4rC)rDr9rFrHrIs r)Ú create_dirzClUserSelect.create_dirZsÀÝŒ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_homedirr8r9r=Ú SELECTOR2_DIRr?r–Ú_create_symlinkrC)rDrFÚhomedirÚ path_in_homeÚcur_users r)Úcreate_selector_symlinksz%ClUserSelect.create_selector_symlinksds´€ð”+×)Ò)¨$Ñ/Ô/ˆÝ”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‘) r8r9r:rÚ DEFAULTS_PATHÚ_dhÚgetr}Ú ConfigParserÚErrorÚIOErrorrV)rDs r)Úget_default_versionz ClUserSelect.get_default_versionpsi€Ý Œ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)r8r9r=r;r™ÚlstatrAr Úst_modeÚ set_versionr¨Ú_get_default_config_handlerr¤r}r¥r¦r§rVrRÚstrrSrT)rDrFÚuser_backup_pathÚstÚdhrIs r)Úset_version_from_backupz$ClUserSelect.set_version_from_backupxs?€Ýœ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})rDr\s r)Ú_version_enabledzClUserSelect._version_enabled’s3€ðŒx×"Ò"¨T¬Z¨Z¸¸Ð#AÀ7ÑKÔKð Ø�4à�5r*c óT—tj¦«dkr+| |¦«x}rtj|¦«‚| |¦«stjd|z¦«‚|rY t |¦«}n#t$rd}YnwxYw||krtjd|›d|›�¦«‚|  ||¦«tj |j |j  |j  |¦«¦«tj|||||¦«} |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 )r8rWÚ"get_version_selection_disabled_msgrÚVersionModificationBlockedr¸rrÚSelectorExceptionÚ_require_website_isolationrÚapply_for_at_least_one_userÚ _set_versionr;Ú get_namesÚget_uidÚNoUserSelector) rDrFr\rdÚreturn_summaryrwr^ÚmessageÚownerr„s r)r®zClUserSelect.set_version s\€õ Œ:‰<Œ<˜1Ò Ð ¨T×-TÒ-TÐUYÑ-ZÔ-ZÐ"Z 'Ð Ý Ô;¸GÑDÔDÐ Dð×$Ò$ WÑ-Ô-ð qÝ Ô;ÐÐ+>Ý Ô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¤rAÚ ValueError)rDrÜÚuidÚ config_fileÚfÚ config_datas r)rºz/ClUserSelect.get_version_selection_disabled_msgs#€ðŒ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)ÚenabledrMÚselectedrrêrMrër¡)rsrŒr|Úsortedr�Úappendrzr¸r£r¤r}r¥ÚNoSectionErrorÚ NoOptionErrorrVrrÊÚpopÚremoveÚ enumerateÚanyÚtuple) rDrFrwr†Ú native_infoÚsummaryÚ alt_versionsÚselected_versionr\Údefault_versionÚresultÚidxÚvs r)rÓzClUserSelect.get_summary0s†€ð ×"Ò" 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 ó—| |¦«}|D]W} | ||d¬¦«Œ#t$r/}tjddt |¦«dœ¦«Yd}~ŒPd}~wwxYw| |¦«dS)z� Changes users of a supplied version to specified_version @param version: string @param current_version: string F)r^ÚtextÚERROR)ÚstatusrÄN)Ú list_usersr®Ú ExceptionrÚ print_diagr°rJ)rDÚ new_versionÚcurrent_versionrErFrIs r)Úchange_to_versionzClUserSelect.change_to_versionas®€ð —’ Ñ0Ô0ˆØð ð ˆDð Ø× Ò   {À%Ð ÑHÔHÐHÐHøÝð ð ð ÝÔ" 6°gÍ#ÈaÉ&Ì&Ð+QÐ+QÑRÔRÐRØ����øøøøð øøøð ×Ò˜uÑ%Ô%Ð%Ð%Ð%s›4´ A-¾%A(Á(A-cóF—| ¦«}||vr||SgS)z8 Returns users of a certain alternative )Úget_version_user_map)rDr\r„s r)rzClUserSelect.list_usersps-€ð×(Ò(Ñ*Ô*ˆØ �dˆ?ˆ?ؘ”=Р؈ r*có¾—|jrddlm}|¦«gSt| ¦« | ¦«¦«¦«S)zF Returns all valid system users @return: list r)Úget_cpanel_user)rhÚclselectctlphpr r�Ú_get_system_usersÚ differenceÚ_get_user_excludes)rDr s r)Úlist_all_userszClUserSelect.list_all_usersysf€ð Ô ð 'Ø 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/cagefsrLrÚetcz /cl.selectorz /cl.php.d)ÚdictrSr9ríÚ cagefsctlÚ ImportErrorrRrTr8r=rrrÍÚcpetc_for_user)rDrFÚconfigÚLIBDIRrÚ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)rrzrÚ NotCageFSUser)rDÚ actual_usersr„rFs r)riz!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)rrzrírr)rDÚ user_namesrdr r„rFr\s r)rz!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 (ú)) r8r9r~r€ÚunlinkrÚremove_file_or_dirrÚsymlinkrrÚUnableToSetAlternativer¼)rÙrÚrFr\r˜rIs 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)r2z1ClUserSelect._get_user_excludes..Üs€ 1§7¢7¡9¤9€r*) ror8r9rQÚCAGEFS_EXCLUDErXrÎr=ÚupdateÚmaprÚread_file_as_stringÚ splitlines)rDrqÚfull_item_paths r)rzClUserSelect._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 NrrrLrz;ERROR: CageFS version is unsupported. Please update CageFS.)rhrr7rSr9rírrrRrTÚis_user_enabledrrÚAttributeError)rDrFrrs r)rsz"ClUserSelect._check_user_in_cagefsàs€ð Ô ð Ø ˆ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)rhr/rZ©rDrFrds r)ruz&ClUserSelect.website_isolation_enabledøs1€ð( Ô ð Õ"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)rurÚWebsiteIsolationDisabledr7s r)r½z'ClUserSelect._require_website_isolationsN€ð ð 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½rd)rDrFÚwebsites r)Ú_require_isolated_websitez&ClUserSelect._require_isolated_websites+€ð ×'Ò'¨ÀÐ.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)r8rÎr}r9r=r~r%)rDr9rÛr�s r)rËz'ClUserSelect._remove_alternatives_links$sx€õ œ  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ÇéþÿÿÿNrz cl.selectorz/etc/cl.selector) rhr;r™r°rÁr.rr7r8r9r=Ú CAGEFS_PATH)rDrFr]rœråÚdocument_root_idÚbases r)rtz#ClUserSelect._compose_user_alt_path2sÙ€ð Ô ð -Ø”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_dictrXr�)rDÚ users_dicts r)r zClUserSelect._get_system_usersGs/€ð ”[×.Ò.Ñ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)r8r9r~r%rArrB)Ú file_paths r)Ú_delete_if_symlinkzClUserSelect._delete_if_symlinkOsv€õ Œ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_gidr8rWÚgetegidÚsetegidÚseteuidÚsecureioÚset_capabilityrArÚUnableToChangeToAnotherUser)rDrFÚentryÚnew_uidÚnew_gidÚcur_euidÚcur_egidrIs 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) r8rWrOrPrMrNrArrQr°)Ú uid_and_gidrIs r)rCzClUserSelect._restore_uidps­€ð �qŒ>�RœZ™\œ\Ò )Ð )Ý Ô #¨$Ð /Ñ /Ô /Ð /ð YÝ” ˜; qœ>Ñ*Ô*Ð*Ý” ˜; qœ>Ñ*Ô*Ð*Ð*Ð*øÝð Yð Yð YÝ$Ô@ÅÀ[ÐQRÄ^ÑATÔATÐVWÑXÔXÐXøøøøð Yøøøð *Ð )s´4A*Á* B!Á4(BÂB!có¢—| |¦«} |s3G2Ç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ÚProcessÚrangeÚparentrpríÚpidÚ NoSuchProcessrrÁÚNoSuchUserExceptionÚ process_iterÚuidsÚrealÚ effectiveÚnameÚfindr}r8ÚkillÚsignalÚSIGHUPrAr§)rDrFÚ next_parentr…råÚprocros r)rÑzClUserSelect._reload_processes±sà€ð Ý œ.Ñ*Ô*ˆ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árUÚrfindríÚcloserAr§)r9Ú 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 = )rdrr]z = native z/alt_phpú.rÉzalt-phpz alt_php.iniú[z ] modules = ú,)rsÚboolrhr.rtr8r9r=rŠrŒr;r™rQr?rr•rArr4rCrrBr}rzrírìr�Úreplacer„rg)rDrFr]rdÚ per_websiteÚ website_idÚbackup_contentsÚ user_alt_pathÚ user_ext_pathr†r±rHrIÚ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-)rhr")rDrFr\s r)rÐzClUserSelect._switch_php_da_isps(€Ø Ô ð Ø ˆFݘt WÑ-Ô-Ð-Ð-Ð-r*r-)NTT)rlNr$)F)NFFT)NN)NNF)T)4Ú__name__Ú __module__Ú __qualname__r@r‹rr7rÌr-ršrJrfrkrnrzrvrr[r–rŸr¨r´r¸r®r¿r°rºrÓrrrrrirr›Ú staticmethodrrsrur½r<rËrtr rHr?rCrgrÑr„rÒrÐr%r*r)r4r4Bs…€€€€€Ø€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ð#ð#ð#ð#ðJP?ðP?ðP?ðP?ðd¸3ðÀ3ððððð2/ð/ð/ð/ðb &ð &ð &ðððð 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*r4)?Ú __future__rrrrâr8rSr^ryrOÚ future.movesrr¥Ústatrrr r r Ú future.utilsr Úpathlibr rkÚclselectrÚclselectexceptrÚclcommonrrÚ clselectprintrrÇrrÚclcommon.utilsrÚclcommon.cpapirrrÚclcommon.cpapi.cpapiexceptionsrrrÚclcagefslib.constrÚclcagefslib.fsrÚclcagefslib.selector.configurerr r!Úclcagefslib.selector.panel.dar"rr+Ú#clcagefslib.webisolation.jail_utilsr.Úclcagefslib.webisolation.configr/r4r%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ØÐÐÐðøøøð [.ð[.ð[.ð[.ð[.�8ñ[.ô[.ð[.ð[.ð[.s6ÂB-Â-B8Â7B8Â<CÃCà Cà Cà C,Ã+C,