B
    u&`                @   s	  d dl mZ d dl mZ d dl mZ d dl mZ d dlZd dlmZ e  d dl	T d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlmZmZmZmZm Z  d d	lm!Z!m"Z"m#Z#m$Z$ d d
lm%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,Z,d dl-m.Z.m/Z/ d dl0m1Z1m2Z2 d dl3Z3d dl4m5Z5 d dl6m7Z7m8Z8m9Z9 d dl,m:Z:m;Z; G dd de<Z=dZ>de> Z?dZ@dZAdZBdZCdZDd ZEdaFdZGdaHdZIdZJdZKdZLdZMd ZNd!eL ZOd"ZPd#ZQd$ZRd%d& ZSdd'd(d)ZTdd'd*d+ZUdd'd,d-ZVd.d/ ZWeXd'd0d1ZYeXd'd2d3ZZd4d5 Z[d6d7 Z\d8d9 Z]d:d; Z^ej_dfd<d=Z`d>d? Zaea peJZbg Zcd@dA ZddBdC ZedDdE ZfdFdG ZgdZhdHZidHZjdHZkdIdJ ZldKdL Zmi and{dMdNZodOdP ZpdQdR ZqdSdT ZrdUdV Zsg ZtdWdX ZudYdZ Zvd[d\ Zwd]d^ Zxd_d` Zydadb Zzi a{dcdd Z|dedf Z}dgdh Z~didj Zdkdl Zi admdn Zdodp Zd|drdsZi ad}dtduZdvdw Zd~dxdyZddzd{Zd|d} Zdd~dZdddZdd Zdd Zi add ZdddZdddZdddZd d ddd g d fddZdd ZdddZdddZdd Zdd Zdd Zdd Zdd ZdZdZi Zi Zdd Zdd Zdd ZdddZddddddadZdZdZde Zed d Zdadd Zdd Zdadd Zdd Zdd Zdd ZddÄ ZdddńZddǄ ZdZdddʄZdd̄ Zd d ddd d g d fdd΄ZddЄ Zddd҄ZdddԄZdddքZddd؄Zddڄ Zdd܄ Zddބ Zdqdqg dg fddZdddZdd Zdd Zdd Zdd Zdd ZȐdddZdd Zdd Zdd Z̐dddZdd Zdd ZdeCfddZdd Zdd  ZҐdd ZӐdd ZԐdddZՐdd Z֐d	d
 Zאdd ZؐdddZِdd Zڐdd Zdaܐdd Zi aސdd ZߐdddZdadd ZdadddZdd Zdad d! Zd"d# Zd$d% Zd&Zde Zd'Zd(Zd)d* Zi ad+d, Zd-d. Zd/d0 Zdd1d2Zdadadd3d4Zdd5d6Zdd7d8Zd9d: Zd;d< Zdadadadad=d> Zdd?d@Z ddAdBZddCdDZi adEdF ZdGZdHdI ZdJdK ZdLdM ZdNZ	dOdP Z
dQdR ZdSdT ZdUdV ZdWdX ZdadYdZ Zd[d\ Zd]d^ Zd_d` Zdadb Zdcdd Zdedf ZdgZdhdi Zdjdk Zdldm ZddndoZdpdq ZddsdtZdudv ZddwdxZdydz Z dS (      )print_function)absolute_import)division)unicode_literalsN)standard_library)*)read_file_securewrite_file_secureset_user_permopen_file_not_symlinkset_root_perm)create_dir_secureclosefdset_owner_dir_secureset_perm_dir_secure)	root_flagprint_error
get_groupsclpwdSILENT_FLAGloggingget_perm)byteify
unicodeify)ClPwd	clcaptain)sigterm_check)ExternalProgramFailedis_socket_filemod_makedirs)get_boolean_paramCL_CONFIG_FILEc               @   s   e Zd Zdd ZdS )CageFSExceptionc             O   s   t j| f|| d S )N)	Exception__init__)selfargskwargs r(   /usr/share/cagefs/cagefslib.pyr$   8   s    zCageFSException.__init__N)__name__
__module____qualname__r$   r(   r(   r(   r)   r"   7   s   r"   z.etc.version/z/etc/cagefs/cagefs.iniz/etc/cl.selector/php.confz/usr/share/cagefsz/usr/share/cagefs/etc.newz/var/run/cagefsFz!/var/log/cagefs-php-opt-check.logz/etc/psa/psa.confz/var/www/vhostsz/run/systemd/journal/dev-logz"/usr/share/cagefs-skeleton/dev/logz/dev/logz/etc/sysconfig/syslogz -a z/etc/rsyslog.confz(/etc/rsyslog.d/cagefs-syslog-socket.confz/etc/rsyslog.d/schroot.confc             C   s8   yt | d W n" tk
r2   t| d  Y nX dS )z
    /bin/touch analog - update timestamp of a file if it exists
    or create a file otherwise
    :param fname: file path
    :type fname: string
    Na)osutimeOSErroropenclose)Zfnamer(   r(   r)   touch_   s    r4   )returnc              C   s   dd } t t}xt|D ]|\}}|| dr|| tdkr|| d dksb|| d dkr|| || td}|||< n| || td}|||< P qW tt|dd	 td
 dS )z_
    Add syslog socket into CageFS, add it to syslog config and restart
    syslog service
    c             S   s   | d| | | |d  S )z5
        Inserts new inside original at pos.
        Nr(   )originalnewposr(   r(   r)   _insertq   s    z2_add_syslog_socket_for_syslog_pkg.<locals>._insertSYSLOGD_OPTIONS"'T)make_backupz)/sbin/service syslog restart &> /dev/nullN)	read_fileSYSCONFIG_SYSLOG	enumerate
startswithfindCAGEFS_SOCKET
write_fileExecuteSimple)r9   linesi_tmpr(   r(   r)   !_add_syslog_socket_for_syslog_pkgl   s     
rL   c           	   C   s   dt  d} tt}x@t|D ]4\}}|| d}|dkr|| |d ||< P qW tjtrt	td}|
 }W dQ R X || krtt tt|dd tt| gdd td	 dS )
za
    Add syslog socket into CageFS, add it to rsyslog config and restart
    rsyslog service
    z$AddUnixListenSocket 
z$ModLoad imuxsock)r;   r   NrT)r?   z*/sbin/service rsyslog restart &> /dev/null)
LOG_SOCKETr@   RSYSLOG_CONFrB   rD   r/   pathisfileCHROOT_OLD_CONFr2   readunlinkrF   CHROOT_CONFrG   )Zchroot_conf_contentrH   rI   rJ   r8   fZold_contentr(   r(   r)   "_add_syslog_socket_for_rsyslog_pkg   s*    
rX   c               C   sF   t  rt rBt  td n&tjtr0t  ntjt	rBt
  dS )z
    Add cagefs skeleton syslog socket to syslog config file.
    Create .conf file for rsyslog
    Restart syslog/rsyslog service
    z/usr/share/cagefs/need.remountN)is_new_syslog_socket_usedis_old_syslog_socket_in_cageremove_syslog_socketr4   r/   rQ   rR   rA   rL   rP   rX   r(   r(   r(   r)   add_syslog_socket   s    
r\   c           
   C   s   t jtrhtt} x<t| D ]0\}}| | dr| | td}|| |< P qW t	t| dd t
d t jtryt t W n4 tk
r } ztdtdt| W dd}~X Y nX t
d	 dS )
zl
    Remove syslog socket info for cagefs from system syslog configs
    Restart syslog/rsyslog service
    r:    T)r?   z)/sbin/service syslog restart &> /dev/nullZremoving:Nz*/sbin/service rsyslog restart &> /dev/null)r/   rQ   rR   rA   r@   rB   rC   replacerE   rF   rG   rV   rU   r1   r   str)rH   rI   rJ   rK   er(   r(   r)   r[      s$    $r[   c               C   s$   t jto"t jttko"ttS )z
    File `/dev/log` is symlink to socket `/run/systemd/journal/dev-log` if
    server uses the newer version of syslog socket
    )r/   rQ   islinkDEV_LOG_SOCKETrealpathSYSTEMD_JOURNAL_SOCKETr   r(   r(   r(   r)   rY      s    rY   c               C   s   t tS )zB
    Return True if CageFS has into self an old syslog socket
    )r   rO   r(   r(   r(   r)   rZ      s    rZ   c             C   s   yt | }W n tk
r$   d}Y nX yt |}W n tk
rJ   d}Y nX |dks\|dkrv|dkrl| |kS | |k S n|dkr||kS ||k S d S )Nr;   r   )int
ValueError)Ztxt1Ztxt2opZi1Zi2r(   r(   r)   getItem   s    


ri   c             C   s   |  d} | d}t| t|kr.t|}nt| }x@t|D ]4}t| | || dr\dS t| | || dr@dS q@W t| t|krdS t| t|krdS dS d S )N.r      r;   )splitlenrangeri   )baseZtestZlnrI   r(   r(   r)   
verCompare	  s    


rp   c             C   s(   yt |  W n tk
r"   Y nX d S )N)r/   rU   r1   )rQ   r(   r(   r)   rU     s    rU   c       
   
   C   sH  t }t st \}}t  ytd krBtd}ttddat| tt	j	
 dd |  d  |rtd x|D ]}td| d  qxW |rtd	 x|D ]}td| d  qW |rtd
 x|D ]}td| d  qW W nB ttfk
r2 }	 ztdtt|	 td W d d }	~	X Y nX |sDt|| d S )N?   r.   rk   z%Y.%m.%d %H:%M:%Sz: rM   z8 - The following options have been disabled as unknown:
z     * zF - The following options have been disabled as have incorrect values:
zI - The following options have been disabled as invalid (have no values):
zwriting to )r   r   r   php_log_optr/   umaskr2   PHP_OPTIONS_LOGFILEwritedatetimeZnowZstrftimer1   IOErrorr   r`   sysexitr
   )
msgZunknown_options_listZinvalid_values_options_listZinvalid_options_listZroot_flag_saveduidgidumask_savedoptionra   r(   r(   r)   php_options_log_write$  s6    


"





r   c             C   s   t  \}}}t|j}t|}|sXd||f }|dd}t| | t|t jd nvydd l}W n t	k
r   t
 }	Y n
X | }	t|||d |	 x0|	 dD ]}
t| |
 t|
t jd qW d S )Nz%s: %sErrnozErr code)filer   rM   )rx   exc_infor`   	__class__r_   syslogprintstderrStringIOImportErrorio	tracebackprint_exceptiongetvaluerl   )levelZincludetracebackexctypeZ	exceptionZexctracebackZexcclassmessagerz   r   Zexcfdliner(   r(   r)   r   D  s"    
r   c           	   C   sb   y"t td} |  }W d Q R X W n tk
r6   d S X td|tj}|sPd S | d dS )NZrtz^HTTPD_VHOSTS_D[ \t]+(\S+)$r   r-   )	r2   GLOBAL_PLESK_CFGrT   r#   research	MULTILINEgroupsrstrip)rW   datamatchr(   r(   r)   _read_vhosts_dir]  s    r   c             C   s8   t | }t|}x"tD ]}t|}||rdS qW dS )NTF)
strip_pathaddslash
black_listrC   )_fileZrfilerQ   r(   r(   r)   is_in_black_listp  s    

r   c               C   s   t  jjS )z*Returns the current line number in program)inspectZcurrentframef_backf_linenor(   r(   r(   r)   linenoz  s    r   c             C   s$   | dkr | d dkr | d d S | S )Nr]   r;   r-   r(   )_dirr(   r(   r)   
stripslash  s    r   c             C   s&   | dkrdS | d dkr"d| f S | S )Nr]   r-   r;   z%s/r(   )r   r(   r(   r)   r     s
    
r   r]   c             C   sX   t   td}ttd}x| D ]}|d|  q W |  t| ttd d S )N   wz%s
i  )r   r/   rs   r2   FUSE_SAFE_LISTru   r3   chmod)Z	safe_listr}   r   filenamer(   r(   r)   save_etc_safe_list  s    



r   c             C   s,   t }t|}| d | |kr(| |d  } | S )N)SKELETONrm   )rQ   ZjailZjaillenr(   r(   r)   r     s
    r   c             C   s   xt | D ]r}t j| |}|}|d kr:|t|d  }|d krJ|| }d||< t j|r|snt j|st||||d qW d S )Nrk   )cut_pathadd_path)r/   listdirrQ   joinrm   isdirrb   add_tree_to_list)src_listfollow_symlinksr   r   namesrcnamerQ   r(   r(   r)   r     s    r   c             C   s&   t jt jt j| t j| S )N)r/   rQ   r   rd   dirnamebasename)rQ   r(   r(   r)   get_real_path  s    r   c             C   sv   |  drrt| ddrd S |  ds.|  dr2d S | dkrrtj| rrtj| rbt| t|   nt| t|  d d S )Nz/etc/T)etcz/etc/cl.php.d/z/etc/cl.selector/)z/etc/passwdz
/etc/groupz/etc/shadowz/etc/cl.php.dz/etc/cl.selector)	rC   move_to_alternativesr/   rQ   existsrR   	copy_fileETC_TEMPLATE_NEW_DIRcopytree)rQ   r(   r(   r)   copy2etc  s    
r   c             C   s^   t | } t| } t|  | drZ| tkrVtj| rVdt| < tj| rVt	| td dS dS )Nz/etc/rk   TF)
r   r   r   rC   
white_listr/   rQ   r   r   r   )rQ   r(   r(   r)   add_to_white_list  s    
r   c             C   s   x~| D ]v}t |}t|}t| t|}||kr:t| tj|}||kr^||kr^t| tj|rt|}t| qW d S )N)	r   r   r   r   r/   rQ   rd   rb   readlink)pathsrQ   path2Zpath3linktor(   r(   r)   copy_to_etc  s    

r   c             C   s
   | | S )N)rC   )rQ   mountr(   r(   r)   $path_includes_mount_point_comparator  s    r   c             C   s
   |  |S )N)rC   )rQ   r   r(   r(   r)   path_is_mounted_comparator	  s    r   c             C   s   t | |pt| |S )N)r   r   )rQ   r   r(   r(   r)   mounts_are_found_comparator  s    r   c             C   sl   t | } t| } | ds$| dr(dS x>tD ]6}|dkr.|d dkr.| }t|}|| |r.dS q.W dS )Nz/etc/z	/var/log/Tr]   r   r-   F)r   r   rC   mountsr   )rQ   Z
comparatorr   r(   r(   r)   mounts_are_found  s    

r   c             C   s
   t | tS )N)r   r   )rQ   r(   r(   r)   path_is_mounted#  s    r   c             C   s
   t | tS )N)r   r   )rQ   r(   r(   r)   path_includes_mount_point)  s    r   c             C   s   |t | < d S )N)	libs_list)binarylibsr(   r(   r)   add_libs_to_list4  s    r   c             C   s"   yt |  S  tk
r   d S X d S )N)r   KeyError)r   r(   r(   r)   get_libs_from_list9  s    r   c             C   s$   y
t | = W n tk
r   Y nX d S )N)r   r   )r   r(   r(   r)   del_libs_from_list@  s    
r   c          
   C   s   t   yJtd}t| d}tjtt|dd |  t| t	| d W n0 t
k
r } ztd| d| W d d }~X Y nX d S )Nrq   wb   )Zprotocoli  zwhile saving-)r   r/   rs   r2   pickledumpr   r   r3   r   r#   r   )r   r}   r   errr(   r(   r)   	save_libsH  s    


r   c          
   C   sn   t j| rjy,t| d}ttj|t da	|
  W n0 tk
rh } ztd| d| W d d }~X Y nX d S )Nrb)encodingZloadingr   )r/   rQ   rR   r2   r   r   loadlocaleZgetpreferredencodingr   r3   r#   r   )r   r   r   r(   r(   r)   	load_libsV  s    
r   c             C   s    t | } t| } t| } | tkS )N)r   r   r   
files_list)rQ   r(   r(   r)   path_is_in_listf  s    r   c             C   s@   t rt| rd S t| } tj| r<t| s<td|d| d d S )NzError in linez: zis not in list)debug_optionr   r   r/   rQ   lexistsr   r   )rQ   Zlinenumr(   r(   r)   check_erroro  s    r   Tc             C   s   t | } tr0t| }| |kr0tdt d| d| tj| r~t| } | t	krdt	| < |rtj
| rtj| st| t	d ntrtdt d|  d S )NzError in linez: z!=rk   Fr   zpath does not exist:)r   r   r   r   r   r/   rQ   r   r   r   r   rb   r   )rQ   add_treeZrpathr(   r(   r)   add_to_list{  s    r   c             C   sF   |st | S yt|  }W n& tk
r@   t |  t| < }Y nX |S )N)r/   lstat
stat_cacher   )rQ   	use_cacheresr(   r(   r)   cached_lstat  s    
r   c             C   s$   y
t | = W n tk
r   Y nX d S )N)r   r   )rQ   r(   r(   r)   clear_stat_cache  s    
r   c             C   s   |d krt | |d}|d kr(t ||d}t|tj t|tj krLdS t|tj rxt| t|krtdS dS |tj }|tj }|tj @ tj @ }|tj @ tj @ }||krdS |tj |tj ks|tj	 |tj	 ks|tj
 |tj
 ks|tj |tj krdS dS )N)r   FT)r   statS_ISLNKST_MODEr/   r   S_ISUIDS_ISGIDST_MTIMEST_SIZEST_UIDST_GID)ZfileAZfileBsbAsbBr   ZmodeAZmodeBr(   r(   r)   is_same_metadata  s(     

,,r   c          
   C   sB   yt | ||||d S  tk
r< } z
|jdkS d}~X Y nX dS )z
    Returns: True if update of "injail" file is needed
             False if update is NOT needed (file in jail has same metadata)
    )r   r   r   r   N)r   r1   errno)r6   ZinjailZorigstatbufZinjailstatbufr   ra   r(   r(   r)   is_update_needed  s    r   c       	   	      s  ddl }g }y,t| d}|d|dd }|  W n
   |S |dkrP|S d}dg}tj|| gd	tjtjtjd
d
d}x|j	 D ]|  
 }|rt fdd|D rq|d dkr|d dkr|S |d dkr|d dkr|d dkr|S |d dks|d dkr nt|dkrL|d dkrL|d dkrLnt|dkrtj|d r|||d g7 }ntd|d d|  ndt|dkr|d d dkrtj|d r||d g7 }ntd|d  ntd dd  qtd dd  qW |S )z6
    Returns list of libraries for the executable
    r   Nr   z<I   iELFz/usr/bin/lddz no version information availableFT)shellstdinstdoutr   Z	close_fdstextc             3   s   | ]}| kV  qd S )Nr(   ).0r   )r   r(   r)   	<genexpr>  s    zget_ldd_libs.<locals>.<genexpr>Z
staticallyrk   Zlinkednotr   Zdynamic   
executablezlinux-gate.so.1zlinux-vdso.so.1foundz ldd returns non existing libraryforr-   zfailed to parse ldd outputr;   )structr2   unpackrT   r3   
subprocessPopenPIPEr  	readlinesrl   anyrm   r/   rQ   r   r   )	r  r
  retvalrW   Z	signatureZldd_pathZskip_err_patternspsplittedr(   )r   r)   get_ldd_libs  sV    
 r  c             C   s   | dkrdS t | }d}|s0|d }|d d }d}d}x|D ]}tj||}t|}t|jr>|d7 }t|}	|	d dkrtj	||	 }q>tj	tjtj
||	}
t|dkr|
d t| |krtd|
d td|
}q>W tj||S )	Nr-   r]   r;   r   rk   zsymlink z points outside jail, ABORTzSymlink points outside jail)
split_pathr/   rQ   r   r   r   r   st_moder   normpathr   rm   r   r#   )rQ   chrootZinclude_filespathr   retZ
doscounterentrysbrd   rK   r(   r(   r)   resolve_realpath  s.    

 r  c             C   s   t | }t|tj }|sR|tjtjB @ rRtd| t| |tj @ tj @ }t ||tj	 |tj
 f |rt ||tj |tj  t || d S )Nz,removing setuid and setgid permissions from )r/   r   S_IMODEr   r   r   r   r   r0   ST_ATIMEr   chownr   r   r   )r   dst
be_verbose
allow_suidcopy_ownershipsbufmoder(   r(   r)   copy_time_and_permissions8  s    
r'  c             C   s.   |  d}g }x|D ]}|r|| qW |S )Nr-   )rl   append)rQ   r  r   itemr(   r(   r)   r  H  s    

r  c             C   s2   t | dkrdS d}x| D ]}|d| 7 }qW |S )Nr   r-   r]   )rm   )r  r  r  r(   r(   r)   	join_pathQ  s    
r*  c             C   s   | d t | d t | S )NrJ   )r`   )rQ   copy_permissionsr$  r(   r(   r)   gen_path_keyZ  s    r,  rk   c          
   C   s,  t   t|r| | S t|||}|tkr2t| S t|}| }d}	x|	t|k r:t   t|d|	d  }
t|
||}|tkr(tj	|||	 }tj
|sP t|| d}tj
|sP |}|rt|syt|
|||| W n8 tk
r } ztd|
d|d|j W d d }~X Y nX |t|< nt| }|	d7 }	qDW x|	t|k rt   t|d|	d  }
tj	|||	 }yt|
}W n8 tk
r } ztd|
 d |j d S d }~X Y nX t|jry,t|}t|jst| t| W n tk
r   Y nX td| t| yt|d	 t|d
 W n> tk
rz } ztd| d |j t| W d d }~X Y nX |ryt|
|||| W n8 tk
r } ztd|
d|d|j W d d }~X Y nX n0t|jrt|
}td| d | t| yt|| W n. tk
rB   td| d | td Y nX t|d
 |d dkr|t| |||||}t|t   ntj!tj	tj"||}t| dkr|d t|  | krtd| d  t#d|t| d  }t| |||||}t|t   |}|	d7 }	q@W t|d
 |t|< |S )Nr   rk   z*failed to copy time/permissions/owner fromtor^   zfailed to lstat(z):zCreate directory i  Fz$Warning: failed to create directory z -- zCreating symlink z to zFailed to create symlink r-   zsymlink z points outside jail, ABORTzSymlink points outside jail)$r   r   r,  handled_dirr  rm   r*  r/   rQ   r   r   r  r   r'  r1   r   strerrorr   r   S_ISDIRr  r   rU   r   r   mkdirr   r   r   symlinkcreate_parent_pathr   r   r  r   r#   )r  rQ   r"  r+  r#  r$  keyr  Z	existpathrI   ZorigpathZorigkeyZtmp1rK   ra   Zjailpathr  injailsbrealfiler(   r(   r)   r3  ]  s    
&
,*

$
r3  c          
   C   s   t |rdS y*t|}t|jr4t| t| W n tt	tj
fk
rR   Y nX d}|dkryt| | d}t| W n$   td|  d | d  Y nX |dkry.t| | t|dd t| ||d|d	 W n@ tt	tj
fk
r } ztd
| d|d|j W dd}~X Y nX dS )zKcopies/links the file and the permissions, except any setuid or setgid bitsNrk   r   zLinking z to z failed, will revert to copyingF)r   )r#  r$  z$ERROR: copying file and permissions z: )r   r   r   r0  r  r   shutilrmtreerw   r1   Errorr/   linkr   r   copyfiler'  r/  )r   r!  r"  try_hardlinkretain_ownerr5  Zdo_normal_copyra   r(   r(   r)   copy_with_permissions  s2    
r>  c       
   
   C   s  t |rd S yt|}W n( tk
rB   td| d t| d S X t| tj||dddd t	| | | }t
|jrd}nt
|jrd}nt
|jrfy>t|}td| d	 | t| t|d
d t|| W n. tk
r   td| d	 | td Y nX |d dkr:tjtjtj||}|dsbtj|rbt| ||| d S d S |jd }|jd }	yptj|std|  | t| ttjdd|t|t|t|	 ntd| d t| t||d|d W n& tk
r   td| td Y nX d S )NzDevice z does NOT exist in real systemrk   r   )r+  r#  r$  cbzCreating symlink z to T)check_mountszFailed to create symlink r-   z/proc/   zCreating device mknodz does exist already)r#  r$  zFailed to create device )r   r/   r   r1   r   r   r3  rQ   r   r  r   S_ISCHRr  S_ISBLKr   r   remove_file_or_dirr2  r  r   rC   r   copy_devicest_rdevr   spawnlpP_WAITr`   r'  )
r  rQ   r"  r=  r  Z
chrootpathr&  r6  majorminorr(   r(   r)   rG    sJ    


&rG  c	             C   s  t   t|r|S d}	xt|D ]}
t   tj||
}yht|}t|j	rt
| ||dd|d}t|t  t| ||||||||d	}n|	tj||
f7 }	W q" tk
r } ztd|d|j W dd}~X Y q"X q"W t| |	|||||||d	}trx|	D ]}t|t  q W |S )	zRcopies a directory and the permissions recursive, except any setuid or setgid bitsr(   rk   r   )r"  r+  r#  r$  )updatez!failed to investigate source filer^   N)r   r   r/   r   rQ   r   r   r   r0  r  r3  r   r   copy_dir_recursiver1   r   r/  copy_binaries_and_libsr   )r  r   force_overwriter"  
check_libsr<  r=  handledfilesrM  Zfiles2r  rK   r%  epathra   r)  r(   r(   r)   rN    s*    &
rN  c             C   s2   |  ddkp0|  ddkp0|tjtjB tjB @ S )Nz/libr;   z.so)rD   r   S_IXUSRS_IXGRPS_IXOTH)r   r&  r(   r(   r)   libs_check_is_needed*  s    rW  c          
   C   s   t   y|r^y4d| }t| | t|tt| j	 W n t
ttjfk
r\   Y nX t| d"}|srdnd}||| W dQ R X W n2 tt
fk
r   td|  td td Y nX dS )z
    Helper for write lines to file
    :param: filename `str` filename for write
    :param: lines `list` list with content lines
    :param: add_eol `bool` if True than add 
 to end each line
    z{}.bakr   r]   rM   NzError: failed to write rk   )r   formatr7  r;  r/   r   r   r  r   r  rw   r1   r9  r2   ru   r   r   r   rx   ry   )r   rH   add_eolr?   Zbackup_namerW   Zsplitterr(   r(   r)   rF   /  s    
rF   c          	   C   s\   yt | d}| }|  |S  ttfk
rV   td|  td |sH td Y nX dS )z
    Helper for read file, process errors and make backup before read
    :param: filename `str` name of file for read
    :param: exit_on_error `bool` use sys.exit on error or raise exception
    rN   zError: failed to read rk   N)	r2   r  r3   r1   rw   r   r   rx   ry   )r   exit_on_errorr   contentr(   r(   r)   r@   H  s    
r@   c             C   s   | dkS )N)
0123456789r(   )nr(   r(   r)   isdigitZ  s    rg  c             C   s&   | sdS x| D ]}t |sdS qW dS )NFT)rg  )scharr(   r(   r)   isdigits_  s    
rj  c             C   sn   t |}| |}|dkrj| || d  }d}x&|t |k rTt|| sJP |d7 }q0W |d | }t|S dS )Nr;   r   rk   )rm   rD   rg  rf   )r   signlengthr8   endpos2verr(   r(   r)   get_versioni  s    
rp  c          	   C   s   | d d  }x,t t|D ]}|| d|}|||< qW tj|ryt| W n2 ttfk
r   t	d| t
d td Y nX td}t|| t| d S )NZALIASzError: failed to delete rk   r   )rn   rm   r_   r/   rQ   rR   rU   r1   rw   r   r   rx   ry   rs   rF   )ZprogramaliascommandZscriptrI   rK   r}   r(   r(   r)   update_wrapperz  s    

rs  c             C   s   t j| sdS d}yltj|dd|| gtjtjdd}| \}}|jdkrptd| d | d	 |  t	d
 dS |jdkr~dS W n4 t
k
r   td| d | d	 |  t	d
 dS X |d krt||}||krdS dS )NTz	/bin/grepz-mr]  )r  r   r  r   zError while executing z -m 1  rk   r   zError: failed to run F)r/   rQ   rR   r  r  r  communicate
returncoder   r   r1   rp  )rr  versionrk  ZGREPr  outrJ   ro  r(   r(   r)   wrapper_not_installed  s(    
 
 
ry  z/usr/share/cagefs/safeprograms/z #CageFS proxyexec wrapper - ver c             C   s&   x | D ]}t |t}|dkrP qW |S )Nr   )rp  	SIGNATURE)proxyr   rw  r(   r(   r)   get_proxy_version  s
    

r|  c          	   C   s   t | } tj| sd S ttt|   }t|}tt	|  |t
rTt|t|  t	|   yt| t	|  dddd W n6 ttfk
r   tdt	 |  td td Y nX d S )Nr   rk   )r"  r#  r$  z*Error: failed to set permissions/owner to )r   r/   rQ   rR   r@   
PROXY_PATHwrappers_namesr|  ry  r   rz  rs  wrappersr'  r1   rw   r   r   rx   ry   )r   r{  Z	proxy_verr(   r(   r)   install_wrapper  s    r  c             C   s2   t   t| } | tkr.t| dd t|  dS dS )NF)r   T)r   r   r  r   r  )r   r(   r(   r)   update_proxy_wrapper  s    r  c          	   C   sf   yt |  W n ttfk
r&   Y nX t j| rb|r@t| sNt| d nt	d|  d t
d d S )NTz"Error: failed to remove directory z because it includes mount pointsrk   )r/   rU   r1   rw   rQ   r   r   r7  r8  r   r   )rQ   rA  r(   r(   r)   rF    s    rF  z/usr/bin/php-cgiz/usr/bin/phpz/etc/php.iniz/usr/local/bin/lsphpz/usr/local/sbin/php-fpm)phpzphp-clizphp.inilsphpzphp-fpmz/usr/selectorz/usr/selector.etczcl.selectorz/etc/znative.confc               C   s   t dkrtjda t S )zI
    Return True if cPanel EasyApache4 (MultiPHP feature) is enabled
    Nz/etc/cpanel/ea4/is_ea4)is_ea4_enabled_cacher/   rQ   r   r(   r(   r(   r)   is_ea4_enabled  s    r  c             C   s   t  r
dS | dkS )z
    Returns True if php file for appropriate alias is mandatory
    for proper work of PHP Selector (i.e the file should exist
    and should be replaced with symlink successfully)
    :param alias: alias for php file
    :type alias: string
    F)r  zphp-clizphp.ini)r  )rq  r(   r(   r)   is_mandatory$  s    r  c              C   s   t stjtrttd} x^| D ]V}|ds | }|dd}t	|dkr |d  }|d  }|t
kr |t
|< q W |   da d S )NrN   #=rk   r   r   T)config_loadedr/   rQ   rR   NATIVE_CONFr2   rC   striprl   rm   orig_binariesr3   )rW   r   arrq  rQ   r(   r(   r)   read_native_conf4  s    


r  c              C   s6   t   x*t D ]} tj| }|drdS qW dS )Nz/etc/TF)r  r  valuesr/   rQ   rd   rC   )rQ   r   r(   r(   r)   is_etc_in_native_confF  s    
r  c             C   s    | dkrt d |  S td |  S )Nzphp.inir-   )ALT_DEST_ETC_PATHALT_DEST_PATH)rq  r(   r(   r)   get_usr_selector_pathP  s    r  c             C   s(   | dkr$|  ds$tdd| gdd d S )Nr]   z.iniz/usr/bin/killallz-qF)check_return_code)endswithExecute)	file_namer(   r(   r)   kill_phpV  s    r  c          
   C   s   | dkrt t }nt t }tj|| }tj|sy<tj|sLt|d t	d}t
|d  t	| W n8 ttfk
r } ztd|dt| dS d}~X Y nX d	S )
zW
    Create stub (empty file) for php file.
    Return True when error has occured
    zphp.inii  r   r   zFailed to write:r^   TNF)r   r  r  r/   rQ   r   r   r   r   rs   r2   r3   r1   rw   r   r`   )rq  Zselector_dirZ	stub_pathr}   ra   r(   r(   r)   create_php_stub[  s    


r  c             C   sF  t   |r| dsdS | }nt| }t  xtD ]}t   tjt| }||kr4tj|r4tj	|s4|dkrt
 rt| dS |}t|}td | }t| }tj|}	|rt| }
nt| }
x^|	tj|
fD ]J}tj|syt|d W q ttfk
r&   td| td dS X qW t||ddrt||dd	rtj|}t| t||dd	rtd
| d | td dS yNtj	|
rt|
|krt|
 t||
 nt|
 t||
 W nL ttfk
r& } z(td|
 d t| dd td dS d}~X Y nX |s:t!|
dd dS q4W dS )aN  
    Move php file to /usr/selector* directory inside cagefs-skeleton and create symlink to it
    Return True if php binary has been moved successfully, False otherwise
    :param path: path to original php file
    :type path: string
    :param etc: True = /etc directory is being processed, False otherwise
    :type etc: bool
    z/etc/F)r  zphp-clir  zphp.inir-   i  zError: failed to create rk   )r   )create_parent_dirzError copying z to z!Error : failed to create symlink z : r   zErr codeN)r   T)"r   rC   r   r  r  r/   rQ   rd   rR   rb   r  r  r  ETC_CL_ALT_PATHr   r   r   r   r   rw   r1   r   r   r   r   r   r  r   rU   r2  rF  r`   r_   r   )rQ   r   r  rq  	orig_pathr   Z	DEST_PATHZLINK_TOZ	dest_filedest_dirZ	orig_fileparent_pathr  ra   r(   r(   r)   r   r  sf    	
 


$r   c             C   s>   | dkrdS t | } | ddddddd	d
ddddddddthkS )Nr-   Tz/binz/bootz/devz/etcz/libz/lost+foundz/mntz/procz/rootz/sbinz/sysz/tmpz/usrz/varz/homez/var/www/vhosts)r   PLESK_VHOSTS_D)rQ   r(   r(   r)   is_path_in_exclusions  s*    r  z(/var/www/cgi-bin/cgi_wrapper/cgi_wrapperc             C   sB   t d|  d | td t| | |r4t|| n
t| | d S )NzCopying z to rk   )r   r   r7  r;  r'  )ABCr(   r(   r)   __copy_wrapper  s
    r  c           
   C   s   t   yt rd} d}ttd tfdtt tf|t|  tf|| tff}tjtt }tj|snt	|d x|D ]\}}}t
||| qtW W n6 ttfk
r } ztdt|  W d d }~X Y nX d S )Nz//var/www/cgi-bin/cgi_wrapper/cloudlinux_wrapperz9/usr/share/cagefs-plugins/plesk-cagefs/cloudlinux_wrapperz4/var/www/cgi-bin/cgi_wrapper/cgi_wrapper.orig.cagefsz2/usr/share/cagefs-plugins/plesk-cagefs/cgi_wrapperi  z!failed to install Plesk wrapper: )r   cldetectlibZis_pleskPLESK_ORIG_WRAPPER_FILENAMEr   r/   rQ   r   r   r   r  r1   rw   r   r`   )ZCLOUDLINUX_WRAPPERZCLOUDLINUX_WRAPPER_PACKAGEZWRAPPERSdirpathr   r!  permra   r(   r(   r)   install_plesk_wrapper  s     
r  c
             C   s	  t   | d dkr| dd } x|D ]}
t   |
|kr<q&t|
rhtj|
s\tj|
r&||
 q&t|
rtj|
stj|
r&||
 q&yt|
}W n t	k
rp } z|j
dkrN|dkr8t|
}t|dkr"t| ||||||d||	d
}tr6x0|D ]}t|t  q
W ntd|
 d	 t| ntd|
 d	 t| ntd
|
d|j w&W dd}~X Y nX t| tj|
|dd|d yttj| d |
 | }W n t	k
r   w&Y nX t|rtj|
stj|
r&||
 q&t|r||
 q&|
tkr(t  ||
 q&t|r^t|
}t| |||d|||	d}||
 q&t|rtj|
stj|
r&||
 q&yt|}d}t| W nH t	k
r } z(|j
dkrd}ntd| |
d|j W dd}~X Y nX |dkr:|	dkr:|r:t !|j"s:td| d t| t|t  q&|r|rt #|j"sbt $|j"rtd| d t| yt%| W n4 t	k
r } ztd|d|j W dd}~X Y nX n"t !|j"rtd| d t| n0|	rt #|j"st $|j"rt&|
|||rptd| d t| yt%| W n4 t	k
rj } ztd|d|j W dd}~X Y nX qtd| d t| t|dd t|t  ||
 t $|j"rJyt'|
}W n t	t(fk
r   d}Y nX |dkrJt)|sJ|d dkr"tjtj*tj|
|}t| |g|||||||	d	}t|t  t +|t j, }|r&t-|
|r&t.|
}|dkrt|
}t/|
| t| |||d|||	d}tr&x|D ]}t|t  qW q&n"t !|j"rtd| d t| n&t !|j"rntd| d t| q&t| tj|
|dd|d t $|j"rtyvt'|
}tj|rrt'||kr~t%| nt0|dd tj|std| d | td t1|| W nH t	k
r } z(td | d | d! t2| td W dd}~X Y nX t|dd ||
 t)|s|d dkrHtjtj*tj|
|}t| |g|||||||	d	}t|t  nt !|j"rt| |
|dd|d}t3|}tr||krtd"t d#|d$| t4| |
|||||||	d	}t|t  nt #|j"rZ|rtd%|
 d | td ntd&|
 d | td t5|
||||d' ||
 t|t  n*t 6|j"svt 7|j"rt8| |
|| t +|t j, }|r&t-|
|r&t $|j"st #|j"r&t|
}t/|
| t| |||d|||	d}tr&x|D ]}t|t  qW q&W |S )(z>copies a list of executables and their libraries to the chrootr;   r-   Nr   rk   r   )r<  r=  try_glob_matchingrR  rM  zSource file(s) z do not existz!failed to investigate source filer^   )r+  r#  r$  )rQ  r<  rR  rM  z'failed to investigate destination file r]   z" already exists, will not touch itzDestination file z$ exists, will delete to force updatezERROR: failed to deletezDestination dir z existsz needs updatezfailed to deletez does NOT need updateF)r   )rQ  r<  r=  rR  rM  T)rA  zCreating symlink z to z!Error : failed to create symlink z : r   z: z!=zTrying to link zCopying )r<  r=  )9r   r   r/   rQ   rR   rb   r(  r   r   r1   r   globrm   rO  r   r   r   r   r   r   r/  r3  r   r  r  r  r  r  r   r  r   r   r   r0  r  S_ISREGr   rU   r   r   rw   r  r   r  r   rW  r   r   rF  r2  r`   r   rN  r>  rD  rE  rG  )r  ZbinarieslistrP  r"  rQ  r<  r=  r  rR  rM  r   r  ra   r  r)  ZchrootrfileZphp_libsZchrootsbZchrootfile_existsr6  r&  r   rS  r(   r(   r)   rO    s^   















$($&







6









rO  c             C   sN   g }|  ||rJ| ||}x,|dD ]}| }|dkr(||g7 }q(W |S )zretrieves a comma separated option from the configparser and splits it into a list, returning an empty list if it does not exist,r]   )
has_optiongetrl   r  )Z	cfgparserZsectionnameZ
optionnamer  ZinputstrrK   r)  r(   r(   r)   config_get_option_as_list  s    r  c             C   s  | d dkr| d d } t j| s\yt| d W n( tk
rZ   td|  td Y nX t | d g }|	| g }|	| tj
dd dkrt| d	 d
  t| d d
  t| d d
  t| d d
  nt j| d	 st| d	 d}nt| d	 d}| }xt|dkr|d}t|dkr|d |ks^|d |krtd|d  d |  d	 t| y||d  W n tk
r   Y nX y||d  W n tk
r   Y nX | }qW |dd t|dkrtdd}	|	 }xt|dkr|d}t|dkr|d |ksP|d |kr|| td|d  d |  d	 t| |d |kr||d g7 }|	 }qW |	  |  td| d	 dddd t j| d st| d d}nt| d d}| }xt|dkr|d}
t|
dkr|
d |ksF|
d |krtd|
d  d |  d t| y||
d  W n tk
r   Y nX y||
d  W n tk
r   Y nX | }qW |dd t|dkrxtdd}	|	 }xzt|dkrn|d}
t|
dkrb|
d |ks8|
d |krb|| td|
d  d |  d t| |	 }qW |	  |  td| d dddd d S )Nr;   r-   i  creatingrk   r      Zbsdz/passwdr.   z/spwd.dbz/pwd.dbz/master.passwdr   zr+r   r^   r  r   zuser z exists in z/etc/passwdrN   zwriting user z to )r"  r#  r$  z/groupzgroup z
/etc/groupzwriting group )r/   rQ   r   r   r1   r   rx   ry   r   extendplatformr2   r3   rR   readlinerm   rl   r   r   removerg   seekru   r'  )r  
users_listgroups_listr"  usersr   fd2r   pwstructfdgroupstructr(   r(   r)   init_passwd_and_group  s    



 


 
 


 r  c          	   C   s  | d dkr| d d } t d}t j| sfyt| d W n( tk
rd   td|  td Y nX t 	| d g }|
| g }|
| t j| d st| d d}nt| d d	}| }| }xnt|d
kr:||kr(td| d |  d t| y|| W n tk
r&   Y nX | }| }qW |d
d t|d
krtdd}	|	 }xt|d
kr|d}
t|
dkr|
d
 |ks|
d |kr||
d
 d  td|
d
  d |  d t| |	 }qjW |	  |  yt 	| d d W n. ttfk
r>   td|  d td Y nX t j| d sbt| d d}nt| d d	}| }| }xpt|d
kr||krtd| d |  d t| y|| W n tk
r   Y nX | }| }qW |d
d t|d
krtdd}	|	 }xt|d
kr|d}t|dkr|d
 |ksb|d |kr||d
 d  td|d
  d |  d t| |	 }q W |	  |  yt 	| d d W n. ttfk
r   td|  d td Y nX t | d S )Nr;   r-   r   i  r  rk   z/safe.usersr   zr+r   zuser z exists in r   z/etc/passwdrN   r^   r  rM   zwriting user z to i  z$Error: failed to set permissions to z/safe.groupszgroup z
/etc/groupzwriting group )r/   rs   rQ   r   r   r1   r   rx   ry   r   r  rR   r2   r  r   rm   r   r   r  rg   r  rl   ru   r3   rw   )r  r  r  r"  r}   r  r   r  r   r  r  r  r(   r(   r)   init_safe_users_and_groupsT  s    






 


 r  c             C   s  | d dkr| d d } t j| s\yt| d W n( tk
rZ   td|  td Y nX t | d g }|	| t j
| d st| d d}nt| d d}| }xt|d	kr6|d
}t|dkr,|d	 |kr,td|d	  d |  d t| y||d	  W n tk
r*   Y nX | }qW |d	d t|d	krtdd}| }xlt|d	kr|d
}t|dkr|d	 |kr|| td|d	  d |  d t| | }qfW |  |  td| d d	d	dd d S )Nr;   r-   i  zError while creatingrk   z/shadowr   zr+r   r^   zuser z exists in r   z/etc/shadowrN   zwriting user z to )r"  r#  r$  )r/   rQ   r   r   r1   r   rx   ry   r   r  rR   r2   r  rm   rl   r   r   r  rg   r  ru   r3   r'  )r  r  r"  r  r  r   r  r  r(   r(   r)   init_shadow  sN    


 


 r  c             C   s   t | } tj| d s0td|  d td d S tj| d rXtd|  d td d S tdd}t| d d}| }xht	|d	kr|
d
d}t	|dkr|d	 |kr|| td|d	  d |  d t| P | }qzW |  |  d S )Nz/shadowzError: z/shadow does not existrk   z/shadow is a symlinkz/etc/shadowrN   r.   r   r^   zWriting user z to )r   r/   rQ   rR   r   r   rb   r2   r  rm   rl   ru   r3   )r  userr"  r  destr   r  r(   r(   r)   add_user_to_shadow  s(    

 r  c             C   sx   t | dkst |dkrd S tt | t |}d}x(|| krZ| | || krPP |d8 }q4W |dkrhd S | |d d  S )Nr   r;   rk   )rm   min)s1s2Zmin_lenr8   r(   r(   r)   get_common_end  s    r  c             C   s  t j| } t j|}t| } t|}| dksP|dksP| d dksP|d dkrltd|  d | td dS tt| t|}|d kryt|d W n t	t
fk
r   Y nX dS t|}|d t|  }| d t|  }x|D ]}|d | }|d | }yt|d W n t	t
fk
r(   Y nX yt||dddd W q t	t
fk
r } z&td	| d
 | d |j td dS d }~X Y qX qW dS )Nr]   r   r-   zError: invalid paths src = z dst = rk   i  )r"  r#  r$  z!ERROR: while copying permissions z to z: )r/   rQ   r  r   r   r   r  r  r   rw   r1   r*  rm   r'  r/  )r   r!  commonZ
common_strZdst_pathZsrc_pathr   ra   r(   r(   r)   	copy_path  s<    (
"r  c          	   C   s(   y
t | S  ttfk
r"   d S X d S )N)r/   r   rw   r1   )rQ   r(   r(   r)   oslstat>  s    
r  c             C   s  | |krdS t | }yt |}t|jr4d}	nb||kr@dS yt | W nB ttfk
r }
 z t	d| d t
|
 td dS d }
~
X Y nX d}	W n ttfk
r   d}	Y nX d}|	st| |dkrd}x|D ]}t j| |}t j||}yVt|}t|}|d k}|rt|jr|s8|r8w|rJ||krJwt |}|rt|jrvt|d n
t | t || nt|jrt||||||dkrPd}n|s|rw|r||krw|r|rt||||sw|r2t|jrt | nt|jr2t|d t|| t||dddd W q tttjfk
r } z,t	d| d	 | d
 t
| td d}W d d }~X Y qX qW yt| |dddd W nP ttfk
r } z,t	d|  d	 | d
 t
| td d}W d d }~X Y nX |S )Nr   TzERROR: failed to delete file z : rk   F)r"  r#  r$  zERROR: while copying z to z: z!ERROR: while copying permissions )r/   r   r   r   r0  r  rU   rw   r1   r   r`   r   r  rQ   r   r   r  r   r   r7  r8  r2  r   r   r;  r'  r9  )r   r!  ZsymlinksZ	overwriteZskip_src_dirsrM  Zskip_dst_filesnamesdstbufZ
dst_existsra   errorr   r   dstnamesrcbufdstname_existsr   r   r(   r(   r)   r   H  s    




$$r   c       
   
   C   sb  t   yt| }t|jr"dS t|}|d k}|s`tj|}|dkr`|r`t	tj| | t
|jrt| }|rt|jrt|d n
t| t|| n`|r|rt| |||sdS |rt|jrt|d n
t| t| | t| |dddd W nN tttjfk
r\ }	 z&td|  d | d |	j td dS d }	~	X Y nX dS )	Nrk   r-   Tr   )r"  r#  r$  zERROR: while copying z to z: )r   r   r   r0  r  r  r/   rQ   r   r  r   r   r7  r8  rU   r2  r   r;  r'  rw   r1   r9  r   r/  r   )
r   r  r  rM  r  r  r  Z
parent_dirr   ra   r(   r(   r)   r     s<    


"r   c             C   sn   yt |d}W n
   dS | }xFt|dkrh|d}t||kr^|| | kr^|  dS | }q$W dS )NrN   r   r^   rk   )r2   r  rm   rl   r3   )r)  Znumr   r  r   r  r(   r(   r)   test_numitem_exist  s    
r  c             C   s   t | d|S )Nr   )r  )r  Z
passwdfiler(   r(   r)   test_user_exist  s    r  c             C   s   t | d|S )Nr   )r  )groupZ	groupfiler(   r(   r)   test_group_exist  s    r  c             C   s
   t | S )N)r   Z	get_names)r{   r(   r(   r)   get_all_users_with_uid  s    r  c             C   s   t |  S )z%
    Simple execute bash command
    )r/   popenrT   )rr  r(   r(   r)   rG     s    rG   c             C   s   yf|rt j| t jt jdd}nt j| t jt jdd}| \}}|rd|jdkrdtdd|  td W n: t	k
r   tdd|  td |rt
d  Y nX |S )NT)r  r   r  r   zError while executing rt  rk   zError: failed to run )r  r  r  ZSTDOUTru  rv  r   r   r   r1   rx   ry   )rr  r  merge_stderrrZ  r  rx  rJ   r(   r(   r)   r    s    

r  c             C   sj   t |}| |}|dkrf| || d  }d}x&|t |k rTt|| sJP |d7 }q0W |d | }|S dS )Nr;   r   rk   r]   )rm   rD   rg  )r   rk  rl  r8   rm  rn  ro  r(   r(   r)   get_version_str  s    
r  c       
      C   s   d}d}t j|rt|}xtt|D ]}|| }|r*|d dkr*|| dkr*|dd}|d  }|| kr*|d  }|d}	|	dkr|d |	 }| }|d}|d	}|}P q*W |S )
Nr]   z#/var/lib/pgsql/data/postgresql.confr   r  r;   r  rk   r>   r=   )	r/   rQ   rR   r@   rn   rm   rD   rl   r  )
r~   valueZ	PSQL_CONFZ	psql_confrI   r   vZopt_namevalr8   r(   r(   r)   get_postgres_config	  s(    


r  c              C   s   d} t j| rt| }x|D ]}| }xtt|D ]r}|| }|d}|d}|dkr8y||d  }W n    td|  t	
d Y nX |d}|d}|S q8W qW tdS )Nz#/var/lib/pgsql/data/postmaster.optsr>   r=   z-prk   zError while parsingport)r/   rQ   rR   r@   rl   rn   rm   r  r   rx   ry   r  )ZOPTSrH   r   r  rI   rh  r  r(   r(   r)   get_postgres_port	  s&    





r  c          	   C   s   d}t  }|dkr(td | r(td d| }|dkrJt||d g nDtj|ryt| W n( t	t
fk
r   t||d g Y nX d S )Nz#/usr/share/cagefs/pgsql.socket.namer]   z)Port of PostgreSQL server is not detectedrk   z/tmp/.s.PGSQL.Z5432rM   )r  r   rx   ry   rF   r/   rQ   rR   rU   r1   rw   )rZ  ZPGSQL_SOCKET_CFGr  Zsocket_namer(   r(   r)   detect_postgres7	  s    
r  c          	   C   s   t | dkrd S t| }xt| D ]}tj| |}yt|j}W n  tk
rf   t	d| w$Y nX t
|rtq$t
|rt| q$|t
jt
jB @ r$|rtd| q$td| q$W d S )Nz/proczlstat() failed for pathzMounted to skeleton:zCopied  to skeleton:)r   r   r/   r   rQ   r   r   r  r1   r   r   r   r0  print_suidsr   r   r   )r   Zmountedr   r   r&  r(   r(   r)   r  P	  s$    



r  c             C   sJ   i }t j| rFt| d}x"|D ]}|dd }d||< q W |  |S )NrN   r^   r   rk   )r/   rQ   rR   r2   rl   r3   )rQ   r  Zpfr   r  r(   r(   r)   get_users_from_passwdg	  s    

r  c          
   C   s@  t   |d }tj|sd S t|}| d kr:t|d } d}xtt|D ]}|| d}t|dkrL|d dkrL|d d d d	}g }d}	x$|D ]}
|
| kr|	|
 qd
}	qW |	rL|d d |d  d }d	
|}||d 7 }|||< d
}qLW |r<t|| ytd| W n tttjfk
r:   Y nX d S )Nz
/etc/groupz/etc/passwdFr^   r   r  )r]   rM   r;   r  Tr   z:x:r   rM   )r   r/   rQ   rR   r@   r  rn   rm   rl   r(  r   rF   r7  Zcopystatr1   rw   r9  )r  rQ   Z
group_filerH   Zfile_changedrI   r  Zgroup_usersZnew_group_usersZchangedr  rK   Ztmp2r(   r(   r)   !remove_unwanted_users_from_groupss	  s<    


r  c             C   sT   i }t j| rPx>t | D ]0}t j| |}t j|rt |}|||< qW |S )N)r/   rQ   r   r   r   rb   r   )Z
cl_alt_dirlinksr   rQ   link_tor(   r(   r)   read_symlinks	  s    
r  c             C   sv   xp| D ]h}y| | }t || W q ttfk
rl } z(td| d t|dd td dS d }~X Y qX qW dS )Nz!Error : failed to create symlink z : r   zErr coderk   TF)r/   r2  r1   rw   r   r`   r_   r   )r  rQ   r  ra   r(   r(   r)   write_symlinks	  s    
$r  c             C   sB   t ||}| j}| j|kr$|tj@ S |tj@ r8| j|kp@|tj@ S )N)r   r  st_uidr   S_IWUSRS_IWGRPst_gidS_IWOTH)r%  r{   r|   r   r&  r(   r(   r)   is_writable	  s
    


r  c             C   s$   t | ||||td}t| |d kS )N)Zlogger)r   r   r   )rQ   r  r{   r|   r  r  r(   r(   r)   make_userdir	  s    r  c          	   C   s   d}yt | }W n tk
r*   d}Y nX |rt|jsL|r^t j| r^|rZt| |S dS yt 	|  W n8 tt
fk
r   t j| rtd|  td dS Y nX yt| | W n8 tt
fk
r   t j| std|  td dS Y nX dS )a  
    Create directory if it does not exist. Check for symlink (race conditions are not handled).
    Returns True if error has occured
    :param path: path to directory
    :type path: string
    :param perm: Linux permissions
    :type perm: int
    :param allow_symlink: True = allow path to be symlink, False = delete symlink and create directory
    :type allow_symlink: bool
    :param update_perm: True = set permissions when path exists
    :type update_perm: bool
    TFzError: failed to remove rk   z#Error : failed to create directory )r/   r   r1   r   r0  r  rQ   r   set_permrU   rw   r   r   r   r   )rQ   r  Zallow_symlinkZupdate_permZpath_existsr%  r(   r(   r)   make_dir	  s.    



r  c          	   C   s>   yt | | dS  ttfk
r8   td|  td dS X d S )NFz$Error: failed to set permissions to rk   T)r/   r   r1   rw   r   r   )rQ   r  r(   r(   r)   r  	  s    r  c          	   C   s@   yt | || dS  ttfk
r:   td|  td dS X d S )NFz"Error: failed to set ownership to rk   T)r/   r   r1   rw   r   r   )rQ   r{   r|   r(   r(   r)   	set_owner 
  s    r  c             C   sh   xb|D ]Z}t |}d}xH|D ]@}tj||}tj| |}	t|	|||}
|
d krTP t|
 qW qW d S )Nr]   )r  r/   rQ   r   r   r   )Zbasepathreal_homepathr{   r|   personal_mountsr   r  rQ   r   r  r  r(   r(   r)   fix_owner_of_personal_mounts
  s    

r  c          	   C   s   |st  sd S dd l}g }|r:ddlm} |dd|d x| D ]}yt|}W n tjk
rj   w@Y nX t	j
|j}t	j
|jd}	t	j
|	d}
t|	|j|j|}|d krq@t|	d||d}|d krq@t| t|j|j t|
 t  |||d |r@t|	||j|j| q@W d S )	Nr   )read_mpfileT)Zskip_errorsZskip_cpanel_checkr  z.cagefsz.cagefs.enabledi  )r  )r  Zis_ispmanagercagefs_ispmanager_lib	cagefsctlr  r   get_pw_by_namer   NoSuchUserExceptionr/   rQ   rd   pw_dirr   r   pw_uidpw_gidr   r   r
   rF  r   Z-ispmanager_create_user_wrapper_detect_php_verr  )r  Zis_user_enabledZ	fix_ownerr  r  r  r  pwr  rQ   Zstatus_flagr  r(   r(   r)   update_status
  s8    
r  c              C   s    t d } t d }t| d|dgS )Nzphp-clizphp.iniz-cz-i)r  r  )php_pathphp_ini_pathr(   r(   r)   get_php_infoH
  s    r  c              C   sb   t d } t d }y4t r,t| dgddd}nt| d|dgddd}W n tk
r\   d	}Y nX |S )
Nzphp-clizphp.iniz-mTF)r  rZ  z-cz-qmr]   )r  r  r  r1   )r  r   resultr(   r(   r)   get_list_of_php_modulesN
  s    
r  c              C   sZ   t d krRt  t d} i a x2| D ]*}|r$|ds$|dd }dt |< q$W tt S )NrM   [rt  rJ   rk   )php_modulesr  r  rl   rC   r_   lowerlist)rH   r   Zmodule_namer(   r(   r)   get_php_modules`
  s    
r  c             C   s   | t krt| t | < t |  S )N)files_cacher@   )rQ   r(   r(   r)   read_file_cachedq
  s    r
  c             C   s   d}i }t j|r~t|}x`|D ]X}| }|dkr"| }t|dkr"|d }| d ksj|| ksj| | r"|d }d||< q"W |S )Nz/etc/cl.selector/selector.confr]   r   rk   r  )r/   rQ   rR   r
  r   rl   rm   )	php_stateCL_ALT_CONF	alt_pathsrH   r   r  versrQ   r(   r(   r)   get_alt_paths{
  s    
r  c              C   sz   t d krvd} i a tj| rvt| }xP|D ]H}| }|dkr*| }t|dkr*|d dkr*|d }|d t |< q*W t S )Nz/etc/cl.selector/selector.confr]   r   r   r  rk   r   )alt_versionsr/   rQ   rR   r
  r   rl   rm   )r  rH   r   r  r  r(   r(   r)   get_alt_versions
  s    
r  r  c             C   s   t d krd}i a tj|rt|}xn|D ]f}| }|dkr*| }t|dkr*|d }|d }|d }	|t kr|t | }
ni }
|	|
|< |
t |< q*W | t kr|rtt |  	 S |t |  krt |  | S d S )Nz/etc/cl.selector/selector.confr]   r   r   rk   r  )
alt_confr/   rQ   rR   r
  r   rl   rm   r  keys)r  rq  get_aliasesr  rH   r   r  Z	cur_aliasZcur_versZcur_pathZtempr(   r(   r)   get_alt_conf
  s0    

r  c             C   s0   | dkrt tS t| dd}|d kr(g S |S d S )NnativeT)r  )r  r  r  )r  aliasesr(   r(   r)   get_alt_aliases
  s    r  c              C   s`   t d krXt } i a xD| D ]<}|d}|d }|drt|tdd  rdt |< qW tt S )Nr-   r  r  rk   )alt_dirsr  rl   rC   rj  rm   r  )r  rQ   r  r   r(   r(   r)   get_alt_dirs
  s    

r  c        
      C   s  d} g }g }xlt  D ]b}d| }|d }|d }tj|r|| nqtj|r`|| tj|r|| qW g }|r|t| g| ddg d |r|t| g| dd	g d t }x,|D ]$}|rxt	|D ]}	|
|	 qW qW t|S )
Nz/usr/bin/findz	/opt/alt/z/usr/binz	/usr/sbinz-namez*.sorM   z-typerW   )r  r/   rQ   r   r(  r  r  rl   setr  addr  )
ZFINDZaltpathsZbinpathsaltdirrQ   ZbinpathZsbinpathr   r   libr(   r(   r)   get_alt_php_libs
  s2    
""
r  c             C   s   ddl m}m} |d ||  d |  d }|d }tj|sX|d }tj|sXd S t|}|drpdS |d	r|d	d
}|d |	d }|S d S )Nr   )get_user_prefixBASEDIRr-   z/etc/cl.selector/r  r  z/usr/selector/r  z/opt/alt/phpr]   )
r  r   r!  r/   rQ   rb   r   rC   r_   rD   )Zusernamer   r!  rQ   Zuser_php_filer  php_verr(   r(   r)   get_php_version_for_user
  s    


r#  zcl.php.dz.cl.selectorzdefaults.cfgc       	      C   s   x||  D ]}|d }t j||}t jd|dd|}t j|s
t| yt || W q
 ttfk
r } z(td| d t	|
dd td	 W d d }~X Y q
X q
W d S )
Nz.iniz/opt/altr   z	php.d.allz!Error : failed to create symlink z : r   zErr coderk   )r/   rQ   r   rb   rF  r2  r1   rw   r   r`   r_   r   )	php_versr  r  r   modZ	link_nameZ	link_pathr  ra   r(   r(   r)   enable_extensions_symlinks1  s    r&  c             C   sB  | t kr:i }tj| r2xt| D ]}| d | }|dr*tj|r*|dtd  }g ||< t|}x|D ]}|	 }|
ds|
drz|dr|dd}n|dr|dd}|d	d
}t|dkrz|d
 drztj|d
  }|dtd  }||krz|| | qzW q*W |t | < t |  S )al  
    Return dependencies of php modules (extensions), determined by parsing of ini files in specified directory
    :param alt_dir: path to directory where ini files are (something like '/opt/alt/php54/etc/php.d.all')
    :type alt_dir: string
    :return: something like { 'mailparse' : ['mbstring'], 'xsl' : ['dom'], 'xmlreader' : ['dom'] }
    :rtype: dict
    r-   z.iniN	extensionZzend_extensionr=   r]   r>   r  rk   r   z.so)
deps_cacher/   rQ   r   r   r  rR   rm   r
  r   rC   r_   rl   r   lstripr(  )Zalt_dirdepsini_fileini_pathZextnamer   r  Zextr(   r(   r)   get_dependenciesA  s0    	



r-  c             C   s<   ||kr8x|| D ]}t | || qW || kr8| | d S )N)get_load_orderr(  )
load_orderr*  r%  depr(   r(   r)   r.  f  s
    r.  c             C   sJ   ||krFx*|| D ]}|| kr||kr|  | qW || krF|  | d S )N)r(  )r/  r*  r%  r0  r(   r(   r)   get_load_order_not_recursivep  s    r1  c          	   C   s   |dkrt |}xttfD ]}g }y^d||  kr>|||d nd||  krV|||d x$||  D ]}|dkr`|||| q`W P W q tk
r   |stdtd Y qX qW |S )aG  

    :param php_vers: something like 'php5.4'
    :type php_vers: string
    :param php_modules: { 'php5.3' : ['dom', 'xmlreader'], 'php5.4' : ['dom', 'xsl'] }
    :type php_modules: dict
    :param ini_path: path to directory where ini files are (something like '/opt/alt/php54/etc/php.d.all')
    :type ini_path: string
    Nioncube_loaderioncube_loader_4)r2  r3  z^Error: cyclic dependencies of PHP modules detected. Depth of dependencies will be limited to 1rk   )r-  r.  r1  RuntimeErrorr   r   )r$  r  r,  r*  quietfuncr/  r%  r(   r(   r)   build_load_orderz  s"    
r7  c          	   C   s  | d krd S t j| t|}t j|s,d S t|||dd}trts|td kr|yt	j
tdaW n ttfk
rz   daY nX tr|S |st	|}t }	tj||	| d}
tjstjstjr|rd| }nd}|d| d	 | 7 }|r|d
| 7 }n|d7 }t|tjtjtj n|}
|
S )NF)rZ  )Zphpconf_pathT)Zinput_phpini_linesr"  zUser: zUser: Unknownz; PHP version: z#
                     Backup file: z(
                     Destination file: z/
                     Destination file: Unknown)r/   rQ   r   CL_ALT_BACKUP_DIRrR   r   validate_alt_php_ini$bad_try_init_phpinivalidator_triggerphp_ini_validatorphpinivalidatorZPHPINIvalidatorPHP_CONFr1   rw   Zget_php_verr  ZvalidateZunknown_optionsZinvalid_values_optionsZinvalid_optionsr   )homepathr   r{   r|   r$  	user_namealt_php_ini_filebackup_pathZphp_ini_linesalt_versZoutput_lines_listZlog_messager(   r(   r)   read_custom_php_settings  s:    


rC  c          	   C   s(  t jd|dd}t| ||}	g }
x~|	D ]v}|
d| d  |d | d }t|}x<|D ]4}| }|r\|ds\|d	7 }||
kr\|
| q\W |
d	 q(W t j|d
}y*t|d| d ||| dd ||d}W n t	t
fk
r   d}Y nX |dk	r|
| |
d	 t|
||| dS )a  
    Enable specified extensions for specific php version and user
    :param php_vers: php version, something like 'php5.4'
    :type php_vers: string
    :param php_modules: extesions enabled for different php version for the user specified like { 'php5.3' : ['dom', 'xmlreader'], 'php5.4' : ['dom', 'xsl'] }
    :type php_modules: dict
    :param dirpath: path where generated alt_php.ini file is written to (something like '/var/cagefs/prefix/user/etc/cl.php.d/alt-php54')
    :type dirpath: string
    :param dirname: name of directory for specified php version inside /opt/alt directory (something like 'php54')
    :type dirname: string
    :param uid: uid of user
    :type uid: int
    :param gid: gid of user
    :type gid: int
    :param homepath: path to home directory of user (something like '/home/user')
    :type homepath: string
    :param user_name: name of user
    :type user_name: string
    z/opt/altr   z	php.d.allz;---z---
r-   z.ini;rM   zalt_php.iniZalt_z.cfgr  N)r$  r?  r@  )r/   rQ   r   r7  r(  r
  r   rC   rC  r1   rw   r  r	   )r$  r  r  r   r{   r|   r>  r?  r,  r/  Zalt_php_inimoduleZmodule_ini_pathZ
module_inir   user_ini_pathZcustom_php_settingsr(   r(   r)   enable_extensions  s:    







rG  c             C   s2  t  }|d krd}|d krd}|d kr*i }|d kr6i }tj| }d}x|D ]}d| }d|dd }d| }tj| |}tj|d}tj|r|	s|
rLt|d|||rqL||ks|	r||kr|| ||< nt }|||< d	}t	||||||||d
 qLW |r|}n|}|s|r.t
||||| d S )Nr  Fr  rj   r]   zalt-zalt_php.inii  T)r>  r?  )r  r/   rQ   rd   r_   r   r   r  r  rG  write_cl_alt_to_backup)Zuserpathr>  r{   r|   def_verscl_alt_def_modulesr  Zvers_changedZdef_vers_oldforceZrebuildr?  rB  Zreal_userpathZmodules_changedr  r$  r   r  r  rF  modulesZnew_versr(   r(   r)   select_default_php_modules  sN    
	rM  c             C   s,   t j| tt}t|| t|}t  |S )N)r/   rQ   r   r8  CL_ALT_DEFAULTSr
   read_cl_alt_backupr   )r>  r{   r|   rA  r  r(   r(   r)   read_cl_alt_backup_as_userW  s
    
rP  c          	   C   s  yt | }W n ttfk
r$   dS X tjd dd}y|| W n tjk
rX   dS X yt|ddd }W n tk
r   dS X i }i }i }x|	 D ]}|
dd}|drt|tdd  rt||d	||< ||d
rV||d
  drVd||tdd  < q|dkri }	x$||D ]}
|||
|	|
< q4W |	||< qW d|krd
|d kr|d d
   drd|d< ||||fS )N)NNNNF)interpolationstrictversionsr  r   rj   r]   rL  stateZdisable)rS  Z	phpnativer  )r   r1   rw   configparserConfigParserZreadfpr9  r  
IndexErrorZsectionsr_   rC   rj  rm   r  r  r  r  options)rA  Zbackup_fileZcfgrI  rL  r  othersectionr   rX  r~   r(   r(   r)   rO  _  s<    "*4rO  c               C   sR   t d kr,td kr,td kr,td kr,t tttfS ttjtt	\a aaat tttfS )N)
cl_alt_def_versrJ  cl_alt_def_php_statecl_alt_def_otherrO  r/   rQ   r   r  rN  r(   r(   r(   r)   read_cl_alt_defaults  s     r^  c             C   sj  | d krt jtt}d}nBt j| t}	t j| }
t|	d|||
rJd S t j| tt}d}g }|d |d| d  |d kri }xl|D ]d}|d| d  |d	d
||  d  |d kr|t	dd  }||kr|| s|d qW |d krVxR|D ]J}|d| d  x0|| D ]$}||d || |  d  q(W qW t
||||| d S )NFi  Tz[versions]
zphp=rM   z
[z]
zmodules=r  r  zstate=disabled
r  )r/   rQ   r   r  rN  r8  rd   r  r(  rm   r	   )r>  rI  rL  r{   r|   rT  rY  rA  Z	drop_permZ
backup_dirr  ZbackuprZ  r  r~   r(   r(   r)   rH    s6    



*rH  c       	      C   s   t dd}g }x|D ]}|ddkr|ddkr| }|d }|d d}|r`d	|kr`q|rnd
|krnq|td dks| r|ddks|ddkr|||dd   qW |  |S )Nz/proc/mountsrN   zcagefs-etcfsr;   zcagefs-varfsrk   r  r  ZnosuidZror-   z/var/cagefs/z	/.cagefs/)r2   rD   rl   r   r(  r3   )	Zall_cagefs_mountsZwithout_nosuidZrw_mounts_onlyr   Zmounts_listr   r  Z
mountpointZoptsr(   r(   r)   get_mounted_dirs  s    

2r_  c             C   s   t d}t }| rXxtdD ]2}|t|}|r tj|r |	|
d q W n>t }x4|D ],}|| j}||}|rf|	|
d qfW |S )zh
    Returns set of base home directories like {"/home0", "/home1", .., "/home9"} including "/home"
    z(/home\d?)/z/home*rk   )r   compiler  r  r   r   r/   rQ   r   r  r  r   Zget_user_dictr  )Zuse_globpatterndirsrQ   mr  r  r   r(   r(   r)   get_homeN_dirs  s    



rd  c          	   C   s|   t | } | tkrpy8t| }t|jr:t|  }t| < ng  }t| < W qx tt	fk
rl   g  }t| < Y qxX nt|  }|S )N)
r   listdir_cacher   r   r0  r  r/   r   r1   rw   )rQ   r%  r   r(   r(   r)   cached_listdir  s    rf  z/etc/cagefs/custom.etc/c               C   s   t tS )N)rf  
CUSTOM_ETCr(   r(   r(   r)   get_custom_etc_list  s    rh  c          	   C   s\   i }| t  krXt|  }yt|}W n ttfk
r:   |S X t|jrXt||||d |S )N)r   r   )	rh  rg  r   r1   rw   r   r0  r  r   )r  user_etc_pathZetc_listrQ   r%  r(   r(   r)   get_custom_etc_files_for_user	  s    
rj  c             C   s   | t  krt|  }yt|}W n ttfk
r6   d S X t|jrxt	|D ]}|t
ttgkrP|d | }|d | }yt|}W nD ttfk
r } z"td| d t| td wPW d d }~X Y nX t|jrt||dd qPt||dd qPW d S )Nr-   zError: lstat() failed file z : rk   T)rM  )rh  rg  r   r1   rw   r   r0  r  r/   r   CL_ALT_NAMECL_PHP_DIR_NAMEETC_VERSION_NAMEr   r`   r   r   r   )r  ri  r   r%  r   r   r  ra   r(   r(   r)    update_custom_etc_files_for_user  s&    
rn  z/usr/share/cagefs/custom.etc/c               C   s   t trdS dS )NTF)rf  CUSTOM_ETC_LOGr(   r(   r(   r)   custom_etc_present4  s    rp  c          	   C   s   yt t}W n8 ttfk
rD   td}ttd t| Y nX |r^tt|  |dd n,ytt|   W n ttfk
r   Y nX d S )Nr   i  T)rY  )	r   ro  r1   rw   r/   rs   r1  rF   rU   )r  list_of_filesrJ   r}   r(   r(   r)   save_custom_etc_log=  s    
rr  c             C   sv   g }| t tkrrtt|  }xL|D ]D}| }||kr"|dt s"|dt s"|ts"|| q"W |	  |S )Nr-   )
rf  ro  r@   r   rC   rk  rl  ETC_VERSIONr(  sort)r  rq  r   Zold_listrQ   r(   r(   r)   get_custom_etc_files_to_deleteP  s    
&ru  c             C   s2   t |}t }x| D ]}|||d   qW |S )N)rm   r  r  )r   rQ   Zplenr   r  r(   r(   r)   r   ^  s
    
r   c             C   sV   yt | }W n tk
r"   dS X t|js4dS |jdkpR|jdkpR|jtj@  S )NFr   )	r/   r   r1   r   r  r  r  r  r  )rQ   r%  r(   r(   r)   is_path_secureg  s    rv  c               C   sd   t d k	rd S tjtr tts(d a d S tjd dda yt t W n tj	k
r^   d a Y nX d S )NF)rQ  rR  )
cagefs_ini_cfgr/   rQ   rR   
CAGEFS_INIrv  rU  rV  rT   r9  r(   r(   r(   r)   read_cagefs_iniw  s    ry  c           	   C   sd   d} t   td kr| S ttdd}yt|d }|dk r<d}W n ttfk
rZ   d}Y nX | | S )NiQ r  update_period_daysr   rk   )ry  rw  r  rf   rg   rW  )Zseconds_in_24hr   daysr(   r(   r)   get_update_period  s    
r|  c             C   st   t   td krtjd ddat| s0t|  t| || ttd}t	| |
  ttdd ttd d S )NF)rQ  rR  r   r   i  )ry  rw  rU  rV  Zhas_sectionZadd_sectionr  r2   rx  ru   r3   r  r  )rZ  r~   r  r+  r(   r(   r)   set_cagefs_ini_option  s    



r}  c             C   s   t ddt|  d S )Nr  rz  )r}  r`   )r{  r(   r(   r)   set_update_period  s    r~  c              C   s2   d} t   td kr| S tddr.tddS | S )Nz/usr/sbin/tmpwatch -umclq 720r  tmpwatch)ry  rw  r  r  )ZTMPWATCHr(   r(   r)   get_tmpwatch_params  s    r  c             C   s   t dd|  d S )Nr  r  )r}  )Z
params_strr(   r(   r)   set_tmpwatch_params  s    r  c               C   s   t   td krg S ttddS )Nr  Ztmpwatch_dirs)ry  rw  r  r(   r(   r(   r)   get_tmpwatch_dirs  s    r  z&/usr/share/cagefs/last_update_time.txtc               C   s,   t tttt gdd ttd d S )NT)rY  i  )rF   LAST_UPDATE_TIMEr`   rf   timer/   r   r(   r(   r(   r)   save_last_update_time  s    r  c           	   C   sB   t jtr>tt} yt| d  S  ttfk
r<   Y nX dS )Nr   )	r/   rQ   rR   r  r@   rf   r  rg   rW  )r[  r(   r(   r)   read_last_update_time  s    r  c              C   s0   t  } | dkrdS t }tt }|||  kS )Nr   T)r|  r  rf   r  )Zupdate_periodZlast_updateZcurrent_timer(   r(   r)   #update_of_cagefs_skeleton_is_needed  s    r  c       
      C   s   t | }|sdS t |}|s dS t|jrt|js<dS t| }|  t|}|  ||krldS x4|D ],}| d | }|d | }	t||	|srdS qrW dS t|jrdS |st|jst|jrt	| |||dS t
j| |ddS d S )NFr-   T)r   r   )shallow)r  r   r0  r  r/   r   rt  are_dirs_equalr   r   filecmpZcmp)
Zdir1Zdir2r  Zsbuf1Zsbuf2Zlistdir1Zlistdir2r   Zpath1r   r(   r(   r)   r    s4    


r  c          	   C   sn   t  tj| d}t }xL|D ]D}y*t|}|j}|| |krNt| W q" tk
rd   Y q"X q"W dS )z
    Clean directories from old files
    :param dir_path: Dir path to clean
    :param max_lifetime: Max lifetime for clean
    :return: None
    zsess_[a-z0-9]*N)	r  r/   rQ   r   r  r   st_ctimerU   r1   )Zdir_pathZmax_lifetimeZsessionsZcur_timeZsessrh  Zctimer(   r(   r)    clean_dir_from_old_session_files  s    

r  /tmpc          
   C   s   yt | dx}xp| D ]d}| }|dr2qq|drXd|krX|dd  }q|drd|krt|dd }qW W dQ R X W n tttfk
r   Y nX |d|fS )	au  
    Read php.ini and returns session.save_path and session.gc_maxlifitime options
    :param str path: Path to ini file
    :param int default_time: Return that time when can not get value from config
    :param str default_path: Return that path when can not get value from config
    :return: Tuple (session.save_path, session.gc_maxlifitime)
    :rtype: (str, int)
    rN   rD  zsession.save_pathr  rk   zsession.gc_maxlifetimeNz"')	r2   r  r  rC   rl   rf   rW  rg   rw   )rQ   Zdefault_timeZdefault_pathZconfigr   lr(   r(   r)   get_opts_from_php_ini"  s    	
$r  c           
   C   s   t jtsdS td } tt }td }yt j|s@t|d W n> tk
r } z td| d t| t	d W dd}~X Y nX yt j
|st | | W nF tk
r } z(td| d	 |  d t| t	d W dd}~X Y nX dS )
z
    Create symlink /usr/share/cagefs-skeleton/var/run/utmp -> /var/run/cagefs/utmp
    needed for emulation of /var/run/utmp inside CageFS
    For details see CAG-706
    Nz/utmpz/var/run/utmpi  z"Error: failed to create directory z : rk   z Error: failed to create symlink z -> )r/   rQ   r   r   VAR_RUN_CAGEFSr   r1   r   r`   r   rb   r2  )Zutmp_cagefsZskel_cagefs_dirZ	skel_utmpra   r(   r(   r)   create_utmp_in_skeleton:  s    .r  c          
   C   s   yt | }W n tjk
r$   dS X |jd t }|d }tj|st	|j
|j y,tj|sttj|ddd t|d W n. tttfk
r   t  |rtd Y nX t  dS )	a  
    Create user's personal /home/user/.cagefs/var/run/cagefs/utmp file
    For details see CAG-706
    :param user: user name
    :type user: string
    :param exit_on_error: True == execute sys.exit(1) when error has occured
    :type exit_on_error: bool
    Nz/.cagefsz/utmpi  T)	recursiver]   rk   )r   r  r   r  r  r  r/   rQ   r   r
   r  r  r   r   r1  ru   r1   rw   r   r   rx   ry   r   )r  rZ  r  Zutmp_dirZ	utmp_filer(   r(   r)   create_utmp_for_userQ  s"    	r  c               C   s   t tdddsdS dS )zf
    Check clean_php_sessions parameter in config file
    By default sessions cleanup is enabled
    Zclean_user_php_sessionsT)Zdefault_valF)r    r!   r(   r(   r(   r)   "is_clean_user_php_sessions_enabledm  s    r  )FNN)T)T)NNT)NNT)r]   r   )r   r   r   )r   rk   r   r   )r   rk   r   )rk   rk   )FF)T)F)F)N)r   )r   )r   )r   )TF)TFT)T)FT)F)N)r  F)NF)NNN)NN)N)NN)FFF)F)T)r  )T(!  Z
__future__r   r   r   r   r   Zfuturer   Zinstall_aliasesbuiltinsr   rx   r7  stringr  r  r   r   rU  r  r  r   r   r   rv   r   r/   Zsecureior   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r  Zclcommon.clfuncr   r   Zclcommonr   r   r<  Zsignals_handlersr   Zclcommon.utilsr   r   r   r    r!   r#   r"   rm  rs  rx  r=  ZETC_TEMPLATE_DIRr   r  ZVERBOSE_FLAGr9  rt   rr   r   ZFALLBACK_PLESK_VHOSTS_Dre   rO   rc   rA   rE   rP   rV   rS   r4   rL   rX   r\   r[   boolrY   rZ   ri   rp   rU   r   ZLOG_ERRr   r   r  r   r   r   r   r   r   r   ZFUSE_WHITE_LISTr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r'  r  r*  r.  r,  r3  r>  rG  rN  rW  rF   r@   rg  rj  rp  rs  ry  r}  rz  r  r~  r|  r  r  rF  r  r  r  rk  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  rO  r  r  r  r  r  r  r  r  r   r   r  r  r  r  rG   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r#  rl  ZETC_CL_PHP_PATHr8  rN  r&  r(  r-  r.  r1  r7  r;  r:  rC  rG  rM  rP  rO  r[  rJ  r\  r]  r^  rH  r_  rd  re  rf  rg  rh  rj  rn  ro  rp  rr  ru  r   rv  rw  ry  r|  r}  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r(   r(   r(   r)   <module>	   s  $"
 

		#C 	d +
&	

I	 bg^4/
N()
,+
$ %

)T>)'		"