jgldddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl mZmZmZmZddlmZddlmZddlZd d lmZd d lmZdd lmZmZd d lmZd dl m!Z!ddl"m#Z# ddl$m%Z%ddl&m'Z'ddl(m)Z)m*Z*m+Z+ddl,m-Z-ddl.m/Z/n #e0$rYnwxYwGddeZ1dS))print_function)absolute_import)divisionN) configparser)S_IRUSRS_IWUSRS_IRGRPS_IROTH) iteritems)Path)ClSelect)ClSelectExcept)ClPwd clcaptain)clprint)utils)ExternalProgramFailed)BASEDIR)get_user_prefix)is_ea4_enabledread_cpanel_ea4_php_confconfigure_alt_php)da_change_user_php_ini)ispmanager_create_user_wrapperceZdZdZdZejrendZdZdZ d-dZ e d.d Z d Z d/d Zd0dZdZdZdZdZd1dZd1dZdedefdZd0dZdZdZdZdZdZd-dZd2dZe eZd Z d!Z!d"Z"d#Z#d$Z$d%Z%e e%Z%d&Z&d'Z'e e'Z'd3d(Z(d)Z)d*Z*e e*Z*d+Z+d,Z,dS)4 ClUserSelectz /var/cagefsz /usr/selectorz'/usr/share/cagefs-skeleton/usr/selectorz/etc/cagefs/excludez.cl.selector/selector.pathNc\tjs!tjdsdS|D]}|j|}tj|jd}tj|s| |} tj |n.#ttf$r}tj||d}~wwxYw t |#t |wxYwdS)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.enabledNmod_lsapi_reset_me)r in_cagefsospathisfile_clpwdget_pw_by_namejoinpw_dir _change_uidrwriteOSErrorrrUnableToSaveDatar _restore_uid)selfusersuserpwr"previous_user_dataes L/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/cluserselect.pyclean_crui_imageszClUserSelect.clean_crui_images/s9   8Y)Z)Z  F B BD++D11B7<< +?@@D7>>$'' B%)%5%5d%;%;"BOD))))!67CCC(9$BBBC*!--.@AAAAL--.@AAAA B B Bs*-CD C-C((C--D  D(Tc4tjts;t js(t d|rtjdndS|rutrgt}|rW |d}| ds(t d|rtjdndSn#t$rYnwxYwt||dtjdk| }|r|rtjd|S) z Switch symlink for alt php. Create .cagefs directory if not created Rerurn True if error has occured ERROR: CageFS not installed.r Tdefaultzea-phpzlERROR: system default PHP version is alt-php. PHP Selector is disabled. Use cPanel MultiPHP manager instead.Fr) write_log drop_permconfigure_multiphp)r!r"isdirrrr printsysexitrr startswithKeyErrorrgeteuid)versionr0 exit_on_errorr:conf default_phperrors r3switch_symlink_for_alt_phpz'ClUserSelect.switch_symlink_for_alt_phpHsMw}}W%% eo.?.?  0 1 1 1  t  ."2"2 +--D  "&y/K&11(;;(_```((HQKKKK#'4D""g2:<<[\K\uGHHH  ]  HQKKK sAC CCc|jr#tdtjdt jdkr#tdtjd|}t|D]M\}}td||j |}t ||ddNdS)NzPERROR: this option does not work in "single user" mode (when CageFS is disabled)r rzERROR: root privileges requiredzProcessing userF)rCr:) without_cagefsr<r=r>r!rAget_user_version_mapr r$r%rrG)r-users_vers_dictr/rBr0s r3apply_symlinks_rulesz!ClUserSelect.apply_symlinks_rulesms    d e e e HQKKK :<<1   3 4 4 4 HQKKK3355&77 p pMD' #T * * *++D11B  3 3GRuin 3 o o o o p pphpctj||t|_t |_|r ||_dSg|_dSN)r__init__rr$set_user_excludesexclude_pid_list)r-itemrTs r3rQzClUserSelect.__init__zsP$%%%gg !ee  '$4D ! ! !$&D ! ! !rMFc ||}|}tj|s|Stj|j}tj |s|Stj |j r9j s jj jkr|Stjjkr|S t!t#fdt!d}||d|djfS#t&t(f$r|cYSwxYw)zl Returns alternative version for a user @param user: string @return: string c>|djkS)Ndata)_item)i alternativeslink_dstr-s r3z*ClUserSelect.get_version..s<?624:>rMrrBrX)_check_user_in_cagefs_compose_user_alt_path_compose_native_infor!r"r;get_all_alternatives_datar&rYislinkreadlinkrI_native_contents_load_native_contentsdirname SELECTOR_PATHlistfilterkeys IndexErrorr@) r-r/show_native_versionalt_pathnative full_pathrBr[r\s ` @@r3 get_versionzClUserSelect.get_versions ""4(((..t44**+>??w}}X&& M5577 GLL4:66 w~~i(( M;y))   ( 7**4:66640<<< 7??8 $ $(: : :M 6\&&(())++,,-./G ))4 )&1$*=? ?H%   MMM s=A.F,,GGcntj|s||} t j|n.#t tf$r}tj ||d}~wwxYw t |dS#t |wxYwdSrP) r!r"r;r(rmkdirr*rrr+rr,)r-r"r/r1r2s r3 create_dirzClUserSelect.create_dirsw}}T"" >!%!1!1$!7!7  >%%%%23 ? ? ?$5dA>>> ?&))*<===== ))*<==== > >s)A B A6A11A66BB2cp|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_homedirr!r"r& SELECTOR2_DIRr(rs_create_symlinkr,)r-r/homedir path_in_homecur_users r3create_selector_symlinksz%ClUserSelect.create_selector_symlinkss+))$//w||GT-?@@ ##D))  d+++ \<+>PTUUU X|J'>PTUUU (#####rMctjtjrD |jd|jS#tj ttf$rYdSwxYwdS)Nversionsrn) r!r"r#r DEFAULTS_PATH_dhgetrY ConfigParserErrorIOErrorr@)r-s r3get_default_versionz ClUserSelect.get_default_versionsi 7>>(0 1 1  x||J ;;; &:   xx xsA A+*A+cJtj|j|dd}tj|s*|||dS ||}||| d|j dS#tj ttf$r<}tdt!|t#jdYd}~dSd}~wwxYw)N .cl.selector defaults.cfgr~z*Error while restoring settings from backupr )r!r"r&r$rvr# set_versionr_get_default_config_handlerrrYrrrr@r<strr=r>)r-r/user_backup_pathdhr2s r3set_version_from_backupz$ClUserSelect.set_version_from_backups7<< (?(?(E(E~Weffw~~.//    T4#;#;#=#= > > > > > 556FGG  rvvj$*'E'EFFFFF &:   BCFFKKK  sAC D"&1DD"c Dtjdkr+||x}rtj|t j|j|j |j |tj ||||}|r|SdS)zz Sets alternative version for a users with the same uid @param user: string @return: None rN) r!rA"get_version_selection_disabled_msgrVersionModificationBlockedrapply_for_at_least_one_user _set_versionr$ get_namesget_uidNoUserSelector)r-r/rBreturn_summaryrlrCmessagerXs r3rzClUserSelect.set_versions :<<1  T-T-TUY-Z-Z"Z'  ;GDD D0   K ! !$+"5"5d";"; < <  ) ^%8-     K  rMc6|jr||}||||}tj|s2|jr|||ntj || }||vr|dkrtj || ||j |} |dkr|jr[|js||jt%|jD]#\} } || |dz| z||$nd} d} tj|jd| }tj|rbtjd|jz| }tj|| }|||||d} t j|jD]}|j|vr |dr| r$tj||}tj|j|}|||||nWt%||d D];\} }||tj|| ||<|jrt4|n3t4|| | ||||||||r| ||Sd S) zg Sets alternative version for a user @param user: string @return: None rn/zphp.iniFz.etcz%s.etcT.inirXrCN)!rIr(r^r_r!r"r;rsrrraNoSuchAlternativeVersion_remove_alternatives_linksr$r%rdrerYr rxr& NATIVE_PATHexistsrglistdirendswithrr,rG_switch_php_da_isp_reload_processes_backup_settings get_summary)r-r/rBrrlrCr1rmr[r0rU native_pathininew_ini_created new_ini_pathsrcdstfilenamer"s r3rzClUserSelect._set_versions   8!%!1!1$!7!7  ""4(((..t44w}}X&& :" :$////$3D9995577 , & &7h+>+> 9'BB B ''111 [ ' ' - - h  " B,;..tz:::)243H)I)IXX%D+((hsl46GwWWWWX "'!w||8H8H8H,JCPP 7>>,//+',,x$2D'DcJJC',,x55C((c4AAA&*O " 4+; < <BBHz11 ((00!_! ',,x::C',,t'98DDC((c4AAAAB( W(=f(EFF X X d$$T27<<$+G+GwWWWW   3  % %&8 9 9 9 9  3 3GRQ^ 3 _ _ _  # #D' 2 2 2 t$$$ d###  ?##D*=>> > ? ?rMusernamereturncn|j|}td|d}|sdS |d5}t j|}|ddcdddS#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.jsonzutf-8)encodingversion_selection_disabled_msgN) r$rr ropenjsonloadrr* ValueError)r-ruid config_filef config_datas r3rz/ClUserSelect.get_version_selection_disabled_msg s#k!!(++`s```aa !!## 2 !!7!33 Mq"ill "'GLL M M M M M M M M M M M M M M M M M M$   22 s6B*B BBBBBB43B4c6|||}||}dddddi}t|}|d||d}|D]O}||vri||<|j|j |d ||d<d||d<d||d <P |j d |j } n##tj tj f$rd} YnwxYw d|| d<d||d <n"#t$rtj| wxYw|d||d<|d||dt't)|D]8} || } | || d|| d|| d ff|| <9t+|S) zb Returns state of alternatives @param user: string @return: tuple rnTF)enabledr7selectedrstaterr7rr~)r^rar`sortedrjappendrpr has_optionrYrrNoSectionError NoOptionErrorr@rrpopremoverangelentuple) r-r/rlr[ native_infosummary alt_versionsselected_versionrBdefault_versionidxvs r3rzClUserSelect.get_summary9s{ ""4(((5577 //0CDD 5BBCl//1122 H%%%++D11!4# 1 1Gg%%#% .2h.A.A**gg./9/9+9GG Y '*/GG Y '+0GG Z ( ( '"hll:tzBBOO+\-GH ' ' '&OOO ' K26GO $Y /48G$ %j 1 1 K K K 9/JJ J K")++h"7"7 AH%%%KN+++\**++ * *CS!AI&I&J')!*L   \"""s+ D D,+D,0EE&c ||}|D]W} |||d#t$r/}tjddt |dYd}~Pd}~wwxYw||dS)z Changes users of a supplied version to specified_version @param version: string @param current_version: string FrtextERROR)statusrN) list_usersr Exceptionr print_diagrr4)r- new_versioncurrent_versionr.r/r2s r3change_to_versionzClUserSelect.change_to_versioncs 00  D   {E JJJJ   "6g#a&&+Q+QRRR  u%%%%%s4 A-%A((A-cF|}||vr||SgS)z8 Returns users of a certain alternative )get_version_user_map)r-rBrXs r3rzClUserSelect.list_usersrs-((** d??=  rMc|jrddlm}|gSt||S)zF Returns all valid system users @return: list r )get_cpanel_user)rIclselectctlphprrh_get_system_users difference_get_user_excludes)r-rs r3list_all_userszClUserSelect.list_all_users{sq   ' 7 7 7 7 7 7#O%%& &D**,,77  # # % %''(( (rMct}d|d<d|d<d|d<d}tj| ddl}n3#t $r&t dtjdYnwxYwtj tt||d}tj |d zr"tj |d zs| ||dSdS) Nrinitreinitverbose/usr/share/cagefsr6r etcz /cl.selectorz /cl.php.d)dictr=r"r cagefsctl ImportErrorr<r>r!r&rrrcpetc_for_user)r-r/configLIBDIRrcagefs_etc_paths r3cagefs_copy_etczClUserSelect.cagefs_copy_etcsvxy$           0 1 1 1 HQKKKKK ',,w0E0EtUSSw~~o>?? 3GNN?[#@AA 3  $ $T6 2 2 2 2 2 3 3sA-A54A5c|}i}|D]7} ||dd||<##tj$rY4wxYw|S)zH Returns user version map as dict @return: dict Fr)rrpr NotCageFSUser)r- actual_usersrXr/s r3rJz!ClUserSelect.get_user_version_mapsv **,,    D !--dE::1=T !/     s<A Ac|p|}i}|D]X} ||dd}||vrg||<|||D#tj$rYUwxYw|S)zH Returns users grouped by version @return: dict Fr)rrprrr)r- user_namesrrXr/rBs r3rz!ClUserSelect.get_version_user_maps ":T%8%8%:%:    D **477:$$&DMW $$T****!/     sAAA10A1c  |rbtj|r/tj||krtj|ndSt j|tj||dS#t$r=}||tj |||tj d|d|d|dd}~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 ()) r!r"rbrcunlinkrremove_file_or_dirrsymlinkrrUnableToSetAlternativeSelectorException)rrr/rBrur2s r3rxzClUserSelect._create_symlinks L 27>>#&&2{3''3.. #,S111  c3 ' ' ' ' ' L L LG$7$;D'1MMM 22>Acc333JLL L LsAA=)A== C8B??Cc |jr|jStj|jst Stj|jD]}tj|j|}|jt tdtj | |jS)zE Returns list of user excludes @return: list c*|SrP)strip)xs r3r]z1ClUserSelect._get_user_excludes..s17799rM) rSr!r"r;CAGEFS_EXCLUDErRrr&updatemaprread_file_as_string splitlines)r-rUfull_item_paths r3rzClUserSelect._get_user_excludess   '& &w}}T011 55LJt233 R RDW\\$*=tDDN   & &,,1.AALLNNPPQQ R R R R""rMc|jrdStjrdSd}tj| ddl}n3#t$r&tdtj dYnwxYw | |stj |dS#t$r'tdtj dYdSwxYw)z4 Check that cagefs enabled for user Nrrr6r z;ERROR: CageFS version is unsupported. Please update CageFS.)rIrr r=r"rrrr<r>is_user_enabledrrAttributeError)r-r/rrs r3r^z"ClUserSelect._check_user_in_cagefss    F ?    F$           0 1 1 1 HQKKKKK  ,,T22 9$24888 9 9    O P P P HQKKKKKK s$A-A65A6:)B%%-CCctj|D]`}|j|vr tj||}tj|sLtj|adS)zg Removes all symlinks from directory @param path: string @return: None N)r!rrYr"r&rbr)r-r"rros r3rz'ClUserSelect._remove_alternatives_linkssx  4(( ! !Hz)) T844I7>>),,  Ii  ! !rMc&|jr|j|}|dzSt|j|}t jrdn/tj |j |dd|ddS)zz Composes and returns user alternative directory path @param user: string @return: string z /.cl.selectorz/etc/cl.selectorNrz cl.selector) rIr$rvrrrr r!r"r& CAGEFS_PATH)r-r/ryrs r3r_z#ClUserSelect._compose_user_alt_path s   -k--d33G_, ,$+%%d++,,   Q   GLL)3rss8T5- P P rMcv|j}t|S)zB Returns set of system users @return: set )r$ get_user_dictrRrj)r- users_dicts r3rzClUserSelect._get_system_userss/ [..00 :??$$%%%rMctj|r: tj|dS#t$rt j|dwxYwdS)z? Deletes file to be written if it is a symlink z'Cannot delete symlink while saving dataN)r!r"rbrr*rr+) file_paths r3_delete_if_symlinkzClUserSelect._delete_if_symlink"su 7>>) $ $ ? ? )$$$$$ ? ? ?$5=??? ? ? ?s 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_uidpw_gidr!rAgetegidsetegidseteuidsecureioset_capabilityr*rUnableToChangeToAnotherUser)r-r/entrynew_uidnew_gidcur_euidcur_egidr2s r3r(zClUserSelect._change_uid/s  **400,,:<<:<< w  X% % F Jw    Jw     # % % %X% % F F F B B=#B88B=cL|dtjkrtjd tj|dtj|ddS#t $r-}tjt|d|d}~wwxYwdS)zw Restores changed uid and gid to original ones @param uid_and_gid: tuple @return: None rT)clearr N) r!rArrrrr*rrr) uid_and_gidr2s r3r,zClUserSelect._restore_uidDs q>RZ\\ ) )  #$ / / / / Y ;q>*** ;q>***** Y Y Y$@[QR^ATATVWXXX Y * )s4A** B!4(BB!c|s!tj|sdS||||}tj|} dt tjz}tj ||}tj ||d ttztztz} tj||tj|| n#t$$rYnwxYw#t&t$t(f$rp} tj|rtj|n#YnxYwt,|t1j|| d} ~ wwxYwt,|dS)z Saves data to file @param user: string @param file_contents: string @param file_path: string @return: None Nz clseltmp_%s )r!r"rrr(rfruuiduuid4r&rr)rrr r renamechmodr*rrrrr,rr+) r-r/ file_contentsrcreater1file_directoryrf temp_pathmaskr2s r3_write_to_filezClUserSelect._write_to_fileSs bgnnY77  F  ***!--d3333 #c$*,,&7&77G ^W==I OI'@ A A A (72W< )Y///D))))    "78 @ @ @ 7>>),,)Ii(((   % %&8 9 9 9 1)Q?? ? @ !!"455555s>.AD$ A D D! D!$F+<3E0/F&0E424F&&F+c6 tj}tdD]8}|}| |j|j8n#tj$rYnwxYw t |}n#tj f$rYdSwxYw tj D]} || j | jfvs0||jdkrh|j}n#tj$rYwxYw ||jvrt%j|t(j#t,f$rYwxYwdS#t,t.f$rYdSwxYw)z& Reloads user process N)psutilProcessrparentrTrpid NoSuchProcessrrNoSuchUserException process_iteruidsreal effectivenamefindrYr!killsignalSIGHUPr*r)r-r/ next_parentrZrprocr8s r3rzClUserSelect._reload_processesvs  .**K1XX  )0022 *)00AAAA#    D  ''//$''CC),    FF  +--  499;;#3TYY[[5J"KKKtyy{{O_O_`d`jOkOkoqOqOq (CC+H$"777V]333{H  !    DD sAAA0/A04!BB*)B*.FA$D1(F)D10F1EFEF(E0/F0 E>;F=E>>FFFcg} t|}|D]I}|dr2|d|d}||J|n#t t f$rYnwxYw|S)zH Get extension names from user extensions file comments z;---z---)rr?rfindrcloser*r)r" extensionsrlineexts r3_skim_over_extensionsz"ClUserSelect._skim_over_extensionss  t**C + +??6**+qE!2!223C%%c*** IIKKKK!    D sA/A44BBc ||g}||}tjtj|d}|}tj|j|d}tj |s| |} tj |nH#ttf$r4}t|t#j||d}~wwxYwt|tj|d} tj |r(d|jd||dd} n d|jd } || t-|D]} |jr |d z| d d zd z} n8tj|d| d d d} || } |d|j| ddt-| d||d|| dS)zk Scans all user settings and backups'em in homedir as INI file @param user: string zcl.php.drNrz [versions] z = rr'z = native z/alt_php.rrzalt-phpz alt_php.ini[z ] modules = ,)r^r_r!r"r&rfrar$rvr;r(rrrr*rrr,rr+rYrprrrjrIreplacerMr1)r-r/backup_contents user_alt_path user_ext_pathr[rr1r2user_backup_filerBalt curr_ext_pathrJs r3rzClUserSelect._backup_settingss ""4(((33D99  RW__]%C%CZPP 5577 7<< K # #D ) )>;;w}}-.. :!%!1!1$!7!7  K 0111123 K K K))*<===$56FJJJ K  % %&8 9 9 97<< n.. 7== ' ' B B D,,T2215557GG B6:ZZZAGw''',++--.. D DC" A - :S[[b=Q=Q QTZ Z " !MS"---$12?!A!A 33MBBJ  " " "JJSXXfZ.@.@%A%A%A%AC D D D D  $))O,,.> @ @ @ @ @s+DE/EEcX|jrdSt||t||dSrP)rIrr)r-r/rBs r3rzClUserSelect._switch_php_da_isps8    FtW---&tW55555rMrP)TT)rNN)F)FFT)NNF)T)-__name__ __module__ __qualname__rrgrr rrrwr4 staticmethodrGrLrQrprsr|rrrrrrrrrrrrJrrxrr^rr_rrr(r,r1rrMrrrMr3rr'sK#M#25?#4#4c--:cK*N0MBBBB2"""\"H p p p''''    F>>> $ $ $   &8?8?8?8?t332(#(#(#(#T & & & ( ( (333&   "LLLL2#l?33O###"0 ! ! !   &&& ? ? ?&&899FFF* Y Y Y < --L!6!6!6!6F"""H)L)>??(@(@(@T66666rMr)2 __future__rrrrr!r=r(rBr future.movesrrstatrrr r future.utilsr pathlibr r5clselectrclselectexceptrclcommonrr clselectprintrrrclcommon.utilsrclcagefslib.constrclcagefslib.fsrclcagefslib.selector.configurerrrclcagefslib.selector.panel.darclcagefslib.selector.panel.isprrrr^rMr3rns&%%%%%&&&&&& 555555333333333333"""""" ******%%%%%%%%""""""000000 ))))))......jjjjjjjjjjDDDDDDMMMMMMM   D r 6r 6r 6r 6r 68r 6r 6r 6r 6r 6s4"BBB