9Vj*g~ddlZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZddlmZmZddlmZddlmZdd lmZdd lmZd d lmZd d lmZd dlmZm Z m!Z!m"Z"d dl#m$Z$d dl%m&Z&m'Z'd dl(m)Z)d dl*m+Z+d dl,m-Z-m.Z.d dl/m0Z0m1Z1dZ2dZ3de4dzfdZ5de4de6fdZ7dZ8dZ9dZ:dgZ;dd d!Zd$Z?de4fd%Z@d&ZAejBd 'd(ZCd)ZDd*ZEd+ZFd,ZGd-ZHd.ZId/ZJd0e4fd1ZKd0e4fd2ZLd0e4fd3ZMd4ZNd5e4fd6ZOd7ZPdeQfd8ZRde4fd9ZSdeQfd:ZTd;ZUd<ZVd>de4d5e4dzfd=ZWdS)?N) defaultdict)Path)ClPwd)setup_mount_dir_cagefsCAGEFSCTL_TOOL)cpusersis_panel_feature_supported)docroot)Feature)NoDomain)PyLve) user_exists)UserNotFoundError) admin_configconfig jail_utils litespeed)DOCROOTS_ISOLATED_BASE)validate_docrootvalidate_docroot_no_symlinks)write_jail_mounts_config)reload_processes_with_docroots)start_monitoring_servicestop_monitoring_service)trigger_xray_ini_regenerationtrigger_ssa_ini_regenerationcTtjtjSN)ospathisfilerWEBSITE_ISOLATION_MARKERFopt/cloudlinux/venv/lib/python3.11/site-packages/clcagefslib/domain.py(is_website_isolation_allowed_server_wider''s 7>>,? @ @@r%cTtjtjSr)r r!r"r"WEBSITE_ISOLATION_AVAILABLE_MARKERr$r%r&&is_website_isolation_feature_availabler*+s 7>>,I J JJr%returnc.tjtj}tjtj}|r8|r6t jdtj tjddS|rdS|rdSdS)uReturn the current user mode for website isolation. Returns: ``"allow_all"`` – all users allowed, denied dir lists exceptions. ``"deny_all"`` – no users allowed, allowed dir lists exceptions. ``None`` – not initialised yet. zBoth site-isolation.users.allowed and site-isolation.users.denied directories exist. Removing allowed directory, treating as allow_all mode.T ignore_errors allow_alldeny_allN) r r!isdirrISOLATION_DENIED_DIRISOLATION_ALLOWED_DIRloggingwarningshutilrmtree) has_denied has_alloweds r&get_isolation_user_moder:/s|@AAJ'-- BCCKk Y     l8MMMM{{z 4r%userctjtjsdSt }|dkr tjtj| S|dkrtjtj|SdS)uCheck whether *user* is allowed to use website isolation. Combines the global marker with the two-mode user model: * **allow_all** – allowed unless the user is in the denied directory. * **deny_all** – denied unless the user is in the allowed directory. Fr/r0) r r!r"rr#r: user_in_dirr2r3)r;modes r&%is_website_isolation_allowed_for_userr?Hsw 7>>,? @ @u " $ $D {+L,MtTTTT z' (JDQQQ 5r%cjtjtjst t tdddttj}|j dd| tj gddddSdS) zCSet up mount directories and the global marker if not already done.*TF)prefixremount_cagefsremount_in_background)parentsexist_ok)z/usr/bin/systemctlz try-restartzclwpos_monitoring.service)capture_outputtextN)r r!r"rr#rstrrrparentmkdirtouch subprocessrun) marker_paths r&"_ensure_isolation_mount_and_markerrPYs 7>>,? @ @   & ' 'u    <@AA    === N N N         r%z/etc/cagefs/proxy.commandsz> w~~f%%    7++D11  tOGc&&F&&&& E>r%cd}|D]e\}|vr tj|r*|d}fd|D}d|}d}f||fS)zRemove proxy entries whose binaries no longer exist on disk. Returns the (possibly updated) content string and a bool indicating whether any entries were removed. FT)keependscDg|]}|d|S)rU) startswith).0lr\s r& z)_remove_proxy_entries..s0AAAqiii)@)@AAAAr%)rVr r!rW splitlinesjoin)rYrZremovedr]linesr\s @r&_remove_proxy_entriesrks G}} V g    7>>& ! !  ""D"11AAAAEAAA''%.. G r%c ttdd5}|}dddn #1swxYwYn#t$rd}YnwxYwd}d|vrEt jdt|r|d s|d z }|td zz }d }t|t\}}|rt jd td }t|t\}}|rt jd td }|sdStj t}tj|d tj|d\}} tj|dd5}||dddn #1swxYwYtj|tn##t($rtj|wxYwd t.d z}t3jt6ddg|t2jt2jdt3jt6dgt2jt2jddS)aRegister the ``cagefsctl-user`` proxyexec alias if not already present. Appends the ``CAGEFSCTL_USER`` entry to ``/etc/cagefs/proxy.commands`` and runs ``cagefsctl --update-list`` to pull the required binaries into the CageFS skeleton. This is a no-op when the entry already exists. Also registers/unregisters the LVD helper binaries (``lvd-registry-helper``, ``lvd-limits-helper``) depending on whether they are present on disk. rzutf-8)encodingNrfFCAGEFSCTL_USERz Registering cagefsctl-user in %srTTzRegistering LVD helpers in %sz"Removing stale LVD helpers from %s)rFz.proxy.commands.)dirrBwz --wait-lockz --update-list)inputstdoutstderrcheckz--update-wrappers)rsrtru)openPROXY_COMMANDS_PATHreadFileNotFoundErrorr4inforXCAGEFSCTL_USER_PROXY_ENTRYr^LVD_PROXY_ENTRIESrkr r!dirnamemakedirstempfilemkstempfdopenwritereplace BaseExceptionunlinkrhCAGEFSCTL_USER_BINARIESencoderMrNrDEVNULL) frYchangedr[ri proxy_dirfdtmp_path update_lists r&ensure_proxyexec_commandrs %sW = = = ffhhG                Gw&& 79LMMM  7++D11  tOG-44'1BCCNGU  46IJJJ,W6GHHGW 9;NOOO  344IK D))))# :LMMMLB Yr3 1 1 1 Q GGG                   801111  ( 99455<DDFFKN 8!! N ,-!! s^A: A>A>A AA'G>F  G F$$G'F$(G G&ctt}|dkrNd}tjtjtjdtjtj dnMd}tjtj tjdtjtjd|S)uFlip the isolation user mode without modifying any per-user state. Unlike :func:`allow_website_isolation_server_wide` and :func:`deny_website_isolation_server_wide`, this function only flips the mode indicator directories. It does **not** clean up existing user isolation or alter the per-user exception lists. * ``allow_all`` → ``deny_all`` * ``deny_all`` → ``allow_all`` * not initialised → ``allow_all`` Returns: The new mode after toggling (``"allow_all"`` or ``"deny_all"``). r/r0Tr>rFr-) rPr:r r~rr3DIR_MODEr6r7r2)currentnew_modes r&toggle_isolation_user_moders'(((%''G+ L6\=R]abbbb l7tLLLLL L5L>D E EEr%cttjsdStsdSt sdSt jdd|gdddS)z;Create LVP infrastructure for user via lvectl (idempotent).N/usr/sbin/lvectlzallow-domain-limitsTrurGr r LVErrrMrNusernames r&_allow_domain_limitsr'sr %gk 2 2 # % % & ( (N&(=xHd444444r%cttjsdStsdSt jdd|gdddS)z1Tear down LVP infrastructure for user via lvectl.Nrzdeny-domain-limitsTrr r rrrMrNrs r&_deny_domain_limitsr4s_ %gk 2 2 # % %N&(sr %gk 2 2 # % % & ( (N 3V<4r%cttjsdStsdSt jdd|gdddS)z!Unregister domain LVE via lvectl.Nrzdisable-domain-limitsTrrrs r&_unregister_domain_lverMs_ %gk 2 2 # % %N 4f=4r%ctttjtjtjdtjtj dtD]S}t|s t|##tjtf$rt!jd|YPwxYwdS)u@Switch to *allow_all* mode – all users are allowed by default.Trr-z5Failed to enable domain limits for user %s, skipping.N)rPrr r~rr2rr6r7r3rrrrMCalledProcessErrorrr4 exceptionrs r&#allow_website_isolation_server_widerYs&(((K 1 8MX\]]]] M,4DIIIIII  8$$     * * * *-w7     G        s B+CCcttD]S}t|s t|##tjt f$rtjd|YPwxYwttj tj tjdtjtjddS)uSwitch to *deny_all* mode – no users are allowed by default. Disables domain isolation for every user and switches the mode. z6Failed to disable domain limits for user %s, skipping.Trr-N)_cleanup_all_users_isolationrrrrMrrr4rrPr r~rr3rr6r7r2rs r&"deny_website_isolation_server_wideros !"""II  8$$     ) ) ) )-w7     H       '(((K 29NY]^^^^ M,34HHHHHHsA+A.-A.rcttt}|dkr tjtj|np|dkr tjtj|nJtj tjtj dtjtj|t|dS)u;Allow website isolation for *username* (mode-aware). * **allow_all** – removes *username* from the denied directory. * **deny_all** – adds *username* to the allowed directory. * **not initialised** – sets up infrastructure in *deny_all* mode with *username* as the first allowed user. r/r0TrN) rPrr:rremove_user_from_dirr2add_user_to_dirr3r r~rrrr>s r& allow_website_isolation_for_userrs'((( " $ $D {),*KXVVVV   $\%GRRRR L6\=R]abbbb$\%GRRR"""""r%ct}|dkr tjtj|n%|dkrtjtj|t |t|dS)uDeny website isolation for *username* (mode-aware). * **allow_all** – adds *username* to the denied directory. * **deny_all** – removes *username* from the allowed directory. Also disables all domain isolation for the user. r/r0N)r:rrr2rr3_cleanup_user_isolationrrs r&deny_website_isolation_for_userrsx # $ $D {$\%FQQQQ   ),*LhWWWH%%%!!!!!r%c6t|sdStj|}|jsdSd|jD}tj|dt |d t j|n%#t$rtj d|YnwxYwt|t| |D]2\}}|tjd|t!j||3dS)z4Remove all domain isolation state for a single user.Nc.i|]}|t|Sr$_get_docroot_or_nonercds r& z+_cleanup_user_isolation..s0'(  " "r%)r) user_configz8Failed to remove LiteSpeed dedicated PHP handlers for %sfilter_by_docrootsz|Unable to detect document root for domain %s, configuration cleanup failed. Contact CloudLinux support if the error repeats.)rrload_user_configenabled_websitessave_user_configrr!remove_all_dedicated_php_handlers Exceptionr4rrlistvaluesrVerrorrremove_website_token_directory)ruser_cfgdomain_docroot_maprr s r&rrs x &x00H  $,4,E HT2222X48888R3H==== RRR F R R R R RR#T*<*C*C*E*E%F%F)..00 E E 7 ? M(     1(GDDDD E Es(A==BBcttD]7} t|#t$rt jd|Y4wxYwt}|st dSdS)z9Remove domain isolation state for every user that has it.z:Unable to disable website isolation for user %s, skipping.N)r#users_with_enabled_domain_isolationrrr4rr)r users_lefts r&rrs<>>??  #H - - - -     L       566J "!!!!!""s/AArc^ t|dS#ttf$rYdSwxYw)Nr)get_domain_docrootr IndexError)rs r&rrsA!&))!,, j !tts ,,ctsdS tj|}n#t$rYdSwxYwtj|S)NF)r'rget_jail_config_pathrr r!rW)r;domains_config_paths r&is_isolation_enabledrse 3 5 5u(=dCC uu 7>>- . ..s ' 55cpdtD}i}|D]}t|}|r|||<|S)NcNg|]"}t|t| |#Sr$)rr)rcus r&rez7users_with_enabled_domain_isolation..s1 P P P1[^^ P8LQ8O8O PQ P P Pr%)r#get_websites_with_enabled_isolation)usersuser_domain_pairsr;domains_with_isolations r&rrsV P P P P PE==!DT!J!J ! =&< d # r%ct|stjd|gStj|jS)Nz=User %s not found, cannot get websites with enabled isolation)rr4r5rrr)r;s r&rrsG t   KT S S S  "4 ( ( 99r%ct}tt}|D]S\}}|D]K} t |d}n#t t f$rY,wxYw|||LT|S)z Returns pairs user: set(docroots) for all users with website isolation enabled Used by monitoring service to watch docroots changes to load actual list of docroot paths instead of stale storage r)rrsetrVrr radd)users_with_isolationpairsr;domainsrdrs r&!get_docroots_of_isolated_websitesr s ?@@   E-3355  g  F '//2j)     $KOOB      LsAA+*A+ct|stjd|dStj|} t t |d}t|t |j n/#t$r"}tjd|||Yd}~dSd}~wwxYw||j vr|j |tj||tj||tj||t%jddd|gdt)|| t+j||n&#t.$rtjd ||YnwxYwt3|t5|g t7t9||t;|t=||dS) Nz2User %s not found, cannot enable website isolationrz4Skipping website isolation for user %s domain %s: %s cagefsctlz--rebuild-alt-php-iniz--domainT)ruz9Failed to apply LiteSpeed dedicated PHP handler for %s/%sr)rr4r5rrrrrrget_pw_by_namepw_dir ValueErrorrappendrcreate_website_token_directory create_overlay_storage_directoryrrMrNrrenable_dedicated_php_handlerrrrrrrrr)r;rr document_rootexcs r&enable_website_isolationrs5 t   @$ H H H)$//K();F)C)CA)FGG $]EGG4J4J44P4P4WXXXX  B &#      [111$++F333-dMBBB/mDDD D+...NK!8*fMUYZZZZT;/// W.t]CCCC WWW Gv W W W W WW#4=QRX=Y=Y> C(C##C(,DD$#D$cZt|stjd|dStj|}d}g}|-t |j}d|jD}g|_n6||jvr-|g}t|g}|j|tj ||t|||ry tj |d|jDn%#t$rtjd|YnwxYwt|||D]}|t!j|||D]D} t%||#t&jt*f$rtjd|YAwxYwt-}|st/dSdS)Nz3User %s not found, cannot disable website isolationc,g|]}t|Sr$r)rcwebsites r&rez-disable_website_isolation..s.   .5  ) )   r%c,g|]}t|Sr$rrs r&rez-disable_website_isolation..s!OOOQ%a((OOOr%rrz1Failed to unregister domain LVE for %s, skipping.)rr4r5rrrrrremoverrrrrrrrrrrMrrrr)r;rrreload_docrootsdomains_to_unregisterrrrs r&disable_website_isolationr sm t   A4 I I I)$//KO ~ $[%A B B  9D9U   (* $$ ;/ / /!'/778$++F333 D+...T;///K  U  6OO+2NOOO     U U U  Mt U U U U U U 'tPPPP, K KM$  5dM J J J J "HH H "4 + + + +-w7 H H H  CQ H H H H H H ?@@ "!!!!!""s$ $C11DD E+FFr)X functoolsr4r r6rMr collectionsrpathlibrclcommonrclcommon.clcagefsrrclcommon.cpapirr r rclcommon.constr clcommon.cpapi.cpapiexceptionsr lve_utils.pylve_wrapperr fsr exceptionsr webisolationrrrrwebisolation.configrwebisolation.docroot_validationrr webisolation.jail_config_builderrwebisolation.phprwebisolation.servicerrwebisolation.triggersrrr'r*rIr:boolr?rPrwr{rr|r^rkrrr lru_cacherrrrrrrrrrrrrrdictrrrrrr r$r%r&rs ######DDDDDDDD>>>>>>>>888888""""""333333))))))))))))EEEEEEEEEEEE777777[[[[[[[[FFFFFF<<<<<<SSSSSSSS^^^^^^^^AAAKKKt2"   $3[ FA *&@@@FCJ/+ Q " "  "FFF 4 4 4444      ,III4#s####."c""""&"Ec"E"E"E"EJ " " "///T:c::::4$?'?'?'D&L&L&LR4"4"C4"t4"4"4"4"4"4"r%