izddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl mZmZmZmZddlmZddlmZddlZd d lmZd d lmZdd lmZmZd d lmZd dl m!Z!ddlm"Z"ddl#m$Z$ddl%m&Z&m'Z'm(Z(ddl)m*Z*m+Z+ ddl,m-Z-ddl.m/Z/ddl0m1Z1m2Z2m3Z3ddl4m5Z5ddl6m7Z7n #e8$rYnwxYw ddl9m:Z:ddl;mr).stceZdZdZdZejrendZdZdZ d.dZ e d/d Z d Z d0d Zd1dZdZdZdZdZdZ d2dZd2dZdedefdZd3dZdZdZdZdZdZd4dZd5d Z e e Z d!Z!d"Z"d#Z#d.d$Z$d%Z%d&Z&e e&Z&d'Z'd(Z(e e(Z(d6d)Z)d*Z*d+Z+e e+Z+d,Z,d-Z-dS)7 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)selfusersuserpwr1previous_user_dataes r(clean_crui_imageszClUserSelect.clean_crui_images9s:!## BGNN;\,],]  F B BD++D11B7<< +?@@D7>>$'' B%)%5%5d%;%;"BOD))))!67CCC(9$BBBC*!--.@AAAAL--.@AAAA B B Bs*-CD C-C((C--D  D(Tc Rtjts;t js(t d|rtjdndS|rutrgt}|rW |d}| ds(t d|rtjdndSn#t$rYnwxYwt|||dtjdk| }|r|rtjd|stt!t|jj} t'|j} n#t($rg} YnwxYw| D]4\} } | |vr t||| dtjdk| 5|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)r0r1isdirrrr/printsysexitrr startswithKeyErrorrgeteuidr#setpw_nameenabled_websitesrr) versionr? document_root exit_on_errorrHconf default_phperrorisolated_domainstarget_domainsdomaindomain_docroots r(switch_symlink_for_alt_phpz'ClUserSelect.switch_symlink_for_alt_phpQsw}}W%% h.@.B.B  0 1 1 1  t  ."2"2 +--D "&y/K&11(;;(])(HQKKKK#'4D" z||q(1      ]  HQKKK !1!="#3BJ#?#?#PQQ  $!,RZ!8!8 $ $ $!# $+9  &!111!#!z||q0'9  s%AC CC E E-,E-c|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)rUrH) without_cagefsrJrKrLr0rOget_user_version_mapr r3r4r,r])r<users_vers_dictr>rSr?s r(apply_symlinks_rulesz!ClUserSelect.apply_symlinks_ruless    d e e e HQKKK :<<1   3 4 4 4 HQKKK3355&77 p pMD' #T * * *++D11B  3 3GRuin 3 o o o o p pr*phpctj||t|_t |_|r ||_dSg|_dSr%)r__init__rr3rP_user_excludesexclude_pid_list)r<itemrgs r(rezClUserSelect.__init__sP$%%%gg !ee  '$4D ! ! !$&D ! ! !r*Fc L ||}|r_t|d}||}tj|s|}|}tj|s|S tj|j }tj |s|Stj | j r9j sj  j j kr|Stj jkr|S t#t% fdt# d}| |d |dj fS#t(t*f$r|cYSwxYw)zl Returns alternative version for a user @param user: string @return: string rc>|djkS)Ndata)_item)i alternativeslink_dstr<s r(r)z*ClUserSelect.get_version..s,q/&"9$*"E"Qr*rSrk)_check_user_in_cagefs_compose_user_alt_pathrr0r1rI_compose_native_infoget_all_alternatives_datar5rlislinkreadlinkr__native_contents_load_native_contentsdirname SELECTOR_PATHlistfilterkeys IndexErrorrN) r<r>r[show_native_versionalt_pathrTnative full_pathrSrnros ` @@r( get_versionzClUserSelect.get_versions ""4(((..t44  =#FOOA.M224GGH7==** =66t<<**+>??w}}X&& M5577 GLL4:66 w~~i(( M;y))   ( 7**4:66640<<< 7??8 $ $(: : :M QQQQQQTXYeYjYjYlYlTmTmnnG\'29=|G?TU[?\]a]g?hi iH%   MMM sA.H H#"H#cntj|s||} t j|n.#t tf$r}tj ||d}~wwxYw t |dS#t |wxYwdSr%) r0r1rIr7rmkdirr9rrr:r,r;)r<r1r>r@rAs r( 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) r3 get_homedirr0r1r5 SELECTOR2_DIRr7r_create_symlinkr;)r<r>homedir path_in_homecur_users r(create_selector_symlinksz%ClUserSelect.create_selector_symlinkss+))$//w||GT-?@@ ##D))  d+++ \<&+@RVWWW X|j'@RVWWW (#####r*ctjtjrD |jd|jS#tj ttf$rYdSwxYwdS)Nversionsr) r0r1r2r DEFAULTS_PATH_dhgetrl ConfigParserErrorIOErrorrN)r<s r(get_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.cfgrz*Error while restoring settings from backupr )r0r1r5r3rr2 set_versionr_get_default_config_handlerrrlrrrrNrJstrrKrL)r<r>user_backup_pathdhrAs r(set_version_from_backupz$ClUserSelect.set_version_from_backups7<< (?(?(E(E~Weffw~~.//    T4#;#;#=#= > > > > > 556FGG  rvvj$*'E'EFFFFF &:   BCFFKKK  sAC D"&1DD"cR|j|j|dsdSdS)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_optionrl)r<rSs r(_version_enabledzClUserSelect._version_enableds3x""TZZ#A7KK 45r*c (tjdkr+||x}rtj|||stjd|z|rC 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 )r0rO"get_version_selection_disabled_msgrVersionModificationBlockedrrrSelectorExceptionrapply_for_at_least_one_user _set_versionr3 get_namesget_uidNoUserSelector) r<r>rSr[return_summaryr~rUmessageownerrks r(rzClUserSelect.set_versionsG :<<1  T-T-TUY-Z-Z"Z'  ;GDD D$$W-- q ;rSr[rr~rUr@rTrrnr?rh native_pathininew_ini_created new_ini_pathsrcdstfilenamer1s r(rzClUserSelect._set_version+s   8!%!1!1$!7!7  ""4(((  /#FOOA.M..t]CCw}}X&& :" :f :$////$3D9995577 , & &7h+>+> 9'BB B ''111 [ ' ' - - h  " B,;..tz:::)243H)I)I\\%D+((hnt6KTSZ[[[[\ "'!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 3GRBOBO 4 Q Q Q  # #D' 2 2 2 t$$$ d###  ?##D*=>> > ? ?r*usernamereturncn|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.jsonrzutf-8)encodingversion_selection_disabled_msgN) r3rr ropenjsonloadrr9 ValueError)r<ruid config_filef config_datas r(rz/ClUserSelect.get_version_selection_disabled_msgjs#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 BBBBBB43B4c|||}||}dddddi}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||dg} t'|D]z\} } t)|| d|| d|| dfs<| | || 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). rTF)enabledrEselectedrrrErr)rprsrrsortedr|appendrrrrrlrNoSectionError NoOptionErrorrNrrpopremove enumerateanytuple) r<r>r~rn native_infosummary alt_versionsselected_versionrSdefault_versionresultidxvs r(rzClUserSelect.get_summarys ""4(((5577 //0CDD %USSTl//1122 H%%%++D11!4# 1 1Gg%%#% *.*?*?*H*HGG 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+++ -- g gFC 9-wqz)/DgajQ[F\]^^  MM1wqz)4gaj6KWUVZXbMcde f f f fV}}s C<<DD D77Ec ||}|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 F)rUtextERROR)statusrN) list_usersr Exceptionr print_diagrrB)r< new_versioncurrent_versionr=r>rAs r(change_to_versionzClUserSelect.change_to_versions 00  D   {% HHHH   "6g#a&&+Q+QRRR  u%%%%%s4 A-%A((A-cF|}||vr||SgS)z8 Returns users of a certain alternative )get_version_user_map)r<rSrks r(rzClUserSelect.list_userss-((** d??=  r*c|jrddlm}|gSt||S)zF Returns all valid system users @return: list r )get_cpanel_user)r_clselectctlphprrz_get_system_users difference_get_user_excludes)r<rs r(list_all_userszClUserSelect.list_all_userssf   ' 7 7 7 7 7 7#O%%& &D**,,778O8O8Q8QRRSSSr*ct}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/cagefsrDr etcz /cl.selectorz /cl.php.d)dictrKr1r cagefsctl ImportErrorrJrLr0r5rrrcpetc_for_user)r<r>configLIBDIRrcagefs_etc_paths r(cagefs_copy_etczClUserSelect.cagefs_copy_etcsvxy$           0 1 1 1 HQKKKKK ',,w0E0EtUSSw~~o>?? 3rw~~VehsVsGtGt 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)rrr NotCageFSUser)r< actual_usersrkr>s r(r`z!ClUserSelect.get_user_version_mapsv **,,    D !--dE::1=T !/     s<A Ac|p|}i}|D]Y} |||dd}||vrg||<|||E#tj$rYVwxYw|S)zH Returns users grouped by version @return: dict Fr)rrrrr )r< user_namesr[r rkr>rSs r(rz!ClUserSelect.get_version_user_maps ":T%8%8%:%:    D **4??B$$&DMW $$T****!/     sAA  A21A2c  |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 ()) r0r1rtruunlinkrremove_file_or_dirrsymlinkrrUnableToSetAlternativer)rrr>rSrrAs r(rzClUserSelect._create_symlinks o 27>>#&&2{3''3.. #,S111  c3 ' ' ' ' ' o o oG$7$;D'1MMM 22adadadfififiklklkl3mnn n osAA=)A== C8B??Cc |jr|jStj|jst Stj|jD]}tj|j|}|jt tdtj | |jS)zE Returns list of user excludes @return: list c*|Sr%)strip)xs r(r)z1ClUserSelect._get_user_excludes../s17799r*) rfr0r1rICAGEFS_EXCLUDErPrr5updatemaprread_file_as_string splitlines)r<rhfull_item_paths r(rzClUserSelect._get_user_excludes#s   '& &w}}T011 55LJt233  DW\\$*=tDDN   & &C,,u/H/X/X/c/c/e/effgg    ""r*c|jrdStjrdSd}tj| ddl}n3#t$r&tdtj dYnwxYw | |stj |dS#t$r'tdtj dYdSwxYw)z4 Check that cagefs enabled for user NrrrDr z;ERROR: CageFS version is unsupported. Please update CageFS.)r_rr/rKr1rrrrJrLis_user_enabledrr AttributeError)r<r>rrs r(rpz"ClUserSelect._check_user_in_cagefs3s    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)r0rrlr1r5rtr)r<r1rrs r(rz'ClUserSelect._remove_alternatives_linksKsx  4(( ! !Hz)) T844I7>>),,  Ii  ! !r*c|jr|j|}|dzSt|j|}d}|r|rt |nd}t js0tj |j |dd|ddnd}|r tj ||n|S)zz Composes and returns user alternative directory path @param user: string @return: string z /.cl.selectorrNrz cl.selectorz/etc/cl.selector) r_r3rrrr"rr/r0r1r5 CAGEFS_PATH)r<r>rTrrdocument_root_idbases r(rqz#ClUserSelect._compose_user_alt_pathYs   -k--d33G_, ,$+%%d++,,  V@MU~m<<>) $ $ l l )$$$$$ l l l$5iAjkkk 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)r3r4pw_uidpw_gidr0rOgetegidsetegidseteuidsecureioset_capabilityr9rUnableToChangeToAnotherUser)r<r>entrynew_uidnew_gidcur_euidcur_egidrAs r(r7zClUserSelect._change_uids  **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) r0rOr2r3r0r1r9rr4r) uid_and_gidrAs r(r;zClUserSelect._restore_uids 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 )r0r1rr+r7rxruuiduuid4r5rr8rrr r renamechmodr9rrrr,r;rr:) r<r> file_contentsr*creater@file_directoryrx temp_pathmaskrAs r(_write_to_filezClUserSelect._write_to_files 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)psutilProcessrangeparentrgrpid NoSuchProcessrrNoSuchUserException process_iteruidsreal effectivenamefindrlr0killsignalSIGHUPr9r)r<r> next_parentrmrprocrPs r(rzClUserSelect._reload_processess  .**K1XX  )0022 *)00AAAA#    D  ''//$''CC)+    FF  +--  499;;#3TYY[[5J"KKKtyy{{O_O_`d`jOkOkoqOqOq (CC+H$"777V]333zH  !    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---)rrMrfindrcloser9r)r1 extensionsrlineexts r(_skim_over_extensionsz"ClUserSelect._skim_over_extensionss  t**C + +??6**+q4::e#4#445C%%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 = ,)rprqr0r1r5rxrsr3rrIr7rrr9rr,r;rr:rlrrrr|r_replacererH)r<r>backup_contents user_alt_path user_ext_pathrnrr@rAuser_backup_filerSalt curr_ext_pathrbs r(rzClUserSelect._backup_settingss ""4(((33D99  RW__]%C%CZPP 5577 7<< (?(?(E(E~VVw}}-.. :!%!1!1$!7!7  K 0111123 K K K))*<===$56FJJJ K  % %&8 9 9 97<<(8.II 7== ' ' B B15T=M=Md=S=STU=V=V=VWGG B6:ZZZAGw''',++--.. o oC" t - :S[[b=Q=Q QTZ Z " ]]CKKX[]_L`L`L`NOOOOOs+DE/EEcX|jrdSt||t||dSr%)r_r r!)r<r>rSs r(rzClUserSelect._switch_php_da_isp"s8    FtW---&tW55555r*r%)NTT)rcN)NF)NFFT)F)NN)NNF)T).__name__ __module__ __qualname__r#ryrr/rrrrB staticmethodr]rbrerrrrrrrrrrrrrrrr`rrrrprrqrr+r7r;rHrrerrr&r*r(r,r,2sK#M#58#5#7#7f--=fK*N0MBBBB0AAA\AF p p p''''""""H>>> $ $ $      ae""""H=?=?=?=?~332////b & & & T T T333$   "oooo2#l?33O### 0 ! ! !RRRR*&&&lll&&899FFF* Y Y Y < --L!6!6!6!6F"""H )L)>?? P P PD66666r*r,)> __future__rrrrr0rKr?rZr2 future.movesrrstatrrr r future.utilsr pathlibr rLclselectrclselectexceptrclcommonrr clselectprintrrrrclcommon.utilsrclcommon.cpapirrrclcommon.cpapi.cpapiexceptionsrrclcagefslib.constrclcagefslib.fsrclcagefslib.selector.configurerrrclcagefslib.selector.panel.dar clcagefslib.selector.panel.ispr!r#clcagefslib.webisolation.jail_utilsr"clcagefslib.webisolation.configr#r,r&r*r(rs&%%%%%&&&&&& 555555333333333333"""""" ******%%%%%%%%""""""000000==========@@@@@@@@ ))))))......jjjjjjjjjjDDDDDDMMMMMMM   D BBBBBB@@@@@@@#^N t 6t 6t 6t 6t 68t 6t 6t 6t 6t 6s$ "B//B76B7; C CC