
    hb                        d dl Z d dlZd dlZd dlZd dlZd dlZe j                  j                  d d       d dlm	Z	m
Z
 d dlmZ d dlmZ d dlZd dlmZ d dlmZmZ d dlmc m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$m%Z% d dl&m'Z' d dlm(Z( d dlm)Z) d dl*m+Z+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3Z3d dlm4Z4 d dl5m6Z6 d dl7m8Z8 d dl9Z9d dl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ d dl7mAZAmBZBmCZC d dlmDZD d dlEZd dlmFZF 	 d dlGmHZH  eHdd      ZI G d d       ZK G d! d"      ZL G d# d$eM      ZN G d% d&eN      ZO G d' d(eN      ZP G d) d*eN      ZQ G d+ d,eM      ZR G d- d.eR      ZS	 d/ ZTd0 ZU	 d1 ZV G d2 d3      ZWd4 ZXd5 ZYd6 ZZd7 Z[d8 Z\d9 Z]d: Z^d; Z_d< Z`d= Zad> ZbdKd?Zcd@ ZddLdAZedB ZfdC ZgdD ZhdE Zi	 dMdFZjdNdGZkdNdHZldI ZmdJ Zny# eJ$ r  G d d      ZIY w xY w)O    Nz
bin/python)NTSTATUSErrorWERRORError)ConfigParser)StringIO)	get_bytes)ABCMetaabstractmethod)Net)nbt)libsmb_samba_internal)LoadParm)UUID)NamedTemporaryFile)preg)misc)ndr_pack
ndr_unpack)SMB_SIGNING_REQUIRED)log)blake2b)
get_string)SamDB)system_session)UF_WORKSTATION_TRUST_ACCOUNTUF_SERVER_TRUST_ACCOUNTGPLINK_OPT_ENFORCEGPLINK_OPT_DISABLEGPO_INHERITGPO_BLOCK_INHERITANCE) AUTH_SESSION_INFO_DEFAULT_GROUPSAUTH_SESSION_INFO_AUTHENTICATED#AUTH_SESSION_INFO_SIMPLE_PRIVILEGES)security)netlogon)EnumGPOSTATEzAPPLY ENFORCE UNAPPLYc                       e Zd ZdZdZdZy)r&            N)__name__
__module____qualname__APPLYENFORCEUNAPPLY     2/usr/lib/python3/dist-packages/samba/gp/gpclass.pyr&   r&   =   s    r2   c                   T    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zy)gp_loga[   Log settings overwritten by gpo apply
    The gp_log is an xml file that stores a history of gpo changes (and the
    original setting value).

    The log is organized like so:

<gp>
    <user name="KDC-1$">
        <applylog>
            <guid count="0" value="{31B2F340-016D-11D2-945F-00C04FB984F9}" />
        </applylog>
        <guid value="{31B2F340-016D-11D2-945F-00C04FB984F9}">
            <gp_ext name="System Access">
                <attribute name="minPwdAge">-864000000000</attribute>
                <attribute name="maxPwdAge">-36288000000000</attribute>
                <attribute name="minPwdLength">7</attribute>
                <attribute name="pwdProperties">1</attribute>
            </gp_ext>
            <gp_ext name="Kerberos Policy">
                <attribute name="ticket_lifetime">1d</attribute>
                <attribute name="renew_lifetime" />
                <attribute name="clockskew">300</attribute>
            </gp_ext>
        </guid>
    </user>
</gp>

    Each guid value contains a list of extensions, which contain a list of
    attributes. The guid value represents a GPO. The attributes are the values
    of those settings prior to the application of the GPO.
    The list of guids is enclosed within a user name, which represents the user
    the settings were applied to. This user may be the samaccountname of the
    local computer, which implies that these are machine policies.
    The applylog keeps track of the order in which the GPOs were applied, so
    that they can be rolled back in reverse, returning the machine to the state
    prior to policy application.
    Nc                 f   t         j                  | _        || _        || _        |rt        j                  |      | _        nt        j                  d      | _        || _	        | j                  j                  d|z        }|0t        j                  | j                  d      }||j                  d<   yy)ag   Initialize the gp_log
        param user          - the username (or machine name) that policies are
                              being applied to
        param gpostore      - the GPOStorage obj which references the tdb which
                              contains gp_logs
        param db_log        - (optional) a string to initialize the gp_log
        gpuser[@name="%s"]Nusername)r&   r.   _stategpostoreusernameetree
fromstringgpdbElementr9   find
SubElementattrib)selfr9   r<   db_loguser_objs        r3   __init__zgp_log.__init__i   s     nn ((0DId+DI	99>>"4t";<''		6:H&*HOOF# r2   c                    |t         j                  k(  rg| j                  j                  d| j                  z        }|j                  d      }|t        |      dk(  rt         j                  | _        y|| _        y|| _        y)a(   Policy application state
        param value         - APPLY, ENFORCE, or UNAPPLY

        The behavior of the gp_log depends on whether we are applying policy,
        enforcing policy, or unapplying policy. During an apply, old settings
        are recorded in the log. During an enforce, settings are being applied
        but the gp_log does not change. During an unapply, additions to the log
        should be ignored (since function calls to apply settings are actually
        reverting policy), but removals from the log are allowed.
        r8   applylogNr   )r&   r/   r@   rB   r9   lenr.   r;   )rE   valuerG   	apply_logs       r3   statezgp_log.state~   sf     H$$$yy~~&8499&DEH j1I C	Na$7&nn#DKr2   c                     | j                   S )zCheck the GPOSTATE
        )r;   rE   s    r3   	get_statezgp_log.get_state   s     {{r2   c                    || _         | j                  j                  d| j                  z        }|j                  d|z        }|%t	        j
                  |d      }||j                  d<   | j                  t        j                  k(  r|j                  d      }|t	        j
                  |d      }|j                  d|z        }|Dt	        j
                  |d      }dt        |      dz
  z  |j                  d	<   ||j                  d<   yyy)
z Log to a different GPO guid
        param guid          - guid value of the GPO from which we're applying
                              policy
        r8   guid[@value="%s"]NguidrL   rJ   z%dr(   count)rT   r@   rB   r9   r>   rC   rD   r;   r&   r.   rK   )rE   rT   rG   objrM   previtems          r3   set_guidzgp_log.set_guid   s    
 	99>>"4tyy"@Amm/$67;""8V4C"&CJJw;;(..( j1I !,,XzB	>>"5"<=D|''	6:'+s9~/A'BG$'+G$  )r2   c                    | j                   t        j                  k(  s| j                   t        j                  k(  ry| j                  j                  d| j                  z        }|j                  d| j                  z        }|J d       |j                  d|z        }|%t        j                  |d      }||j                  d<   |j                  d|z        }|-t        j                  |d	      }||j                  d<   ||_        yy)
a   Store an attribute in the gp_log
        param gp_ext_name   - Name of the extension applying policy
        param attribute     - The attribute being modified
        param old_val       - The value of the attribute prior to policy
                              application
        Nr8   rS   gpo guid was not setgp_ext[@name="%s"]gp_extr:   attribute[@name="%s"]	attribute)r;   r&   r0   r/   r@   rB   r9   rT   r>   rC   rD   text)rE   gp_ext_namer_   old_valrG   guid_objextattrs           r3   storezgp_log.store   s     ;;(***dkkX=M=M.M99>>"4tyy"@A==!4tyy!@A#;%;;#mm0;>?;""8X6C!,CJJvxx/);<<##C5D"+DKKDI r2   c                    | j                   j                  d| j                  z        }|j                  d| j                  z        }|J d       |j                  d|z        }|"|j                  d|z        }||j                  S y)a-   Retrieve a stored attribute from the gp_log
        param gp_ext_name   - Name of the extension which applied policy
        param attribute     - The attribute being retrieved
        return              - The value of the attribute prior to policy
                              application
        r8   rS   Nr[   r\   r^   )r@   rB   r9   rT   r`   rE   ra   r_   rG   rc   rd   re   s          r3   retrievezgp_log.retrieve   s     99>>"4tyy"@A==!4tyy!@A#;%;;#mm0;>??883i?@Dyy r2   c                 L   | j                   j                  d| j                  z        }|j                  d| j                  z        }|J d       |j                  d|z        }|9|j	                  d      }|D ci c]  }|j
                  d   |j                   c}S i S c c}w )a   Retrieve all stored attributes for this user, GPO guid, and CSE
        param gp_ext_name   - Name of the extension which applied policy
        return              - The values of the attributes prior to policy
                              application
        r8   rS   r[   r\   r_   r:   )r@   rB   r9   rT   findallrD   r`   )rE   ra   rG   rc   rd   attrsre   s          r3   retrieve_allzgp_log.retrieve_all   s     99>>"4tyy"@A==!4tyy!@A#;%;;#mm0;>??KK,E?DEtDKK'2EE	 Fs   ;!B!c                 b   g }| j                   j                  d| j                  z        }|}|j                  d      }|j|j                  d      }|D cg c]$  }|j	                  d      |j	                  d      f& }}|j                  d       |j                  d |D               |S c c}w )	z Return a list of applied ext guids
        return              - List of guids for gpos that have applied settings
                              to the system.
        r8   rJ   zguid[@count]rU   rL   T)reversec              3   &   K   | ]	  \  }}|  y wNr1   ).0rU   rT   s      r3   	<genexpr>z+gp_log.get_applied_guids.<locals>.<genexpr>   s     DkeTTDs   )r@   rB   r9   rk   getsortextend)rE   guidsrG   rM   	guid_objsgguids_by_counts          r3   get_applied_guidszgp_log.get_applied_guids   s    
 99>>"4tyy"@A j1I$%--n=	+4"6&' $%55>155>"B "6 "6##D#1D^DD	"6s   )B,c                 z   g }| j                   j                  d| j                  z        }|D ]  }|j                  d|z        }|j                  d      }i }|D ]J  }i }	|j                  d      }
|
D ]  }|j                  |	|j
                  d   <     |	||j
                  d   <   L |j                  ||f        |S )ai   Return a list of applied ext guids
        return              - List of tuples containing the guid of a gpo, then
                              a dictionary of policies and their values prior
                              policy application. These are sorted so that the
                              most recently applied settings are removed first.
        r8   rS   r]   r_   r:   )r@   rB   r9   rk   r`   rD   append)rE   rw   retrG   rT   guid_settingsextssettingsrd   	attr_dictrl   re   s               r3   get_applied_settingszgp_log.get_applied_settings   s     99>>"4tyy"@A 
	)D$MM*=*DEM ((2DH 9	K0! ?D59YYIdkk&12?/8F+,9 JJh'(
	) 
r2   c                 `   | j                   j                  d| j                  z        }|j                  d| j                  z        }|J d       |j                  d|z        }|I|j                  d|z        }|2|j	                  |       t        |      dk(  r|j	                  |       yyyy)z Remove an attribute from the gp_log
        param gp_ext_name   - name of extension from which to remove the
                              attribute
        param attribute     - attribute to remove
        r8   rS   Nr[   r\   r^   r   )r@   rB   r9   rT   removerK   rh   s          r3   deletezgp_log.delete  s     99>>"4tyy"@A==!4tyy!@A#;%;;#mm0;>??883i?@D

4 s8q=OOC( !   r2   c                     | j                   j                  | j                  t        j                  | j
                  d             y)z Write gp_log changes to disk zutf-8N)r<   rf   r=   r>   tostringr@   rP   s    r3   commitzgp_log.commit  s)    DMM5>>$))W+MNr2   rq   )r+   r,   r-   __doc__rH   rN   rQ   rY   rf   ri   rm   r{   r   r   r   r1   r2   r3   r5   r5   C   s@    $J+* ,
,* ,"",)"Or2   r5   c                   H    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)
GPOStoragec                    t         j                  j                  |      rt        j                  |      | _        y t        j                  |dt        j                  t         j                  t         j                  z        | _        y )Nr   )
ospathisfiletdbopenr   TdbDEFAULTO_CREATO_RDWR)rE   log_files     r3   rH   zGPOStorage.__init__"  sI    77>>(#xx)DHwwxCKKbii9OPDHr2   c                 8    | j                   j                          y rq   )r   transaction_startrP   s    r3   startzGPOStorage.start(  s    ""$r2   c                 |    	 t        | j                  j                  t        |                  S # t        $ r Y y w xY wrq   )intr   rt   r   	TypeErrorrE   keys     r3   get_intzGPOStorage.get_int+  s5    	txx||IcN344 		s   ,/ 	;;c                 J    | j                   j                  t        |            S rq   )r   rt   r   r   s     r3   rt   zGPOStorage.get1  s    xx||IcN++r2   c           	      `    t        || | j                  j                  t        |                  S rq   )r5   r   rt   r   )rE   r9   s     r3   	get_gplogzGPOStorage.get_gplog4  s"    dD$((,,y"?@@r2   c                 `    | j                   j                  t        |      t        |             y rq   )r   rf   r   )rE   r   vals      r3   rf   zGPOStorage.store7  s    y~y~6r2   c                 8    | j                   j                          y rq   )r   transaction_cancelrP   s    r3   cancelzGPOStorage.cancel:      ##%r2   c                 L    | j                   j                  t        |             y rq   )r   r   r   r   s     r3   r   zGPOStorage.delete=  s    	#'r2   c                 8    | j                   j                          y rq   )r   transaction_commitrP   s    r3   r   zGPOStorage.commit@  r   r2   c                 8    | j                   j                          y rq   )r   closerP   s    r3   __del__zGPOStorage.__del__C  s    r2   N)r+   r,   r-   rH   r   r   rt   r   rf   r   r   r   r   r1   r2   r3   r   r   !  s6    Q%,A7&(&r2   r   c                   \    e Zd ZeZd Zed        Zed        Zd Z	ed        Z
ed        Zy)r]   c                 Z    || _         || _        || _        |j                  |      | _        y rq   )lpcredsr=   r   gp_db)rE   r   r   r=   rf   s        r3   rH   zgp_ext.__init__J  s'    
 __X.
r2   c                      y rq   r1   )rE   deleted_gpo_listchanged_gpo_lists      r3   process_group_policyzgp_ext.process_group_policyP      r2   c                      y rq   r1   )rE   policys     r3   readzgp_ext.readT  r   r2   c                    | j                   j                  d      }t        j                  j	                  |t        |      j                               }t        j                  j                  |      r| j                  |      S y )N	gpo_cache)	r   
cache_pathr   r   joincheck_safe_pathupperexistsr   )rE   afile
local_path	data_files       r3   parsezgp_ext.parseX  sZ    WW''4
GGLL_U-C-I-I-KL	77>>)$99Y''r2   c                      y rq   r1   rP   s    r3   __str__zgp_ext.__str___  r   r2   c                     i S rq   r1   )rE   gpos     r3   rsopzgp_ext.rsopc  s    	r2   N)r+   r,   r-   r   __metaclass__rH   r	   r   r   r   r   r   r1   r2   r3   r]   r]   G  sa    M/        r2   r]   c                       e Zd Zd Zy)
gp_inf_extc                 ,   t        |d      j                         }t        d       }t        |_        	 |j                  t        |j                                      |S # t        $ r- |j                  t        |j                  d                   Y |S w xY w)Nrbinterpolationutf-16)	r   r   r   stroptionxform	read_filer   decodeUnicodeDecodeError)rE   r   r   inf_confs       r3   r   zgp_inf_ext.readi  s    i&++-d3"	Bx89  " 	Bxh(?@A	Bs   (A 2BBNr+   r,   r-   r   r1   r2   r3   r   r   h  s    r2   r   c                       e Zd Zd Zy)
gp_pol_extc                 j    t        |d      j                         }t        t        j                  |      S )Nr   )r   r   r   r   filerE   r   raws      r3   r   zgp_pol_ext.readu  s(    9d#((*$))S))r2   Nr   r1   r2   r3   r   r   t  s    *r2   r   c                       e Zd Zd Zy)
gp_xml_extc                     t        |d      j                         }	 t        j                  |j	                               S # t
        $ r' t        j                  |j	                  d            cY S w xY w)Nr   r   )r   r   r>   r?   r   r   r   s      r3   r   zgp_xml_ext.read{  s\    9d#((*	:##CJJL11! 	:##CJJx$899	:s   "? -A/.A/Nr   r1   r2   r3   r   r   z  s    :r2   r   c                   f    e Zd ZdZeZd Zd Zd Zd Z	d Z
d Zd Zed	        Zed
        ZddZy)
gp_applierzGroup Policy Applier/Unapplier/Modifier
    The applier defines functions for monitoring policy application,
    removal, and modification. It must be a multi-derived class paired
    with a subclass of gp_ext.
    c                     | j                   j                  |       | j                   j                  t        |       ||       | j                   j	                          y)aL  Add an attribute and value to the Group Policy cache
        guid        - The GPO guid which applies this policy
        attribute   - The attribute name of the policy being applied
        value       - The value of the policy being applied

        Normally called by the subclass apply() function after applying policy.
        N)r   rY   rf   r   r   rE   rT   r_   rL   s       r3   cache_add_attributezgp_applier.cache_add_attribute  s@     	

D!

TIu5

r2   c                     | j                   j                  |       | j                   j                  t        |       |       | j                   j	                          y)a  Remove an attribute from the Group Policy cache
        guid        - The GPO guid which applies this policy
        attribute   - The attribute name of the policy being unapplied

        Normally called by the subclass unapply() function when removing old
        policy.
        N)r   rY   r   r   r   rE   rT   r_   s      r3   cache_remove_attributez!gp_applier.cache_remove_attribute  s>     	

D!

#d)Y/

r2   c                     | j                   j                  |       | j                   j                  t        |       |      S )zRetrieve the value stored in the cache for the given attribute
        guid        - The GPO guid which applies this policy
        attribute   - The attribute name of the policy
        )r   rY   ri   r   r   s      r3   cache_get_attribute_valuez$gp_applier.cache_get_attribute_value  s1    
 	

D!zz""3t9i88r2   c                     | j                   j                  |       | j                   j                  t        |             S )zRetrieve all attribute/values currently stored for this gpo+policy
        guid        - The GPO guid which applies this policy
        )r   rY   rm   r   )rE   rT   s     r3   cache_get_all_attribute_valuesz)gp_applier.cache_get_all_attribute_values  s/     	

D!zz&&s4y11r2   c                 6    | j                   j                         S )zSReturn the current apply state
        return      - APPLY|ENFORCE|UNAPPLY
        )r   rQ   rP   s    r3   cache_get_apply_statez gp_applier.cache_get_apply_state  s     zz##%%r2   c                     dj                  g |D cg c]  }t        |       c}      }t        t        |      |z         j                         S c c}w )a"  Generate an attribute name from arbitrary data
        name            - A name to ensure uniqueness
        args            - Any arbitrary set of args, str or bytes
        return          - A blake2b digest of the data, the attribute

        The importance here is the digest of the data makes the attribute
        reproducible and uniquely identifies it. Hashing the name with
        the data ensures we don't falsely identify a match which is the same
        text in a different file. Using this attribute generator is optional.
        r2   r   r   r   	hexdigest)rE   r:   argsargdatas        r3   generate_attributezgp_applier.generate_attribute  sG     xx7T7;C3;<yt+,6688 <s   Ac                     dj                  g |D cg c]  }t        |       c}      }t        |      j                         S c c}w )zGenerate a unique value which identifies value changes
        args            - Any arbitrary set of args, str or bytes
        return          - A blake2b digest of the data, the value represented
        r2   r   )rE   r   r   r   s       r3   generate_value_hashzgp_applier.generate_value_hash  s=    
 xx7T7;C3;<t}&&(( <s   Ac                      y)zGroup Policy Unapply
        guid            - The GPO guid which applies this policy
        attribute       - The attribute name of the policy being unapplied
        value           - The value of the policy being unapplied
        Nr1   r   s       r3   unapplyzgp_applier.unapply  s     	r2   c                      y)a  Group Policy Apply
        guid            - The GPO guid which applies this policy
        attribute       - The attribute name of the policy being applied
        applier_func    - An applier function which takes variable args
        args            - The variable arguments to pass to applier_func

        The applier_func function MUST return the value of the policy being
        applied. It's important that implementations of `apply` check for and
        first unapply any changed policy. See for example calls to
        `cache_get_all_attribute_values()` which searches for all policies
        applied by this GPO for this Client Side Extension (CSE).
        Nr1   )rE   rT   r_   applier_funcr   s        r3   applyzgp_applier.apply  s     	r2   Nc                 V   |g }|g }t        |      t        k7  r+| j                  ||      }| | j                  |||fi | yy| j	                  |      }|j                         D ]@  \  }}t        |      dkD  r||v st        |      dkD  s'||vs, | j                  |||fi | B y)al  Cleanup old removed attributes
        keep    - A list of attributes to keep
        remove  - A single attribute to remove, or a list of attributes to
                  remove
        kwargs  - Additional keyword args required by the subclass unapply
                  function

        This is only necessary for CSEs which provide multiple attributes.
        Nr   )typelistr   r   r   itemsrK   )rE   rT   keepr   kwargsrL   old_valsr_   s           r3   cleanzgp_applier.clean  s     <D>F<4224@E T65;F; ! ::4@H$,NN$4 C 	5K!O	V(;IMit&; DLLy%B6BCr2   )NN)r+   r,   r-   r   r   r   r   r   r   r   r   r   r   r	   r   r   r  r1   r2   r3   r   r     s_    
 M

92&9)    Cr2   r   c                   0    e Zd ZdZd Zd Zd	dZdddZy)
gp_file_applierzGroup Policy File Applier/Unapplier/Modifier
    Subclass of abstract class gp_applier for monitoring policy applied
    via a file.
    c                 L    |g}|j                  |       |j                  |      S rq   )rv   r   )rE   
value_hashfilessepr   s        r3   __generate_valuez gp_file_applier.__generate_value
  s#    |Exx~r2   c                 |    |dg fS |j                  |      }d|d   v rd|fS |d   t        |      dkD  r|dd fS g fS )zYParse a value
        return          - A unique HASH, followed by the file list
        N/r   r(   )splitrK   )rE   rL   r  r   s       r3   __parse_valuezgp_file_applier.__parse_value  s^     =8O{{3$q'> :7D	ADH==2==r2   :c                     t        |      t        k7  r| j                  ||      \  }}|D ]7  }t        j                  j                  |      s#t        j                  |       9 | j                  ||       y rq   )r  r  _gp_file_applier__parse_valuer   r   r   unlinkr   )rE   rT   r_   r  r  _r   s          r3   r   zgp_file_applier.unapply  s`    ;$))%5HAu 	 Dww~~d#		$	  	##D)4r2   )r  c                   | j                  ||      }| j                  ||      \  }}	||k7  sW| j                         t        j                  k(  s6t        |	D 
cg c]!  }
t        j                  j                  |
      # c}
      s| j                  |||	       ny || }| j                  |||      }| j                  |||       yc c}
w )a(  
        applier_func MUST return a list of files created by the applier.

        This applier is for policies which only apply to a single file (with
        a couple small exceptions). This applier will remove any policy applied
        by this GPO which doesn't match the new policy.
        N)r   r  r   r&   r/   allr   r   r   r    _gp_file_applier__generate_valuer   )rE   rT   r_   r  r   r  r   rb   old_val_hashold_val_filesfr  	new_values                r3   r   zgp_file_applier.apply&  s     00yA&*&8&8#&F#mJ&**,0@0@@MBq*BCLLy-8  d#))*eSA	  y)< Cs   &CN)r  )r+   r,   r-   r   r  r  r   r   r1   r2   r3   r
  r
    s"    

>5 KN =r2   r
  c                     t        | |      }|j                  |j                  d      t        j                  t        j
                  z        }|j                  S N)r   r   realm)domainflags)r
   finddcrt   r   NBT_SERVER_LDAPNBT_SERVER_DSpdc_dns_namer   r   net	cldap_rets       r3   get_dc_hostnamer,  C  sL    
Eb
!C

"&&/#:M:M:=:K:K;L
 NI!!!r2   c                     t        | |      }|j                  |j                  d      t        j                  t        j
                  z        }|j                  S r!  )r
   r%  rt   r   r&  r'  pdc_namer)  s       r3   get_dc_netbios_hostnamer/  I  sL    
Eb
!C

"&&/#:M:M:=:K:K;L
 NIr2   c                 <   t        j                         }g d}|j                  d      r|j                  d      }t        j
                  t        j                  z  t        j                  z  }	 | j                  |t        j                  d|d|z  g      }|j                  dk7  r$t        j                  t        j                   d      ||_        d	|j$                  d
   j'                         v r#t)        |j$                  d
   d	   d
         |_        d|j$                  d
   j'                         v r#t)        |j$                  d
   d   d
         |_        d|j$                  d
   j'                         v r(|j$                  d
   d   d
   j/                         |_        d|j$                  d
   j'                         v r(|j$                  d
   d   d
   j/                         |_        d|j$                  d
   j'                         v r(|j$                  d
   d   d
   j/                         |_        d|j$                  d
   j'                         v r#t7        |j$                  d
   d   d
         |_        d|j$                  d
   j'                         v r#t7        |j$                  d
   d   d
         |_        d|j$                  d
   j'                         v r-|j=                  t?        |j$                  d
   d   d
                |S # t        $ r t        j                  d        w xY w)N)cndisplayNamer$  gPCFileSysPathgPCFunctionalityVersiongPCMachineExtensionNamesgPCUserExtensionNamesgPCWQLFilterr:   nTSecurityDescriptorversionNumberzLDAP://(objectclass=*)zsd_flags:1:%d)controlsz4Failed to fetch gpo object with nTSecurityDescriptorr(   zget_gpo: search failedr9  r   r$  r3  r2  r:   r5  r6  r8  ) r   GROUP_POLICY_OBJECT
startswithlstripr#   SECINFO_OWNERSECINFO_GROUPSECINFO_DACLsearchldb
SCOPE_BASE	Exceptionr   errorrU   LdbErrorERR_NO_SUCH_OBJECTds_pathmsgskeysr   versionoptionsr   file_sys_pathdisplay_namer:   r   machine_extensionsuser_extensionsset_sec_descbytes)samdbgpo_dnry   rl   sd_flagsress         r3   get_gporX  S  s   !AE #y)&&&&'%%&Hll63>>3De%4x%?$@  B
 yyA~ll31135 	5 AI#((1+**,,O4Q78	#((1+""$$G,Q/0	388A;++--((1+&67:AAC((**!]3A6==?!!!##!V$Q'..0!SXXa[%5%5%77"388A;/I#J1#MN#((1+"2"2"44,C DQ GH!!1!1!33	uSXXa[)?@CDEH1  		HIs   .(K; ; Lc                       e Zd Zd Zd Zd Zy)GP_LINKc                 b    g | _         g | _        | j                  |       t        |      | _        y rq   )
link_names	link_optsgpo_parse_gplinkr   gp_opts)rE   gPLink	gPOptionss      r3   rH   zGP_LINK.__init__  s)    f%9~r2   c                    |j                         j                  d      D ]  }|st        j                  d       |j	                  d      }|j                  d      \  }}t        j                  dj                  |             t        j                  dj                  |             | j                  j                  |       | j                  j                  t        |              y )N]z!gpo_parse_gplink: processing link[;zgpo_parse_gplink: link: {}zgpo_parse_gplink: opt: {})
r   r  r   debugr>  formatr\  r}   r]  r   )rE   r`  p	link_namelink_opts        r3   r^  zGP_LINK.gpo_parse_gplink  s    &&s+ 		1AII9:A"#''#,IxII299)DEII188BCOO""9-NN!!#h-0		1r2   c                     t        | j                        t        | j                        k7  rt        d      t        | j                        S )NzLink names and opts mismatch)rK   r\  r]  RuntimeErrorrP   s    r3   	num_linkszGP_LINK.num_links  s7    t3t~~#66=>>4??##r2   N)r+   r,   r-   rH   r^  rm  r1   r2   r3   rZ  rZ    s    &
1$r2   rZ  c                    ddg}| j                  | j                         t        j                  dj	                  |      |      }|j
                  dk7  r3t        j                  t        j                  dj	                  |            t        |j                  d   d   d         }|j                  d   d   }t        j                  dj	                  ||             ||fS )NdnuserAccountControlz(sAMAccountName={})r(   z"Failed to find samAccountName '{}'r   z!Found dn {} for samaccountname {})rB  get_default_basednrC  SCOPE_SUBTREErg  rU   rG  rH  r   rJ  r   info)rT  samaccountnamerl   rW  uacro  s         r3   find_samaccountrv    s    '(E
,,u//133D3D,33NCULC
yyA~ll311077G
 	
 chhqk./2
3C	!T	BHH077NKL7Nr2   c                    | j                  |t        j                  dddg      }|j                  dk7  r$t        j                  t        j
                  d      d|j                  d   vr3t        j                  t        j                  dj                  |            |j                  d   d   d   }d}d|j                  d   v r|j                  d   d   d   }nt        j                  d       t        ||      S )	Nr:  r`  ra  r(   zget_gpo_link: no resultr   z2get_gpo_link: no 'gPLink' attribute found for '{}'z,get_gpo_link: no 'gPOptions' attribute found)rB  rC  rD  rU   rG  rH  rJ  ERR_NO_SUCH_ATTRIBUTErg  r   rf  rZ  )rT  link_dnrW  r`  ra  s        r3   get_gpo_linkrz    s    
,,w(8[*ACC
yyA~ll3113LMMsxx{"ll344@GGP
 	
 XXa["1%FIchhqk!HHQK,Q/			@A69%%r2   c                    t        |j                         dz
  dd      D ]p  }|j                  |   t        z  dk7  }	|j                  |   t        z  rt        j                  d       I|r-|	st        j                  d       ct        j                  d       	 t        | |j                  |         }
	 t        t        j                  |
j                               }t        j                  j                  ||t        j                  t        j                   z  t        j"                  z         t)        |      |
_        ||
_        |	r|j/                  d|
       n|j/                  d|
       t        j                  d||j                  |   fz         s y # t$        $ r-}t        j                  d|
j&                  z         Y d }~d }~ww xY w# t0        j2                  $ r}}|j4                  \  }}t        j                  d	|j                  |   z         |t0        j6                  k(  r+t        j                  d
|j                  |   z         Y d }~3Y d }~ y d }~ww xY w)Nr(   r   zskipping disabled GPOzNskipping nonenforced GPO link because GPOPTIONS_BLOCK_INHERITANCE has been setzNadding enforced GPO link although the GPOPTIONS_BLOCK_INHERITANCE has been setz/skipping GPO "%s" as object has no access to itz7add_gplink_to_gpo_list: added GPLINK #%d %s to GPO listzfailed to get gpo: %szskipping empty gpo: %s)rangerm  r]  r   r   r   rf  rX  r\  r   r#   
descriptorget_sec_desc_bufsambaaccess_checkSEC_STD_READ_CONTROLSEC_ADS_LISTSEC_ADS_READ_PROPrE  rO  r   link	link_typeinsertrC  rG  r   rH  )rT  gpo_listforced_gpo_listry  gp_linkr  only_add_forced_gpostokeni	is_forcednew_gposec_desceenumestrs                  r3   add_gplink_to_gpo_listr    s   7$$&q("b1 0B&&q),>>1D	Q"44II-.		 ) * 		 ) *	BeW%7%7%:;G
%h&9&9&-&>&>&@B++He,4,I,I,4,A,A-B,4,F,F-GH w<GL )G&&q'27+II $'('*<*<Q*?&@A B_0BD  		 0292F2FG H || 	66LT4II-0B0B10EEFs---		2W5G5G5JJK	s2   G2A9F	G
"GG
I A,IIc                     | j                   }|j                  |j                          || _         | xj                  |j                  z  c_        | xj                  |j                  z  c_        | S rq   )sidsrv   rights_maskprivilege_mask)token_1token_2r  s      r3   merge_nt_tokenr    sU    <<DKKGL7...g444Nr2   c                    | j                         }	 t        j                  d|z  ||      }|j                  |      }dj                  ||      S # t        $ r t        ||      }| j                  |t        j                  d|z  dg      }	|	j                  dk7  r$t        j                  t        j                  d      |	j                  d   d   }
|
j                         j                         }|cY S w xY w)Nzncacn_np:%s[seal]zCN={},CN=Sites,{}z(cn=%s)ro  r(   zsite_dn_for_machine: no resultr   )get_config_basednr$   netr_DsRGetSiteNamerg  r   r/  rB  rC  rr  rU   rG  rH  rJ  parent)rT  dc_hostnamer   r   hostnameconfig_contextc	site_namenb_hostnamerW  ro  site_dns               r3   site_dn_for_machiner    s    ,,.N1K?UK))(3	")))^DD 
-eR8ll>3+<+<${2TF<99>,,s55?A AXXa[))+$$&
s   <A B C21C2c           
         g }g }d| z   }t        |t               ||      }t        ||j                  d      d         \  }}	d}
t        t
        z  }|j                  d      r	|t        z  }t        j                  j                  |||	|      }d}|t        z  s	|t        z  r+d}t        |j                  t               j                        }n|j                  }|	j                         }	 t!        |      t!        |j#                         j                               k(  rn|j%                  d	      d
k(  r[	 t'        j(                  d|z         t+        ||      }t-        |||||t.        j0                  |
|       |j2                  t4        z  rd}
	 |j                         }|	j                         }	 t!        |      t!        |j#                         j                               k(  rn|j%                  d	      dk(  r[	 t'        j(                  d|z         t+        ||      }t-        |||||t.        j<                  |
|       |j2                  t4        z  rd}
	 |j                         }|rU	 t?        || |||      }	 t'        j(                  d|z         t+        ||      }t-        |||||t.        j@                  |
|       |jC                  d	t/        jD                  ddt.        jF                               ||z   S # t6        j8                  $ r/}|j:                  \  }}t'        j(                  |       Y d}~d}~ww xY w# t6        j8                  $ r/}|j:                  \  }}t'        j(                  |       Y d}~$d}~ww xY w# t6        j8                  $ r/}|j:                  \  }}t'        j(                  |       Y d}~d}~ww xY w# t6        j8                  $ r Y w xY w)a3  Get the full list of GROUP_POLICY_OBJECTs for a given username.
    Push GPOs to gpo_list so that the traversal order of the list matches
    the order of application:
    (L)ocal (S)ite (D)omain (O)rganizational(U)nit
    For different domains and OUs: parent-to-child.
    Within same level of domains and OUs: Link order.
    Since GPOs are pushed to the front of gpo_list, GPOs have to be
    pushed in the opposite order of application (OUs first, local last,
    child-to-parent).
    Forced GPOs are appended in the end since they override all others.
    zldap://)urlsession_infocredentialsr   \r|  Fldap)lp_ctxro  session_info_flagsTr   OUz%get_gpo_list: query OU: [%s] for GPOsNDCz%get_gpo_list: query DC: [%s] for GPOsz'get_gpo_list: query SITE: [%s] for GPOsLocal Policy)$r   r   rv  r  r    r!   r=  r"   r  authuser_sessionr   r   r  security_tokenr  r   rq  get_component_namer   rf  rz  r  r   
GP_LINK_OUr_  r   rC  rG  r   GP_LINK_DOMAINr  GP_LINK_SITEr  r<  GP_LINK_LOCAL)r  r   r   r=   r  r  r  rT  ru  ro  add_only_forced_gposr  sessiongpo_list_machiner  	parent_dnr  r  r  r  r  s                        r3   get_gpo_listr  
  s    HO
k
!Cc-/#,E eX^^D%9"%=>GC  ;9:
~~fAAjj%%eB29K & MG
))S3J-Jw55-/>>@ && 		I
y>S!9!9!;!B!B!DEE ''*d20		AIMN&ui8
 'uh'0''*~~';UD ??%::+/($$&	- 2 		I
y>S!9!9!;!B!B!DEE ''*d20		AIMN&ui8
 'uh'0''*'9'9';UD ??%::+/($$&	- 2 	)%b%RG
D		CgMN&ug6
 'uh'.'*'7'7';UD OOAs..~/=/2/@/@B C O##M <<   vvt		$ 4 <<   vvt		$ . <<   vvt		$  || 	 		sl   3$K4 8$L9 &O 6$M>  O 4L6$L11L69M;$M66M;>O $N;5O ;O  O OOc           
      :   |j                         }t        j                  j                  ||      }	 t        j                  |d       | j                  |      D ]	  }|d   t        j                  z  r/t        | |t        j                  j                  ||d                I|d   j                         }t        d|      }t        j                  j                  ||d         j                  dd      }	|j                  | j                  |	             |j!                          t        j"                  |j$                  t        j                  j                  ||              y # t
        $ r)}|j                  t        j                  k7  r Y d }~Ld }~ww xY w)	Ni  )moderD   r:   F)r   dirr  r  )r   r   r   r   makedirsOSErrorerrnoEEXISTr  libsmbFILE_ATTRIBUTE_DIRECTORYcache_gpo_dirr   replacewriteloadfiler   renamer:   )
conncachesub_dirloc_sub_dir	local_dirr  fdata
local_namer  fnames
             r3   r  r    s-   --/KUK0I
IE* 7# 	C?V<<<$rww||GU6]'KLv,,.J"%Y?AGGLL%-8@@dKEGGDMM%()GGIIIaffbggll9jAB	C  77ell" #s   E( (	F1FFc                    t        j                  d|       }d| j                         v r;t        j                  d| j                               }||j                  d      dz   d  }d|vrt	        j
                  j                  | S t        |       )Nz/|\\sysvolr(   z..)rer  lowerindexr   r   r   r  )r   dirsldirss      r3   r   r     sv    88Hd#D4::<4::<0EKK)A-./4ww||T""
$-r2   c                 ,   |j                         }|j                  t               t        j                  | d||      }|j                  |       |j                  d      }|D ]/  }|j                  st        ||t        |j                               1 y )Nr  )r   r   r   )	get_smb_signingset_smb_signingr   r  Connr   rN  r  r   )r  r   r   gpossaved_signing_stater  r   gpo_objs           r3   check_refresh_gpo_listr    s    //1	./;;{H5AD	-.{+J P$$dJ8M8M(NOPr2   c                     | j                         }t        |D cg c]  }|j                   c}      }|D cg c]	  }||vs| }}| j                  |      S c c}w c c}w rq   )r{   setr:   r   )r   r  applied_gposrh  current_guidsrT   deleted_gposs          r3   get_deleted_gpos_listr    s\    **,L.A./M%1OTT5NDOLO%%l33 /Os   A	AAc                     | j                  t        j                  j                  d|            }t	        t        j                  |      d         S )Nr   r(   )r   r   r   r   r   r   gpo_get_sysvol_gpt_version)r   r   gpt_paths      r3   gpo_versionr    s<     }}RWW\\+t<=Hs--h7:;;r2   c                 J   |j                  |      }t        ||       }t        ||| |      }	t        ||	      }
	 t	        || ||	       |r"|	}|j                  t        j                         ng }|	D ]  }|j                  s|j                  }t        |j                        j                         }t        | |      }||j                  |      k7  s`t        j                   d|z         |j#                  |        |j                  t        j$                         |j'                          |D ]>  }	  || |||      }|dk(  r|j)                  |
|       nt+        ||j(                  |
|       @ |	D ]_  }|j                  s|j                  }t        |j                        j                         }t        | |      }|j=                  |d|z         a |j?                          y #  t        j                  d|z         Y y xY w# t,        $ r}t        j                  dt/        |      z         t1        j2                         \  }}}t5        j6                  |      d   \  }}}}t        j                  d||t9        |      j:                  t/        |      fz         Y d }~rd }~ww xY w)Nz0Failed downloading gpt cache from '%s' using SMBzGPO %s has changedComputerzFailed to apply extension  %sr|  z%s:%d: %s: %sz%i) r   r,  r  r  r  r   rF  rN   r&   r/   rN  r:   r   r   r  r   rs  r}   r.   r   r   drop_privilegesrE  r   sysexc_info	traceback
extract_tbr  r+   rf   r   )r   r   rf   gp_extensionsr=   targetforcer   r  r  del_gposchanged_gposr  rT   r   rL  rd   r  r  tbfilenameline_numbers                         r3   apply_gpr    sj   OOH%E!%,KUB9D$UD1H{Bt< H$$% 	-G((<<D"7#8#89??AD!"d+G%-----45##G,	- 	HNN#	KKM 	b%51C#((<@#*B*B (,8  *$$||w445;;=b$'D$.)* 
LLNY		F  	!6  	II5C@A||~HAq"*3*>*>r*B2*F'Hk1aIIo;)-a)9)93q6)C C D	s$   G! /;H !G= 	J"	BJJ"c                    |j                  |      }|j                  t        j                         |j	                  |j                               }|j                          |D ]>  }	  || |||      }|dk(  r|j                  |g        nt        ||j                  |g        @ |j                          y # t        $ rL}	t        j                  dt        |      z         t        j                  dt        |	      z          Y d }	~	d }	~	ww xY w)Nr  zFailed to unapply extension  %szMessage was: )r   rN   r&   r0   r   r{   r   r   r  rE  r   rF  r   r   )
r   r   rf   r  r=   r  r   r  rd   r  s
             r3   
unapply_gpr     s    OOH%E	KK  !))%*A*A*CDH	KKM 
	b%51C#((26#*B*B (". 
LLN	  	II7#c(BCIIoA./	s   &;B44	D	=ADD	c                    t        |       t        k(  rO| j                         D cg c]   \  }}d|z  d|dt        ||dz         z   " }}}ddj	                  |      z   S t        |       t
        k(  r9| D cg c]  }d|z  dt        ||dz         z  z    }}ddj	                  |      z   S t        | t        j                        rd|dz   z  t        |       z   S d|dz   z  t        |       z   S c c}}w c c}w )N z[ z ] = r)   
z[ %s ])r  dictr  __rsop_valsr   r  
isinstancenumbersNumberr   r   )valslevelkvr~   s        r3   r  r    s    DzT JJL*Aq 5yA{1eAg/FGG * *diin$$	dt	GKL!s5y8k!U1W&===LLdiin$$dGNN+a=3t9,,a=:d#333* Ms   %C/8C5c                 (   t        ||       }t        ||| |      }t        || ||       t        d       t        d|z         t	        j
                  d      d   }|D ]  }	|	j                  j                         dk(  r"t        d|	j                  z         t        d|z         |D ]T  }
 |
| |||      }
t        j                  d	t        t        |
                  }t        |      dkD  r|d
   j                  d      d
   }n|
j                  j                  d      d
   }t        d|z         t        ddt        |dz        z  z          |
j!                  |	      j#                         D ]p  \  }}t        d|z         t        ddt        |dz        z  z          t        t%        |      j'                  d             t        ddt        |dz        z  z          r t        ddt        |dz        z  z          W t        dd|z  z          y )NzResultant Set of Policyz
%s Policy
)x   2   )fallbackr   r  zGPO: %s=z'([\w\.]+)'r|  .z	  CSE: %sz  -r)   z    Policy Type: %sz    r  z%s
)r,  r  r  printshutilget_terminal_sizerO  stripr  rk   r   r  rK   r  r,   r   r   r  r  r>  )r   r   rf   r  r=   r  r  r  
term_widthr  rd   
cse_name_mcse_namesectionr   s                  r3   r   r     s   !%,KUB9D;E48	
#$	-&
 !))9=a@J )%%'>9i'.../c*n  	2Cb%51CNCS	NCJ:"%b>//4R8>>//4R8+()$#c*Q,//01%(XXg%6%<%<%> 8!+g56fC
1$5 567k(+22489fC
1$5 567	8
 $#c*Q,//01	2 	fJ'())r2   c                     ddl m} |j                         }| |j                  |        n|j	                          |j                  d      }t        d       }|j                  |       ||fS )Nr   )param
gpext.confr   )samba.samba3r  get_contextloadload_default
state_pathr   r   )smb_confs3paramr   ext_confparsers        r3   parse_gpext_confr(  4  s]    -				B

}}\*H-F
KKv:r2   c                    | j                  d      }t        ddt        j                  j	                  |            5 }|j                  |       t        j                  |j                  |       d d d        y # 1 sw Y   y xY w)Nr  zw+F)r  r   r  )r#  r   r   r   dirnamer  r  r:   )r   r'  r&  r  s       r3   atomic_write_confr+  A  s^    }}\*H	e9R	S $WXQ
		!&&(#$ $ $s   2A88Bc                 |    | d   dk7  s| d   dk7  st        |       dk7  ry	 t        | d       y	# t        $ r Y yw xY w)
Nr   {r|  }&   F   )rL  T)rK   r   
ValueError)rT   s    r3   
check_guidr2  H  sL    Aw#~bSCIOT1   s   / 	;;c                 ~   t         j                  j                  |      syt        |       syt	        |      \  }}| |j                         vr|j                  |        |j                  | d|       |j                  | d|       |j                  | d|rdnd       |j                  | d|rdnd       t        ||       y)	NFDllNameProcessGroupPolicyNoMachinePolicy01NoUserPolicyT)	r   r   r   r2  r(  sectionsadd_sectionr  r+  )rT   r:   r   r$  machiner9   r   r'  s           r3   register_gp_extensionr=  S  s     77>>$d!(+JB6??$$4 
JJtY%
JJt)40
JJt&wC@
JJt^DSc:b&!r2   c                 B   t        |       \  }}i }|j                         D ]{  }i ||<   |j                  |d      ||   d<   |j                  |d      ||   d<   t        |j                  |d             ||   d<   t        |j                  |d             ||   d<   } |S )Nr4  r5  r6  MachinePolicyr9  
UserPolicy)r(  r:  rt   r   )r$  r  r'  resultsrT   s        r3   list_gp_extensionsrB  h  s     *IAvG! P#)::dI#>i JJt12 	*+ FJJt%6788 	o&*-fjj~.N*O&Ol#P Nr2   c                     t        |       syt        |      \  }}| |j                         v r|j                  |        t	        ||       y)NFT)r2  r(  r:  remove_sectionr+  )rT   r$  r   r'  s       r3   unregister_gp_extensionrE  v  sE    d!(+JBv  d#b&!r2   c                 X    t        j                  |       t        j                  |       y)z(
    Set current process privileges
    N)r   setegidseteuid)r=   uidgids      r3   set_privilegesrK    s    
 JJsOJJsOr2   c                 J   t        j                         }|dk(  st        d      t        j                  |       j
                  }t        j                  |       j                  }t        | ||       d}d}	  || }t        d|d       |r||S # t        $ r}|}Y d}~#d}~ww xY w)zG
    Run supplied function with privileges for specified username.
    r   z)Not enough permissions to drop privilegesNroot)r   getuidrE  pwdgetpwnampw_uidpw_gidrK  )	r=   funcr   current_uiduser_uiduser_gidoutexcr  s	            r3   r  r    s     ))+K!CDD||H%,,H||H%,,H 8Xx0 C
CDk
 6;*
	J  s   5B 	B"BB")F)r0  )NTTrq   )or  r   r  r  r   rO  r   r  r  r   r   configparserr   ior   r  samba.commonr   abcr   r	   xml.etree.ElementTreer>   ElementTreer  	samba.netr
   samba.dcerpcr   r  r   r  	samba.gpor   samba.paramr   uuidr   tempfiler   r   r   	samba.ndrr   r   samba.credentialsr   samba.gp.util.loggingr   hashlibr   r  r   samba.samdbr   
samba.authr   rC  
samba.dsdbr   r   r   r   r   r   r    r!   r"   r#   samba.securityr$   r  r%   r&   ImportErrorr5   r   objectr]   r   r   r   r   r
  r,  r/  rX  rZ  rv  rz  r  r  r  r  r  r   r  r  r  r  r   r  r   r(  r+  r2  r=  rB  rE  rK  r  r1   r2   r3   <module>ro     s  $    
 
 <   , %   " ' % % 	   8     '   * 2 %   #  % 
 Y  Y } } !  !J 78H[O [O|# #LV B	 	* *: :~C ~CB9=j 9=x ," 20d$ $0&"2Bh&v$rC(P4<3l*4)>
$ =A*
a"   s   =G GG