a tU~h¡&ã@s–dZddlZddlmZddlmZddlmZddlm Z m Z m Z m Z ddl Z ddlmZddlmZGd d „d ƒZGd d „d ƒZGd d„dƒZdS)zCommon fixperms classeséN)Úquote)ÚPath)ÚUnion)ÚS_IMODEÚS_ISREGÚS_ISDIRÚS_ISLNK)ÚArgs)ÚIDCachec@s$eZdZdZeeeeeee eefdœdd„Z ee e edfe edffe eefddœdd„Z ee jeed œd d „Zee je edfd œd d„Zd(eedœdd„Zd)eedœdd„Zddœdd„Zddœdd„Ze je defdœdd„Ze jedœdd „Zed!d"œd#d$„Zed%œd&d'„ZdS)*ÚPermMapzBase class for fixperms)ÚidsÚargsÚuserÚ all_docrootsÚ docroot_chmodÚ docroot_chownc CsÔ||_|jj ¡|_||_|j|_t|ƒ|_||_||_ |j  |¡}|j |_ |j |_|  |d¡j }| |d¡j} tdd|f|| fƒ|_tj |j¡|_t d|j¡s¼t|›d|j›ƒ‚t |j¡|_g|_dS)NréÚz \/home\d*\/z: unexpected homedir: )r ÚskipÚcopyrZloggerÚlogÚHardLinkTrackerÚ hard_linksr rÚgetpwnamZpw_uidÚuidZpw_gidÚgidZgetgrnamZgr_gidÚRuleÚ docroot_permsÚosÚpathÚrealpathÚpw_dirÚhomedirÚreÚmatchÚ ValueErrorÚescapeÚhome_reÚperm_map) Úselfr r rrrrZpwuserZdoc_uidZdoc_gid©r*ú#./usr/lib/fixperms/fixperms_base.pyÚ__init__s$   zPermMap.__init__N)ÚregexÚmodesÚchownÚreturncCs"|j t|j›|›||ƒ¡dS)z9Add a fixperms path rule. ^HOMEDIR is automatically addedN)r(Úappendrr'©r)r-r.r/r*r*r+Úadd_rule+szPermMap.add_rule)rÚstatrrc Csø||krdkrnndS|dkr*|jn|}|dkr<|jn|}|j|jf||fkrXdS|jjs¦zt |||¡Wn2ty¤}z|j |¡WYd}~dSd}~00|j   |j¡}|j   |j¡} |j   |¡} |j   |¡} |j  dt |ƒ|| | | ¡dS)zRuns os.lchownéÿÿÿÿNz+Changed ownership of %s from %s:%s to %s:%s)Úst_uidÚst_gidr ÚnooprÚlchownÚOSErrorrÚerrorr Z uid_labelZ gid_labelÚdebugr) r)rr4rrZtgt_uidZtgt_gidÚexcZold_userZ old_groupZnew_userZ new_groupr*r*r+r95s0   úzPermMap.lchown)rr4Úmodec Cs®|dur dSt|jƒ}||kr"dSt|jƒr0dS|jjs|zt ||¡Wn2tyz}z|j  |¡WYd}~dSd}~00|j  dt |ƒt |ƒdd…t |ƒdd…¡dS)z*Runs os.chmod if the path is not a symlinkNz Changed mode of %s from %s to %sé) rÚst_moderr r8rÚchmodr:rr;r<rÚoct)r)rr4r>Zorigr=r*r*r+ÚlchmodPs&   üzPermMap.lchmodF)rÚ ignore_skipsc csl| ||¡D]Z}zt |¡}Wn<tyZ}z$|j |¡WYd}~q WYd}~n d}~00||fVq dS)z8os.walk/os.lstat to yield a path and all of its contentsN)Ú_walkrÚlstatr:rr;)r)rrDÚentryr4r=r*r*r+Úwalkks "z PermMap.walk)Útop_dirrDc #sÈ|s| |¡rdS|Vtj |¡s(dSt |¡D]\}}}|D]&}tj ||¡}|s`| |¡s@|Vq@g‰|D]2}tj ||¡}|sœ| |¡rœˆ |¡qp|Vqpˆr2‡fdd„|Dƒ|dd…<q2dS)Ncsg|]}|ˆvr|‘qSr*r*)Ú.0Úx©Z skip_dirsr*r+Ú ‰óz!PermMap._walk..)Ú should_skiprrÚisdirrHÚjoinr1) r)rIrDÚdirpathZdirnamesÚ filenamesÚfilenamerÚdirnamer*rLr+rEus$  z PermMap._walk)r0cCs| ¡|j ¡dS)z8To be called from fixperms_main.py - processes this userN)ÚfixpermsrÚhandle)r)r*r*r+Úrun‹sz PermMap.runc Cs\| |j¡D]J\}}z| ||¡Wq tyT}z|j |¡WYd}~q d}~00q dS)z5Iterate over a user's files and chown/chmod as neededN)rHr"Ú check_pathr:rr;)r)r4rr=r*r*r+rVs zPermMap.fixperms)r4Únew_modecCs*|dur dS|jjr&|jd@}||BS|S)z2Get a new file mode including old mode's exec bitsNéI)r Z preserve_execr@)r)r4rZZ exec_bitsr*r*r+Úwith_exec_bits˜s  zPermMap.with_exec_bits)r4rcCs´| t|ƒ¡}|j\}}t|jƒrR| ||¡}|jdkr„|j |||j |¡dSn2t |jƒrb|}n"t |jƒrrd}n|j   d|¡dS|durš| |||¡|j||g|j ¢RŽdS)z"Chown and chmod files as necessaryrNz#Skipping unexpected path type at %s)Ú find_ruleÚstrr.rr@r\Úst_nlinkrÚaddr/rrrZwarningrCr9)r)r4rÚruleZ file_modeZdir_moderZr*r*r+rY¡s       zPermMap.check_pathr)rr0cCsPt|tƒsJ‚||jvr|jS|jD]}|j |¡r$|Sq$td|›ƒ‚dS)z+Find the matching ``Rule`` for a given pathzNo matching rule for N)Ú isinstancer^rrr(r-r$r%)r)rrar*r*r+r]µs    zPermMap.find_rule)rcCs2|jD]&}||krdSt|ƒ |¡rdSqdS)z:Determine if a path should be skipped based on --skip argsTF)rrÚis_relative_to)r)rrr*r*r+rO¿s  zPermMap.should_skip)F)F)Ú__name__Ú __module__Ú __qualname__Ú__doc__r r r^ÚlistÚintÚtupler,rr3rÚ stat_resultr9rCÚboolrHrErXrVr\rYr]rOr*r*r*r+r s4 ù  û  ü    r c@sLeZdZdZedœdd„Zeeje e e fe e dfdœdd„Z d d „Z dS) rzQTracks and handles hard links discovered while walking through a user's files)r(cCs"||_i|_i|_i|_i|_dS)N)r(ÚchownsÚstatsr.Úpaths)r)r(r*r*r+r,Ís zHardLinkTracker.__init__N)rr4r/r>c Cs |j}||j|<||jvr,|j| |¡n |g|j|<||jvr€|\}}|j|\}} |dkrd|}|dkrp| }||g|j|<n ||j|<|durœ||j|<dS)zaUsed to add a hard link found during the fixperms run which might be unsafe to operate onr5N)Úst_inornror1rmr.) r)rr4r/r>ÚinumrrZprev_uidZprev_gidr*r*r+r`Ôs      zHardLinkTracker.addc Cs–|j ¡D]†\}}|jt|j|ƒkrl|j|d}|jj||g|j|¢RŽ|j |||j   |d¡¡q |j|D]}|jj   dt |ƒ¡qvq dS)zjIf self.hard_links was populated with any items, handle any that are safe, or log any that are notrNz*%s is hardlinked and not owned by the user)rnÚitemsr_Úlenror(r9rmrCr.Úgetrr;r)r)rqr4rr*r*r+rWðsþzHardLinkTracker.handle)rdrerfrgr r,r^rrkrjrirr`rWr*r*r*r+rÉs   û rc@sBeZdZdZeeeedfeedffeeefdœdd„ZdS)rzFixperms path ruleN)r-r.r/cCs8t |¡|_t|tƒsJ‚t|tƒs(J‚||_||_dS)a,Fixperms path rule Args: regex (str): regular expression file tuple[(int | None), (int | None)]: (file, dir) modes if matched chown tuple[int, int]: if a matching file/dir is found, chown to this UID/GID. Use -1 to make no change. N)r#Úcompiler-rbrjr.r/r2r*r*r+r,s  z Rule.__init__) rdrerfrgr^rjrrir,r*r*r*r+rs  ür)rgrZshlexrÚpathlibrÚtypingrr4rrrrr#Z fixperms_clir Z fixperms_idsr r rrr*r*r*r+Ús     ><