a
    W×aíN  ã                   @   s.  d dl Z d dlZd dlZd dlZe j d d¡ 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  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% d dl&m'Z'm(Z( zd dl)m*Z* e*ddƒZ+W n" e,yL   G dd„ dƒZ+Y n0 G dd„ dƒZ-G dd„ dƒZ.G dd„ de/ƒZ0G dd„ de/ƒZ1G dd„ de0ƒZ2G d d!„ d!e0ƒZ3d"d#„ Z4d$d%„ Z5d&d'„ Z6d(d)„ Z7d*d+„ Z8d,d-„ Z9d.d/„ Z:dBd1d2„Z;d3d4„ Z<d5d6„ Z=d7d8„ Z>d9d:„ Z?dCd<d=„Z@dDd>d?„ZAdEd@dA„ZBdS )Fé    Nz
bin/python)ÚNTSTATUSError)ÚConfigParser)ÚStringIO)Ú	get_bytes)ÚABCMetaÚabstractmethod)ÚNet)Únbt)Úlibsmb_samba_internal)Úparam)ÚLoadParm)ÚUUID)ÚNamedTemporaryFile)Úpreg)Úmisc)Úndr_packÚ
ndr_unpack)ÚEnumÚGPOSTATEzAPPLY ENFORCE UNAPPLYc                   @   s   e Zd ZdZdZdZdS )r   é   é   é   N)Ú__name__Ú
__module__Ú__qualname__ÚAPPLYÚENFORCEÚUNAPPLY© r   r   ú//usr/lib/python3/dist-packages/samba/gpclass.pyr   .   s   c                   @   sZ   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú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                 C   sl   t j| _|| _|| _|r&t |¡| _nt d¡| _|| _	| j 
d| ¡}|du rht | jd¡}||jd< dS )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
        Zgpúuser[@name="%s"]NÚuserÚname)r   r   Ú_stateÚgpostoreÚusernameÚetreeZ
fromstringÚgpdbZElementr"   ÚfindÚ
SubElementÚattrib)Úselfr"   r%   Zdb_logÚuser_objr   r   r   Ú__init__Z   s    zgp_log.__init__c                 C   sV   |t jkrL| j d| j ¡}| d¡}|du s:t|ƒdkrDt j| _qR|| _n|| _dS )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.
        r!   ÚapplylogNr   )r   r   r(   r)   r"   Úlenr   r$   )r,   Úvaluer-   Ú	apply_logr   r   r   Ústateo   s    


zgp_log.statec                 C   s´   || _ | j d| j ¡}| d| ¡}|du rDt |d¡}||jd< | jtj	kr°| d¡}|du rnt |d¡}| d| ¡}|du r°t |d¡}dt
|ƒd  |jd	< ||jd< dS )
z˜ Log to a different GPO guid
        param guid          - guid value of the GPO from which we're applying
                              policy
        r!   úguid[@value="%s"]NÚguidr1   r/   z%dr   Úcount)r5   r(   r)   r"   r'   r*   r+   r$   r   r   r0   )r,   r5   r-   Úobjr2   ÚprevÚitemr   r   r   Úset_guid…   s    

zgp_log.set_guidc                 C   s°   | j tjks| j tjkrdS | j d| j ¡}| d| j ¡}|dusNJ dƒ‚| d| ¡}|du rzt 	|d¡}||j
d< | d| ¡}|du r¬t 	|d	¡}||j
d< ||_dS )
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
        Nr!   r4   úgpo guid was not setúgp_ext[@name="%s"]Úgp_extr#   úattribute[@name="%s"]Ú	attribute)r$   r   r   r   r(   r)   r"   r5   r'   r*   r+   Útext)r,   Úgp_ext_namer?   Zold_valr-   Úguid_objÚextÚattrr   r   r   Ústoreš   s    

zgp_log.storec                 C   sh   | j  d| j ¡}| d| j ¡}|dus2J dƒ‚| d| ¡}|durd| d| ¡}|durd|jS dS )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
        r!   r4   Nr;   r<   r>   )r(   r)   r"   r5   r@   ©r,   rA   r?   r-   rB   rC   rD   r   r   r   Úretrieve°   s    zgp_log.retrievec                 C   sl   g }| j  d| j ¡}|durh| d¡}|durh| d¡}dd„ |D ƒ}|jdd | d	d
„ |D ƒ¡ |S )z© Return a list of applied ext guids
        return              - List of guids for gpos that have applied settings
                              to the system.
        r!   Nr/   zguid[@count]c                 S   s    g | ]}|  d ¡|  d¡f‘qS )r6   r1   )Úget)Ú.0Úgr   r   r   Ú
<listcomp>Ì   s   ÿz,gp_log.get_applied_guids.<locals>.<listcomp>T)Úreversec                 s   s   | ]\}}|V  qd S ©Nr   )rI   r6   r5   r   r   r   Ú	<genexpr>Ï   ó    z+gp_log.get_applied_guids.<locals>.<genexpr>)r(   r)   r"   ÚfindallÚsortÚextend)r,   Úguidsr-   r2   Z	guid_objsZguids_by_countr   r   r   Úget_applied_guidsÁ   s    

ÿzgp_log.get_applied_guidsc                 C   sŽ   g }| j  d| j ¡}|D ]n}| d| ¡}| d¡}i }|D ]:}i }	| d¡}
|
D ]}|j|	|jd < qT|	||jd < q>| ||f¡ q|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.
        r!   r4   r=   r?   r#   )r(   r)   r"   rP   r@   r+   Úappend)r,   rS   Zretr-   r5   Zguid_settingsZextsZsettingsrC   Z	attr_dictÚattrsrD   r   r   r   Úget_applied_settingsÒ   s    

zgp_log.get_applied_settingsc                 C   s‚   | j  d| j ¡}| d| j ¡}|dus2J dƒ‚| d| ¡}|dur~| d| ¡}|dur~| |¡ t|ƒdkr~| |¡ dS )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
        r!   r4   Nr;   r<   r>   r   )r(   r)   r"   r5   Úremover0   rF   r   r   r   Údeleteè   s    
zgp_log.deletec                 C   s   | j  | jt | jd¡¡ dS )z Write gp_log changes to disk zutf-8N)r%   rE   r&   r'   Ztostringr(   ©r,   r   r   r   Úcommitù   s    zgp_log.commit)N)r   r   r   Ú__doc__r.   r3   r:   rE   rG   rT   rW   rY   r[   r   r   r   r   r    4   s   %
r    c                   @   s\   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú
GPOStoragec                 C   s:   t j |¡rt |¡| _nt |dtjt jt j	B ¡| _d S )Nr   )
ÚosÚpathÚisfileÚtdbÚopenÚlogZTdbZDEFAULTÚO_CREATÚO_RDWR)r,   Zlog_filer   r   r   r.   ÿ   s    zGPOStorage.__init__c                 C   s   | j  ¡  d S rM   )rc   Ztransaction_startrZ   r   r   r   Ústart  s    zGPOStorage.startc                 C   s0   zt | j t|ƒ¡ƒW S  ty*   Y d S 0 d S rM   )Úintrc   rH   r   Ú	TypeError©r,   Úkeyr   r   r   Úget_int  s    zGPOStorage.get_intc                 C   s   | j  t|ƒ¡S rM   )rc   rH   r   ri   r   r   r   rH     s    zGPOStorage.getc                 C   s   t || | j t|ƒ¡ƒS rM   )r    rc   rH   r   )r,   r"   r   r   r   Ú	get_gplog  s    zGPOStorage.get_gplogc                 C   s   | j  t|ƒt|ƒ¡ d S rM   )rc   rE   r   )r,   rj   Úvalr   r   r   rE     s    zGPOStorage.storec                 C   s   | j  ¡  d S rM   )rc   Ztransaction_cancelrZ   r   r   r   Úcancel  s    zGPOStorage.cancelc                 C   s   | j  t|ƒ¡ d S rM   )rc   rY   r   ri   r   r   r   rY     s    zGPOStorage.deletec                 C   s   | j  ¡  d S rM   )rc   Ztransaction_commitrZ   r   r   r   r[     s    zGPOStorage.commitc                 C   s   | j  ¡  d S rM   )rc   ÚcloserZ   r   r   r   Ú__del__   s    zGPOStorage.__del__N)r   r   r   r.   rf   rk   rH   rl   rE   rn   rY   r[   rp   r   r   r   r   r]   þ   s   r]   c                   @   sD   e Zd ZeZdd„ Zedd„ ƒZedd„ ƒZdd„ Z	ed	d
„ ƒZ
dS )r=   c                 C   s&   || _ || _|| _| | ¡ ¡| _d S rM   )ÚloggerÚlpÚcredsrl   Úget_usernameÚgp_db)r,   rq   rr   rs   rE   r   r   r   r.   '  s    zgp_ext.__init__c                 C   s   d S rM   r   )r,   Zdeleted_gpo_listZchanged_gpo_listr   r   r   Úprocess_group_policy-  s    zgp_ext.process_group_policyc                 C   s   d S rM   r   )r,   Úpolicyr   r   r   Úread1  s    zgp_ext.readc                 C   s<   | j  d¡}tj |t|ƒ ¡ ¡}tj |¡r8|  |¡S d S )NÚ	gpo_cache)	rr   Ú
cache_pathr^   r_   ÚjoinÚcheck_safe_pathÚupperÚexistsrx   )r,   ZafileZ
local_pathÚ	data_filer   r   r   Úparse5  s
    
zgp_ext.parsec                 C   s   d S rM   r   rZ   r   r   r   Ú__str__<  s    zgp_ext.__str__N)r   r   r   r   Ú__metaclass__r.   r   rv   rx   r€   r   r   r   r   r   r=   $  s   

r=   c                   @   sH   e Zd ZeZdd„ Zdd„ Zdd„ Zedd„ ƒZ	d	d
„ Z
edd„ ƒZdS )Úgp_ext_setterc                 C   s(   || _ || _|| _|| _|| _|| _d S rM   )rq   r?   rm   rr   rs   ru   )r,   rq   ru   rr   rs   r?   rm   r   r   r   r.   D  s    zgp_ext_setter.__init__c                 C   s   | j S rM   )rm   rZ   r   r   r   ÚexplicitL  s    zgp_ext_setter.explicitc                 C   s"   |   ¡  | j¡\}}||ƒ ƒ d S rM   )ÚmapperrH   r?   )r,   Úupd_samr1   r   r   r   Úupdate_sambaO  s    zgp_ext_setter.update_sambac                 C   s   d S rM   r   rZ   r   r   r   r…   S  s    zgp_ext_setter.mapperc                 C   s"   |   ¡  | j¡\}}|| jƒ d S rM   )r…   rH   r?   rm   )r,   r†   Ú_r   r   r   rY   W  s    zgp_ext_setter.deletec                 C   s   d S rM   r   rZ   r   r   r   r   [  s    zgp_ext_setter.__str__N)r   r   r   r   r‚   r.   r„   r‡   r   r…   rY   r   r   r   r   r   rƒ   A  s   
rƒ   c                   @   s   e Zd Zdd„ ZdS )Ú
gp_inf_extc              	   C   sR   t |dƒ ¡ }tƒ }t|_z| t|ƒ¡ W n    | t| d¡ƒ¡ Y n0 |S )NÚrzutf-16)rb   rx   r   ÚstrZoptionxformZreadfpr   Údecode)r,   r   rw   Zinf_confr   r   r   rx   a  s    zgp_inf_ext.readN©r   r   r   rx   r   r   r   r   r‰   `  s   r‰   c                   @   s   e Zd Zdd„ ZdS )Ú
gp_pol_extc                 C   s   t |dƒ ¡ }ttj|ƒS )NÚrb)rb   rx   r   r   Úfile)r,   r   Úrawr   r   r   rx   m  s    zgp_pol_ext.readNr   r   r   r   r   rŽ   l  s   rŽ   c                 C   s.   t | |d}|j| d¡tjtjB d}|jS )N)rs   rr   Zrealm)ZdomainÚflags)r   ZfinddcrH   r	   ZNBT_SERVER_LDAPZNBT_SERVER_DSZpdc_dns_name)rs   rr   ZnetZ	cldap_retr   r   r   Úget_dc_hostnameu  s
    ÿr“   c                 C   s,   g }t  | ||¡}| ¡ r(| | ¡ ¡}|S rM   )ÚgpoZ
ADS_STRUCTZconnectÚget_gpo_listrt   )Údc_hostnamers   rr   ÚgposZadsr   r   r   r•     s
    r•   c           
   
   C   sü   |  ¡ }tj ||¡}ztj|dd W n2 tyZ } z|jtjkrF‚ W Y d }~n
d }~0 0 |  |¡D ]}|d t	j
@ r”t| |tj ||d ¡ƒ qf|d   ¡ }td|d}tj ||d ¡ dd¡}	| |  |	¡¡ | ¡  t |jtj ||¡¡ qfd S )	Nií  )Úmoder+   r#   F)rY   Údirú/ú\)r}   r^   r_   r{   ÚmakedirsÚOSErrorÚerrnoZEEXISTÚlistÚlibsmbÚFILE_ATTRIBUTE_DIRECTORYÚcache_gpo_dirr   ÚreplaceÚwriteZloadfilero   Úrenamer#   )
ÚconnÚcacheZsub_dirZloc_sub_dirZ	local_dirÚeZfdataZ
local_nameÚfÚfnamer   r   r   r¢   ‡  s     r¢   c                 C   sJ   t  d| ¡}d| v r*|| d¡d d … }d|vr>tjj|Ž S t| ƒ‚d S )Nz/|\\Úsysvolr   z..)ÚreÚsplitÚindexr^   r_   r{   r   )r_   Údirsr   r   r   r|   ›  s    r|   c                 C   sZ   t  ¡ }| |j¡ tj| d||dd}| d¡}|D ]}|jsBq6t||t	|jƒƒ q6d S )Nr«   T)rr   rs   Zsignry   )
Ús3paramZget_contextÚloadZ
configfiler    ZConnrz   Úfile_sys_pathr¢   r|   )r–   rr   rs   r—   Zs3_lpr¦   rz   r”   r   r   r   Úcheck_refresh_gpo_list¤  s    
r³   c                    s6   |   ¡ }tdd„ |D ƒƒ‰ ‡ fdd„|D ƒ}|  |¡S )Nc                 S   s   g | ]
}|j ‘qS r   )r#   )rI   Úpr   r   r   rK   ²  rO   z)get_deleted_gpos_list.<locals>.<listcomp>c                    s   g | ]}|ˆ vr|‘qS r   r   )rI   r5   ©Zcurrent_guidsr   r   rK   ³  rO   )rT   ÚsetrW   )ru   r—   Zapplied_gposZdeleted_gposr   rµ   r   Úget_deleted_gpos_list°  s    r·   c                 C   s&   |   tj d|¡¡}tt |¡d ƒS )Nry   r   )rz   r^   r_   r{   rg   r”   Zgpo_get_sysvol_gpt_version)rr   r_   Zgpt_pathr   r   r   Úgpo_version¶  s    r¸   Fc                 C   s¦  |  | ¡ ¡}t|| ƒ}t||| ƒ}t||ƒ}	zt|| ||ƒ W n   | d| ¡ Y d S 0 |rt|}
| tj	¡ nfg }
|D ]P}|j
sˆq||j}t|j
ƒ ¡ }t| |ƒ}|| |¡kr|| d| ¡ |
 |¡ q|| tj¡ | ¡  |D ]l}z| |	|
¡ W qæ tyP } z<| dt|ƒ ¡ | dt|ƒ ¡ W Y d }~qæW Y d }~qæd }~0 0 qæ|D ]@}|j
shqX|j}t|j
ƒ ¡ }t| |ƒ}| |d| ¡ qX| ¡  d S )Nz0Failed downloading gpt cache from '%s' using SMBzGPO %s has changedzFailed to apply extension  %súMessage was: z%i)rl   rt   r“   r•   r·   r³   Úerrorr3   r   r   r²   r#   r|   r}   r¸   rk   ÚinforU   r   rf   rv   Ú	Exceptionr‹   rE   r[   )rr   rs   rq   rE   Úgp_extensionsZforceru   r–   r—   Údel_gposZchanged_gposZgpo_objr5   r_   ÚversionrC   r¨   r   r   r   Úapply_gp½  sR    

ÿ
$
rÀ   c           	      C   s¬   |  | ¡ ¡}| tj¡ | | ¡ ¡}| ¡  |D ]j}z| |g ¡ W q4 t	yœ } z<| 
dt|ƒ ¡ | 
dt|ƒ ¡ W Y d }~q4W Y d }~q4d }~0 0 q4| ¡  d S )NzFailed to unapply extension  %sr¹   )rl   rt   r3   r   r   rW   rT   rf   rv   r¼   rº   r‹   r[   )	rr   rs   rq   rE   r½   ru   r¾   rC   r¨   r   r   r   Ú
unapply_gpë  s    $rÁ   c                 C   sD   t ƒ }| d ur| | ¡ n| ¡  | d¡}tƒ }| |¡ ||fS )Nú
gpext.conf)r   r±   Zload_defaultÚ
state_pathr   rx   )Úsmb_confrr   Úext_confÚparserr   r   r   Úparse_gpext_confû  s    

rÇ   c                 C   s\   |   d¡}tddtj |¡d(}| |¡ t |j|¡ W d   ƒ n1 sN0    Y  d S )NrÂ   zw+F)r˜   rY   r™   )rÃ   r   r^   r_   Údirnamer¤   r¥   r#   )rr   rÆ   rÅ   r©   r   r   r   Úatomic_write_conf  s    

rÉ   c                 C   sR   | d dks$| d dks$t | ƒdkr(dS zt| dd W n tyL   Y dS 0 d	S )
Nr   ú{éÿÿÿÿú}é&   Fé   )r¿   T)r0   r   Ú
ValueError)r5   r   r   r   Ú
check_guid  s    $rÐ   Tc                 C   s”   t j |¡sdS t| ƒsdS t|ƒ\}}| | ¡ vr>| | ¡ | | d|¡ | | d|¡ | | d|rjdnd¡ | | d|r€dnd¡ t||ƒ dS )	NFÚDllNameÚProcessGroupPolicyÚNoMachinePolicyÚ0Ú1ÚNoUserPolicyT)	r^   r_   r~   rÐ   rÇ   ÚsectionsZadd_sectionr¶   rÉ   )r5   r#   r_   rÄ   Úmachiner"   rr   rÆ   r   r   r   Úregister_gp_extension  s    

rÙ   c                 C   s†   t | ƒ\}}i }| ¡ D ]h}i ||< | |d¡|| d< | |d¡|| d< t| |d¡ƒ || d< t| |d¡ƒ || d< q|S )NrÑ   rÒ   rÓ   ZMachinePolicyrÖ   Z
UserPolicy)rÇ   r×   rH   rg   )rÄ   rˆ   rÆ   Zresultsr5   r   r   r   Úlist_gp_extensions.  s    
ÿ
ÿ
rÚ   c                 C   s<   t | ƒsdS t|ƒ\}}| | ¡ v r.| | ¡ t||ƒ dS )NFT)rÐ   rÇ   r×   Zremove_sectionrÉ   )r5   rÄ   rr   rÆ   r   r   r   Úunregister_gp_extension<  s    

rÛ   )F)NTT)N)N)CÚsysr^   rž   ra   r_   ÚinsertZsambar   Zsamba.compatr   r   r   Úabcr   r   Zxml.etree.ElementTreer'   ZElementTreer¬   Z	samba.netr   Zsamba.dcerpcr	   Zsamba.samba3r
   r    r   r°   Z	samba.gpor”   Zsamba.paramr   Zuuidr   Ztempfiler   r   r   Z	samba.ndrr   r   Úenumr   r   ÚImportErrorr    r]   Úobjectr=   rƒ   r‰   rŽ   r“   r•   r¢   r|   r³   r·   r¸   rÀ   rÁ   rÇ   rÉ   rÐ   rÙ   rÚ   rÛ   r   r   r   r   Ú<module>   sd    K&	
	
. ÿ

