Ë
    M/Åew  ã                   óh  — d Z ddlmZ ddlmZ ddlZddlZddlZddlZddl	m
Z
 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ZddlZddlZddlZddlZddlZd
Z G d„ d«      Z e«       Zdededdfd„Zdedefd„Zededed   fd„«       Zdedededededdfd„Z 	 d@dededededdf
d„Z!dededefd„Z"dedefd„Z#dededefd„Z$dAdedededefd „Z%dAdededdfd!„Z&dAdededdfd"„Z'dededdfd#„Z(dedefd$„Z)d%edefd&„Z*d'edefd(„Z+d'edefd)„Z,d*ed+edefd,„Z-d-ed.edefd/„Z.d'ed0edefd1„Z/d'edefd2„Z0dededdfd3„Z1dBd4e
dedee   de
fd5„Z2dedeeeeef   f   fd6„Z3dededdfd7„Z4dededdfd8„Z5d9eeef   defd:„Z6dededefd;„Z7d<e
d=e
defd>„Z8de
fd?„Z9y# e$ r dZY �ŒTw xY w)Cz;Compat module to handle files security on Windows and Linuxé    )Úabsolute_import)ÚcontextmanagerN)ÚAny)ÚDict)Ú	Generator)ÚList)ÚOptionalFTc                   ó   — e Zd ZdZdd„Zy)Ú_WindowsUmaskz+Store the current umask to apply on WindowsNc                 ó   — d| _         y )Né   )Úmask)Úselfs    ú;/usr/lib/python3/dist-packages/certbot/compat/filesystem.pyÚ__init__z_WindowsUmask.__init__$   s	   € Øˆ�	ó    )ÚreturnN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   © r   r   r   r   "   s
   „ Ù5ôr   r   Ú	file_pathÚmoder   c                 óV   — t         rt        j                  | |«       yt        | |«       y)a[  
    Apply a POSIX mode on given file_path:

      - for Linux, the POSIX mode will be directly applied using chmod,
      - for Windows, the POSIX mode will be translated into a Windows DACL that make sense for
        Certbot context, and applied to the file using kernel calls.

    The definition of the Windows DACL that correspond to a POSIX mode, in the context of Certbot,
    is explained at https://github.com/certbot/certbot/issues/6356 and is implemented by the
    method `_generate_windows_flags()`.

    :param str file_path: Path of the file
    :param int mode: POSIX mode to apply
    N)Ú
POSIX_MODEÚosÚchmodÚ_apply_win_mode©r   r   s     r   r   r   +   s   € õ Ü
�‰�˜DÕ!ä˜	 4Õ(r   r   c                 ór   — t         rt        j                  | «      S t        j                  }| t        _        |S )a$  
    Set the current numeric umask and return the previous umask. On Linux, the built-in umask
    method is used. On Windows, our Certbot-side implementation is used.

    :param int mask: The user file-creation mode mask to apply.
    :rtype: int
    :return: The previous umask value.
    )r   r   ÚumaskÚ_WINDOWS_UMASKr   )r   Úprevious_umasks     r   r"   r"   @   s.   € õ Ü�x‰x˜‹~Ðä#×(Ñ(€NØ„NÔØÐr   )NNNc              #   ór   K  — d}	 t        | «      }d–— |�t        |«       yy# |�t        |«       w w xY w­w)zÂ
    Apply a umask temporarily, meant to be used in a `with` block. Uses the Certbot
    implementation of umask.

    :param int mask: The user file-creation mode mask to apply temporarily
    N)r"   )r   Ú	old_umasks     r   Ú
temp_umaskr'   Q   sF   è ø€ ð  $€IðÜ˜$“Kˆ	ØŠ
àÐ Ü�)Õð !øˆ9Ð Ü�)Õð !üs   ‚7†$ •7¤4´7ÚsrcÚdstÚ	copy_userÚ
copy_groupc                 óÞ   — t         rMt        j                  | «      }|r|j                  nd}|r|j                  nd}t        j
                  |||«       n|rt        | |«       t        ||«       y)aô  
    Copy ownership (user and optionally group on Linux) from the source to the
    destination, then apply given mode in compatible way for Linux and Windows.
    This replaces the os.chown command.

    :param str src: Path of the source file
    :param str dst: Path of the destination file
    :param int mode: Permission mode to apply on the destination file
    :param bool copy_user: Copy user if `True`
    :param bool copy_group: Copy group if `True` on Linux (has no effect on Windows)
    éÿÿÿÿN)r   r   ÚstatÚst_uidÚst_gidÚchownÚ_copy_win_ownershipr   )r(   r)   r   r*   r+   ÚstatsÚuser_idÚgroup_ids           r   Úcopy_ownership_and_apply_moder6   k   sW   € õ Ü—‘˜“ˆÙ"+�%—,’,°ˆÙ#-�5—<’<°2ˆô 	�‰��g˜xÕ(Ù	ä˜C Ô%ä	ˆ#ˆtÕr   c                 ó
  — t         rct        j                  | «      }|r|j                  nd}|r|j                  nd}t        j
                  |||«       t        ||j                  «       y|rt        | |«       t        | |«       y)aU  
    Copy ownership (user and optionally group on Linux) and mode/DACL
    from the source to the destination.

    :param str src: Path of the source file
    :param str dst: Path of the destination file
    :param bool copy_user: Copy user if `True`
    :param bool copy_group: Copy group if `True` on Linux (has no effect on Windows)
    r-   N)
r   r   r.   r/   r0   r1   r   Úst_moder2   Ú_copy_win_mode)r(   r)   r*   r+   r3   r4   r5   s          r   Úcopy_ownership_and_moder:   Œ   sc   € õ ä—‘˜“ˆÙ"+�%—,’,°ˆÙ#-�5—<’<°2ˆÜ
�‰��g˜xÔ(Üˆc�5—=‘=Õ!áä  SÔ)Ü�s˜CÕ r   c                 ó�   — t         r5t        j                  t        j                  | «      j                  «      |k(  S t        | |«      S )aa  
    Check if the given mode matches the permissions of the given file.
    On Linux, will make a direct comparison, on Windows, mode will be compared against
    the security model.

    :param str file_path: Path of the file
    :param int mode: POSIX mode to test
    :rtype: bool
    :return: True if the POSIX mode matches the file permissions
    )r   r.   ÚS_IMODEr   r8   Ú_check_win_moder    s     r   Ú
check_moder>   ¥   s7   € õ Ü�|‰|œBŸG™G IÓ.×6Ñ6Ó7¸4Ñ?Ð?ä˜9 dÓ+Ð+r   c                 óø   — t         r4t        j                  | «      j                  t        j                  «       k(  S t        j                  | t
        j                  «      }|j                  «       }t        «       |k(  S )zÁ
    Check if given file is owned by current user.

    :param str file_path: File path to check
    :rtype: bool
    :return: True if given file is owned by current user, False otherwise.
    )
r   r   r.   r/   ÚgetuidÚwin32securityÚGetFileSecurityÚOWNER_SECURITY_INFORMATIONÚGetSecurityDescriptorOwnerÚ_get_current_user)r   ÚsecurityÚusers      r   Úcheck_ownerrH   ¶   s_   € õ Ü�w‰w�yÓ!×(Ñ(¬B¯I©I«KÑ7Ð7ô ×,Ñ,¨Y¼×8`Ñ8`Óa€HØ×.Ñ.Ó0€Dô Ó $Ñ&Ð&r   c                 ó4   — t        | «      xr t        | |«      S )zý
    Check if given file has the given mode and is owned by current user.

    :param str file_path: File path to check
    :param int mode: POSIX mode to check
    :rtype: bool
    :return: True if file has correct mode and owner, False otherwise.
    )rH   r>   r    s     r   Úcheck_permissionsrJ   É   s   € ô �yÓ!ÒA¤j°¸DÓ&AÐAr   Úflagsc           	      ó‚  — t         rt        j                  | ||«      S |t        j                  z  �r4|t        j                  z  rt
        j                  nt
        j                  }t        j                  «       }|j                  }t        «       }t        ||t        j                  «      }|j                  |d«       |j!                  d|d«       d}	 t#        j$                  | t"        j&                  t"        j(                  t"        j*                  z  ||dd«      }	 |r|jA                  «        	 t        j                  | |t        j                  z  t        j                  z  «      S t        j                  | |«      }
tC        | |«       |
S # t,        j.                  $ r‰}	|	j0                  t0        j2                  k(  r$t5        t6        j8                  |	j:                  «      ‚|	j0                  t0        j<                  k(  r$t5        t6        j>                  |	j:                  «      ‚|	‚d}	~	ww xY w# |r|jA                  «        w w xY w)aw  
    Wrapper of original os.open function, that will ensure on Windows that given mode
    is correctly applied.

    :param str file_path: The file path to open
    :param int flags: Flags to apply on file while opened
    :param int mode: POSIX mode to apply on file when opened,
        Python defaults will be applied if ``None``
    :returns: the file descriptor to the opened file
    :rtype: int
    :raise: OSError(errno.EEXIST) if the file already exists and os.O_CREAT & os.O_EXCL are set,
            OSError(errno.EACCES) on Windows if the file already exists and is a directory, and
            os.O_CREAT is set.
    r   é   N)"r   r   ÚopenÚO_CREATÚO_EXCLÚwin32conÚ
CREATE_NEWÚCREATE_ALWAYSrA   ÚSECURITY_ATTRIBUTESÚSECURITY_DESCRIPTORrE   Ú_generate_daclr#   r   ÚSetSecurityDescriptorOwnerÚSetSecurityDescriptorDaclÚ	win32fileÚ
CreateFileÚGENERIC_READÚFILE_SHARE_READÚFILE_SHARE_WRITEÚ
pywintypesÚerrorÚwinerrorÚERROR_FILE_EXISTSÚOSErrorÚerrnoÚEEXISTÚstrerrorÚERROR_SHARING_VIOLATIONÚEACCESÚCloser   )r   rK   r   ÚdispositionÚ
attributesrF   rG   ÚdaclÚhandleÚerrÚfds              r   rN   rN   Õ   sº  € õ ä�w‰w�y %¨Ó.Ð.ð Œr�z‰zÓð .3´R·Y±YÒ->”h×)Ò)ÄH×DZÑDZˆä"×6Ñ6Ó8ˆ
Ø×1Ñ1ˆÜ Ó"ˆÜ˜d D¬.×*=Ñ*=Ó>ˆð 	×+Ñ+¨D°!Ô4ð 	×*Ñ*¨1¨d°AÔ6àˆð	Ü×)Ñ)¨)´Y×5KÑ5KÜ*3×*CÑ*CÄi×F`ÑF`Ñ*`Ø*4°kÀ1ÀdóL‰Fñ Ø—‘•ô
 �w‰w�y %¬"¯*©*Ñ"4´r·y±yÑ"@ÓAÐAô 
�‰�˜EÓ	"€BÜ	ˆ)�TÔØ€Iøô) ×Ñò 	ð �|‰|œx×9Ñ9Ò9ÜœeŸl™l¨C¯L©LÓ9Ð9Ø�|‰|œx×?Ñ?Ò?ÜœeŸl™l¨C¯L©LÓ9Ð9ØˆIûð	ûñ Ø—‘•ð ús&   ÃAF
 Æ
H&ÆBH!È!H&È&H) È)H>c                 ób  — t        d«      }	 t        |d|z  z  «       t        r!t        j                  | |«      t        |«       S t        j                  }	 t        t        _        t        j                  | |«      |t        _        t        |«       S # |t        _        w xY w# t        |«       w xY w)a4  
    Rewrite of original os.makedirs function, that will ensure on Windows that given mode
    is correctly applied.

    :param str file_path: The file path to open
    :param int mode: POSIX mode to apply on leaf directory when created, Python defaults
                     will be applied if ``None``
    r   éÿ  )r"   r   r   ÚmakedirsÚmkdir)r   r   Úcurrent_umaskÚorig_mkdir_fns       r   rq   rq     sŠ   € ô ˜!“H€Mðô
 	ˆm˜e d™lÑ*Ô+åÜ—;‘;˜y¨$Ó/ô 	ˆmÕô Ÿ™ˆð	%ô ŒBŒHÜ—;‘;˜y¨$Ó/à$ŒBŒHäˆmÕøð %ŒB�HûäˆmÕús)   �,B! ÁB! Á$B Á:B! ÂBÂB! Â!B.c                 ó  — t         rt        j                  | |«      S t        j                  «       }|j
                  }t        «       }t        ||t        j                  «      }|j                  |d«       |j                  d|d«       	 t        j                  | |«       y# t        j                  $ rT}|j                   t         j"                  k(  r0t%        t&        j(                  |j*                  | |j                   «      ‚|‚d}~ww xY w)a,  
    Rewrite of original os.mkdir function, that will ensure on Windows that given mode
    is correctly applied.

    :param str file_path: The file path to open
    :param int mode: POSIX mode to apply on directory when created, Python defaults
                     will be applied if ``None``
    FrM   r   N)r   r   rr   rA   rT   rU   rE   rV   r#   r   rW   rX   rY   ÚCreateDirectoryr^   r_   r`   ÚERROR_ALREADY_EXISTSrb   rc   rd   re   )r   r   rj   rF   rG   rk   rm   s          r   rr   rr   :  s×   € õ Ü�x‰x˜	 4Ó(Ð(ä×2Ñ2Ó4€JØ×-Ñ-€HÜÓ€DÜ˜$ ¤n×&9Ñ&9Ó:€DØ×'Ñ'¨¨eÔ4Ø×&Ñ& q¨$°Ô2ðÜ×!Ñ! )¨ZÔ8ð øô ×Ñò ð �<‰<œ8×8Ñ8Ò8Üœ%Ÿ,™,¨¯©°iÀÇÁÓNÐNØˆ	ûðús   ÂB ÂDÂ2ADÄDc                 ó€   — t        t        d«      r t        t        d«      | |«       yt        j                  | |«       y)zµ
    Rename a file to a destination path and handles situations where the destination exists.

    :param str src: The current file path.
    :param str dst: The new file path.
    ÚreplaceN)Úhasattrr   ÚgetattrÚrename)r(   r)   s     r   ry   ry   Y  s3   € ô Œr�9Ôð 	Œ”�IÓ˜s CÕ(ô 	�	‰	�#�sÕr   c                 óð  — | }t         st        j                  dk\  rZt        j                  j                  | «      }t        j                  j                  |«      rt        dj                  |«      «      ‚|S g }t        j                  j                  | «      rÂ| }t        j                  | «      } t        j                  j                  | «      s=t        j                  j                  t        j                  j                  |«      | «      } | |v rt        dj                  |«      «      ‚|j                  | «       t        j                  j                  | «      rŒÂt        j                  j                  | «      S )a   
    Find the real path for the given path. This method resolves symlinks, including
    recursive symlinks, and is protected against symlinks that creates an infinite loop.

    :param str file_path: The path to resolve
    :returns: The real path for the given path
    :rtype: str
    )é   é   zError, link {0} is a loop!)r   ÚsysÚversion_infor   ÚpathÚrealpathÚislinkÚRuntimeErrorÚformatÚreadlinkÚisabsÚjoinÚdirnameÚappendÚabspath)r   Úoriginal_pathr‚   Úinspected_pathsÚ	link_paths        r   rƒ   rƒ   j  s
  € ð €Mõ ”S×%Ñ%¨Ò/Ü�w‰w×Ñ 	Ó*ˆÜ�7‰7�>‰>˜$Ôô Ð;×BÑBÀ=ÓQÓRÐRØˆà!#€OÜ
�'‰'�.‰.˜Ô
#Øˆ	Ü—K‘K 	Ó*ˆ	Ü�w‰w�}‰}˜YÔ'ÜŸ™Ÿ™¤R§W¡W§_¡_°YÓ%?ÀÓKˆIØ˜Ñ'ÜÐ;×BÑBÀ=ÓQÓRÐRØ×Ñ˜yÔ)ô �'‰'�.‰.˜Õ
#ô �7‰7�?‰?˜9Ó%Ð%r   r�   c                 óš   — t        j                  | «      }t        s|j                  d«      s|S t	        |«      dk  r|dd S t        d«      ‚)a  
    Return a string representing the path to which the symbolic link points.

    :param str link_path: The symlink path to resolve
    :return: The path the symlink points to
    :returns: str
    :raise: ValueError if a long path (260> characters) is encountered on Windows
    z\\?\i  é   Nz3Long paths are not supported by Certbot on Windows.)r   r‡   r   Ú
startswithÚlenÚ
ValueError)r�   r‚   s     r   r‡   r‡   Œ  sI   € ô �;‰;�yÓ!€Då˜Ÿ™¨Ô3Øˆô ˆ4ƒy�3‚Ø�A�Bˆxˆä
ÐJÓ
KÐKr   r‚   c                 ó®   — t         rEt        j                  j                  | «      xr$ t        j                  | t        j
                  «      S t        | «      S )z‰
    Is path an executable file?

    :param str path: path to test
    :return: True if path is an executable file
    :rtype: bool
    )r   r   r‚   ÚisfileÚaccessÚX_OKÚ_win_is_executable)r‚   s    r   Úis_executablerš   ®  s9   € õ Ü�w‰w�~‰~˜dÓ#Ò@¬¯	©	°$¼¿¹Ó(@Ð@ä˜dÓ#Ð#r   c           	      ó¨  — t         rLt        t        j                  t	        j                  | «      j
                  «      t        j                  z  «      S t        j                  | t        j                  «      }|j                  «       }t        |j                  t        j                  t        j                  t        j                  d«      dœ«      «      S )zÒ
    Check if everybody/world has any right (read/write/execute) on a file given its path.

    :param str path: path to test
    :return: True if everybody/world has any right to the file
    :rtype: bool
    úS-1-1-0©ÚTrusteeFormÚTrusteeTypeÚ
Identifier)r   Úboolr.   r<   r   r8   ÚS_IRWXOrA   rB   ÚDACL_SECURITY_INFORMATIONÚGetSecurityDescriptorDaclÚGetEffectiveRightsFromAclÚTRUSTEE_IS_SIDÚTRUSTEE_IS_USERÚConvertStringSidToSid)r‚   rF   rk   s      r   Úhas_world_permissionsr©   ¼  s—   € õ Ü”D—L‘L¤§¡¨£×!6Ñ!6Ó7¼$¿,¹,ÑFÓGÐGä×,Ñ,¨T´=×3ZÑ3ZÓ[€HØ×-Ñ-Ó/€Dä�×.Ñ.Ü$×3Ñ3Ü$×4Ñ4Ü#×9Ñ9¸)ÓDñ0ó ó ð r   Úold_keyÚ	base_modec                 ó  — t         r{t        j                  t        j                  | «      j                  «      t        j
                  t        j                  z  t        j                  z  t        j                  z  z  }||z  S |S )a  
    Calculate the POSIX mode to apply to a private key given the previous private key.

    :param str old_key: path to the previous private key
    :param int base_mode: the minimum modes to apply to a private key
    :return: the POSIX mode to apply
    :rtype: int
    )	r   r.   r<   r   r8   ÚS_IRGRPÚS_IWGRPÚS_IXGRPÚS_IROTH)rª   r«   Úold_modes      r   Úcompute_private_key_moder²   Ñ  sa   € õ ô —L‘L¤§¡¨Ó!1×!9Ñ!9Ó:Ü—\‘\¤D§L¡LÑ0´4·<±<Ñ?Ä$Ç,Á,ÑNñPˆà˜8Ñ#Ð#ð Ðr   Úpath1Úpath2c                 óž  — t         r[t        j                  | «      }t        j                  |«      }|j                  |j                  f|j                  |j                  fk(  S t        j                  | t
        j                  «      }|j                  «       }t        j                  |t
        j                  «      }|j                  «       }||k(  S )as  
    Return True if the ownership of two files given their respective path is the same.
    On Windows, ownership is checked against owner only, since files do not have a group owner.

    :param str path1: path to the first file
    :param str path2: path to the second file
    :return: True if both files have the same ownership, False otherwise
    :rtype: bool

    )	r   r   r.   r/   r0   rA   rB   rC   rD   )r³   r´   Ústats1Ústats2Ú	security1Úuser1Ú	security2Úuser2s           r   Úhas_same_ownershipr¼   æ  sœ   € õ Ü—‘˜“ˆÜ—‘˜“ˆØ—‘˜vŸ}™}Ð-°&·-±-ÀÇÁÐ1OÑOÐOä×-Ñ-¨e´]×5]Ñ5]Ó^€IØ×0Ñ0Ó2€Eä×-Ñ-¨e´]×5]Ñ5]Ó^€IØ×0Ñ0Ó2€Eà�E‰>Ðr   Úmin_modec                 ó  — t         r't        j                  | «      j                  }|||z  k(  S t	        | «      } t        j                  | t
        j                  t
        j                  z  «      }|j                  «       }|j                  «       }t        ||«      }t        |j                  «       «      D ]X  }|j                  |«      }|d   }	|d   }|j                  t
        j                   t
        j"                  |dœ«      }
|
|
|	z  k7  sŒX y y)a”  
    Check if a file given its path has at least the permissions defined by the given minimal mode.
    On Windows, group permissions are ignored since files do not have a group owner.

    :param str path: path to the file to check
    :param int min_mode: the minimal permissions expected
    :return: True if the file matches the minimal permissions expectations, False otherwise
    :rtype: bool
    rM   é   r�   FT)r   r   r.   r8   rƒ   rA   rB   rC   r£   rD   r¤   rV   ÚrangeÚGetAceCountÚGetAcer¥   r¦   r§   )r‚   r½   r8   rF   rG   rk   Úmin_daclÚindexÚmin_acer   Úeffective_masks              r   Úhas_min_permissionsrÇ   ÿ  s  € õ Ü—'‘'˜$“-×'Ñ'ˆØ˜' HÑ,Ñ,Ð,ô �D‹>€Dô ×,Ñ,ØŒm×6Ñ6¼×9`Ñ9`Ñ`ób€Hà×.Ñ.Ó0€DØ×-Ñ-Ó/€DÜ˜d HÓ-€Hä�x×+Ñ+Ó-Ó.ò ˆØ—/‘/ %Ó(ˆð �q‰zˆØ�q‰zˆà×7Ñ7Ü(×7Ñ7Ü(×8Ñ8Øñ9
ó ˆð ˜^¨dÑ2Ó2Ùðð" r   c                 ód  — t         j                  j                  | «      syt        j                  | t        j
                  «      }|j                  «       }|j                  t        j                  t        j                  t        «       dœ«      }|t        j                  z  t        j                  k(  S )NFr�   )r   r‚   r–   rA   rB   r£   r¤   r¥   r¦   r§   rE   ÚntsecurityconÚFILE_GENERIC_EXECUTE)r‚   rF   rk   r   s       r   r™   r™   ,  s†   € Ü�7‰7�>‰>˜$ÔØä×,Ñ,¨T´=×3ZÑ3ZÓ[€HØ×-Ñ-Ó/€Dà×)Ñ)Ü$×3Ñ3Ü$×4Ñ4Ü'Ó)ñ+ó €Dð ”-×4Ñ4Ñ4¼×8ZÑ8ZÑZÐZr   c                 ó
  — t        | «      } t        j                  | t        j                  «      }|j	                  «       }t        ||«      }|j                  d|d«       t        j                  | t        j                  |«       y)zà
    This function converts the given POSIX mode into a Windows ACL list, and applies it to the
    file given its path. If the given path is a symbolic link, it will resolved to apply the
    mode on the targeted file.
    rM   r   N)	rƒ   rA   rB   rC   rD   rV   rX   ÚSetFileSecurityr£   )r   r   rF   rG   rk   s        r   r   r   <  so   € ô ˜Ó#€Iä×,Ñ,¨Y¼×8`Ñ8`Óa€HØ×.Ñ.Ó0€Dô ˜$ Ó%€Dð ×&Ñ& q¨$°Ô2Ü×!Ñ! )¬]×-TÑ-TÐV^Õ_r   Úuser_sidc                 óH  — |r|d|z
  z  }t        |«      }t        j                  d«      }t        j                  d«      }t        j                  d«      }t        j                  «       }| ||fvr1t	        |d   «      }|r!|j                  t        j                  || «       t	        |d   «      }	|	r!|j                  t        j                  |	|«       t	        ddddœ«      }
|j                  t        j                  |
|«       |j                  t        j                  |
|«       |S )	Nrp   zS-1-5-18zS-1-5-32-544rœ   rG   ÚallT©ÚreadÚwriteÚexecute)Ú_analyze_moderA   r¨   ÚACLÚ_generate_windows_flagsÚAddAccessAllowedAceÚACL_REVISION)rÍ   r   r   ÚanalysisÚsystemÚadminsÚeveryonerk   Ú
user_flagsÚeverybody_flagsÚfull_permissionss              r   rV   rV   O  s  € ÙØ�u˜t‘|Ñ$ˆÜ˜TÓ"€Hô
 ×0Ñ0°Ó<€FÜ×0Ñ0°Ó@€FÜ×2Ñ2°9Ó=€Hô ×ÑÓ€Dð ˜ Ð'Ñ'ä,¨X°fÑ-=Ó>ˆ
ÙØ×$Ñ$¤]×%?Ñ%?ÀÈXÔVô .¨h°u©oÓ>€OÙØ× Ñ ¤×!;Ñ!;¸_ÈhÔWô /¸ÀtÐX\Ñ/]Ó^ÐØ×Ñœ]×7Ñ7Ð9IÈ6ÔRØ×Ñœ]×7Ñ7Ð9IÈ6ÔRà€Kr   c                 óè   — | t         j                  z  | t         j                  z  | t         j                  z  dœ| t         j                  z  | t         j
                  z  | t         j                  z  dœdœS )NrÐ   )rG   rÏ   )r.   ÚS_IRUSRÚS_IWUSRÚS_IXUSRr°   ÚS_IWOTHÚS_IXOTH)r   s    r   rÔ   rÔ   s  sb   € ð œ4Ÿ<™<Ñ'ØœDŸL™LÑ(ØœdŸl™lÑ*ñ
ð œ4Ÿ<™<Ñ'ØœDŸL™LÑ(ØœdŸl™lÑ*ñ
ñð r   c                 ó8  — t        | «      } t        j                  | t        j                  «      }|j	                  «       }t        j                  |t        j                  «      }|j                  |d«       t        j                  |t        j                  |«       y ©NF)rƒ   rA   rB   rC   rD   rW   rÌ   )r(   r)   Úsecurity_srcÚuser_srcÚsecurity_dsts        r   r2   r2   ‚  st   € ä
�3‹-€Cä ×0Ñ0°´m×6^Ñ6^Ó_€LØ×6Ñ6Ó8€Hä ×0Ñ0°´m×6^Ñ6^Ó_€Lð ×+Ñ+¨H°eÔ<ä×!Ñ! #¤}×'OÑ'OÐQ]Õ^r   c                 ó:  — t        | «      } t        j                  | t        j                  «      }|j	                  «       }t        j                  |t        j                  «      }|j                  d|d«       t        j                  |t        j                  |«       y )NrM   r   )rƒ   rA   rB   r£   r¤   rX   rÌ   )r(   r)   rè   rk   rê   s        r   r9   r9   ‘  sv   € ä
�3‹-€Cô !×0Ñ0°´m×6]Ñ6]Ó^€LØ×1Ñ1Ó3€Dä ×0Ñ0°´m×6]Ñ6]Ó^€LØ×*Ñ*¨1¨d°AÔ6Ü×!Ñ! #¤}×'NÑ'NÐP\Õ]r   Úrights_descc                 óÞ   — d}| d   r|t         j                  z  }| d   r5|t         j                  t         j                  z  t         j                  z  z  }| d   r|t         j                  z  }|S )Nr   rÑ   rÒ   rÓ   )rÉ   ÚFILE_GENERIC_READÚFILE_ALL_ACCESSrÊ   )rì   Úflags     r   rÖ   rÖ   ž  sv   € ð$ €DØ�6ÒØ”m×5Ñ5Ñ5ˆØ�7ÒØ”}×4Ñ4Ü&×8Ñ8ñ9ä&×;Ñ;ñ<ñ =ˆð �9ÒØ”m×8Ñ8Ñ8ˆà€Kr   c                 óø   — t        | «      } t        j                  | t        j                  t        j                  z  «      }|j                  «       }|j                  «       }|syt        ||«      }t        ||«      S rç   )	rƒ   rA   rB   rC   r£   r¤   rD   rV   Ú_compare_dacls)r   r   rF   rk   rG   Úref_dacls         r   r=   r=   ½  sw   € ä˜Ó#€Iä×,Ñ,¨Y¼×8`Ñ8`Ü/<×/VÑ/Vñ9Wó X€Hà×-Ñ-Ó/€Dð ×.Ñ.Ó0€Dáð ô ˜d DÓ)€Hä˜$ Ó)Ð)r   Údacl1Údacl2c                 óð   — t        | j                  «       «      D �cg c]  }| j                  |«      ‘Œ c}t        |j                  «       «      D �cg c]  }|j                  |«      ‘Œ c}k(  S c c}w c c}w )z¥
    This method compare the two given DACLs to check if they are identical.
    Identical means here that they contains the same set of ACEs in the same order.
    )rÀ   rÁ   rÂ   )rô   rõ   rÄ   s      r   rò   rò   Ó  s`   € ô
 /4°E×4EÑ4EÓ4GÓ.HÖI UˆU�\‰\˜%Õ ÒIÜ.3°E×4EÑ4EÓ4GÓ.HÖI UˆU�\‰\˜%Õ ÒIñJð KùÒIùÚIs   œA.ÁA3c                  ó    — dj                  t        j                  «       t        j                  «       «      } t	        j
                  d| «      d   S )z=
    Return the pySID corresponding to the current user.
    z{0}\{1}Nr   )r†   Úwin32apiÚGetDomainNameÚGetUserNamerA   ÚLookupAccountName)Úaccount_names    r   rE   rE   Ü  sB   € ð ×$Ñ$¤X×%;Ñ%;Ó%=¼x×?SÑ?SÓ?UÓV€Lô ×*Ñ*¨4°Ó>¸qÑAÐAr   )TT)rp   )N):r   Ú
__future__r   Ú
contextlibr   rc   r   r.   r€   Útypingr   r   r   r   r	   rÉ   r^   rø   rQ   rY   rA   r`   r   ÚImportErrorr   r#   ÚstrÚintr   r"   r'   r¡   r6   r:   r>   rH   rJ   rN   rq   rr   ry   rƒ   r‡   rš   r©   r²   r¼   rÇ   r™   r   rV   rÔ   r2   r9   rÖ   r=   rò   rE   r   r   r   ú<module>r     s«  ðÙ AÝ &å %Û Û 	Û Û 
Ý Ý Ý Ý Ý ðÛÛÛÛÛÛÛð €J÷ñ ñ “€ð)�Sð ) ð )¨ó )ð*�ð ˜ó ð" ð�Sð ˜YÐ'7Ñ8ò ó ðð2 sð °ð ¸Cð Ø-1ðØ?CðØHLóðD HLñ! ð !¨3ð !Ø'+ð!Ø@Dð!ØPTó!ð2,˜#ð , Sð ,¨Tó ,ð"'˜3ð ' 4ó 'ð&	B ð 	B¨Cð 	B°Dó 	BñB�Cð B ð B¨3ð B¸3ó BñJ˜ð  3ð °4ó ñ@�Sð  ð °ó ð>�ð ˜3ð  4ó ð"&˜ð & ó &ðDL˜ð L ó LðD$˜ð $ ó $ð ð ¨ó ð* cð °cð ¸có ð*˜cð ¨#ð °$ó ð2*˜cð *¨Sð *°Tó *ðZ[˜Sð [ Tó [ð `˜sð `¨#ð `°$ó `ñ&!˜Sð !¨ð !°8¸C±=ð !ÈCó !ðH˜ð   S¨$¨s°C¨x©.Ð%8Ñ 9ó ð_˜Sð _ sð _¨tó _ð
^˜ð 
^ #ð 
^¨$ó 
^ð¨¨c°3¨h©ð ¸Có ð>*˜sð *¨#ð *°$ó *ð,K˜#ð K cð K¨dó KðB˜3ô BøðK ò ØƒJðús   ¾F& Æ&F1Æ0F1