a
    Wa6K                     @   s   d dl mZmZ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Zd dlZd dlmZmZmZ d dlZG d	d
 d
eZdd Zdd Zdd Zdd Zdd Zdd ZG dd deZG dd deZdS )    )drsuapimiscdrsblobs)Net)
ndr_unpack)dsdb)werror)WERRORErrorN)DRSUAPI_ATTID_name(DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8)DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10c                   @   s    e Zd ZdZdd Zdd ZdS )drsExceptionzBase element for drs errorsc                 C   s
   || _ d S Nvalue)selfr    r   1/usr/lib/python3/dist-packages/samba/drs_utils.py__init__%   s    zdrsException.__init__c                 C   s
   d| j  S )NzdrsException: r   )r   r   r   r   __str__(   s    zdrsException.__str__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   "   s   r   c           	   
   C   s   d}|  dkr|d7 }d| |f }zt|||}t|\}}W n4 tyv } ztd| |f W Y d}~n
d}~0 0 |||fS )am  Make a DRSUAPI connection to the server.

    :param server: the name of the server to connect to
    :param lp: a samba line parameter object
    :param creds: credential used for the connection
    :return: A tuple with the drsuapi bind object, the drsuapi handle
                and the supported extensions.
    :raise drsException: if the connection fails
    Zseal	   z,printzncacn_ip_tcp:%s[%s]zDRS connection to %s failed: %sN)Z	log_levelr   
drs_DsBind	Exceptionr   )	ZserverlpcredsZbinding_optionsbinding_stringdrsuapiBindZdrsuapiHandleZbindSupportedExtensionser   r   r   drsuapi_connect,   s    &r"   c              
   C   sv   t  }||_t  }||_||_t||_z| 	|d| W n0 t
yp } ztd| W Y d}~n
d}~0 0 dS )a  Send DS replica sync request.

    :param drsuapiBind: a drsuapi Bind object
    :param drsuapi_handle: a drsuapi handle on the drsuapi connection
    :param source_dsa_guid: the guid of the source dsa for the replication
    :param naming_context: the DN of the naming context to replicate
    :param req_options: replication options for the DsReplicaSync call
    :raise drsException: if any error occur while sending and receiving the
        reply for the dsReplicaSync
       zDsReplicaSync failed %sN)r   DsReplicaObjectIdentifierdnZDsReplicaSyncRequest1naming_contextZoptionsr   GUIDsource_dsa_guidZDsReplicaSyncr   r   )r    drsuapi_handler(   r&   Z
req_optionZncreq1estrr   r   r   sendDsReplicaSyncD   s    r,   c              
   C   sj   z4t  }t||_t||_d|_| |d| W n0 tyd } ztd| W Y d}~n
d}~0 0 dS )a  Send RemoveDSServer request.

    :param drsuapiBind: a drsuapi Bind object
    :param drsuapi_handle: a drsuapi handle on the drsuapi connection
    :param server_dsa_dn: a DN object of the server's dsa that we want to
        demote
    :param domain: a DN object of the server's domain
    :raise drsException: if any error occur while sending and receiving the
        reply for the DsRemoveDSServer
    r#   zDsRemoveDSServer failed %sN)	r   ZDsRemoveDSServerRequest1strZ	server_dnZ	domain_dnZcommitZDsRemoveDSServerr   r   )r    r)   Zserver_dsa_dnZdomainr*   r+   r   r   r   sendRemoveDsServer_   s    

r.   c                 C   s4  t  }d|_t  |_|j jt jO  _|j jt jO  _|j jt jO  _|j jt j	O  _|j jt j
O  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt jO  _|j jt j O  _|j jt j!O  _| "t#$t j%|\}}||jjfS )z0make a DsBind call, returning the binding handle   )&r   ZDsBindInfoCtrZlengthZDsBindInfo28infoZsupported_extensionsZ DRSUAPI_SUPPORTED_EXTENSION_BASEZ-DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATIONZ%DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPIZ&DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2Z+DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESSZ%DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1Z4DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATIONZ'DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTEZ'DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2Z4DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATIONZ%DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2Z8DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MODZ'DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BINDZ)DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFOZ-DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTIONZ&DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01Z1DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIPZ+DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORYZ&DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3Z,DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2Z(DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6Z)DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCSr   Z*DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5Z*DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6Z,DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3Z*DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7Z)DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECTZDsBindr   r'   ZDRSUAPI_DS_BIND_GUID)drsZ	bind_infor0   Zhandler   r   r   r   v   sB    
r   c           
      C   s   t  }d|_g }|  }| j|tjdg dd}|D ]}t|d d }d|v rx|d d }t|t	j
jt	j
jB @ rxq6d|v r|d d }t|t	j
j@ rq6| |}	|t|	 q6|  ||_t||_|S )	z-get a list of attributes for RODC replicationr#   zobjectClass=attributeSchema)lDAPDisplayNamesystemFlagssearchFlags)basescopeZ
expressionattrsr2   r   r3   r4   )r   ZDsPartialAttributeSetversionZget_schema_basednsearchldbZSCOPE_SUBTREEr-   intsambar   ZDS_FLAG_ATTR_NOT_REPLICATEDZDS_FLAG_ATTR_IS_CONSTRUCTEDZSEARCH_FLAG_RODC_ATTRIBUTEZget_attid_from_lDAPDisplayNameappendsortattidslenZ
num_attids)
samdbpartial_attribute_setr?   Z	schema_dnresrZldap_display_nameZsystem_flagsZsearch_flagsattidr   r   r   "drs_get_rodc_partial_attribute_set   s4    


rF   c                 C   s   |j | _ |j| _|j| _dS )z
    Copies the highwater mark by value, rather than by object reference. (This
    avoids lingering talloc references to old GetNCChanges reply messages).
    N)tmp_highest_usnreserved_usnhighest_usn)hwmZnew_hwmr   r   r   drs_copy_highwater_mark   s    rK   c                   @   sB   e Zd ZdZdd Zdd Zdd Zdejdd	d
ddfddZ	d	S )drs_ReplicatezDRS replication callsc                 C   s   t  |||| _t| j\| _| _t||d| _|| _t|t	j
sJtd|t	
dkr`td| j| j|| j|| _d| _d S )N)r   r   z"Must supply GUID for invocation_idz$00000000-0000-0000-0000-000000000000zGMust not set GUID 00000000-0000-0000-0000-000000000000 as invocation_idr   )r   r1   r   
drs_handlesupports_extr   netrA   
isinstancer   r'   RuntimeErrorZreplicate_initreplication_state
more_flags)r   r   r   r   rA   invocation_idr   r   r   r      s    zdrs_Replicate.__init__c                 C   s&   | j }|dko$|t@ o$|jtj@ dkS )Ni!  r   )rN   r   rS   r   DRSUAPI_DRS_GET_TGT)r   Z
error_codereqrN   r   r   r   _should_retry_with_get_tgt   s    z(drs_Replicate._should_retry_with_get_tgtc                 C   s   | j j| j|||||d dS )5Processes a single chunk of received replication data)schema	req_levelrV   N)rO   Zreplicate_chunkrR   r   levelctrrY   rZ   rV   first_chunkr   r   r   process_chunk   s    zdrs_Replicate.process_chunkFNTr   c              
   C   s  | j t@ r$t }|
| jB |_d}nd}t }||_||_t |_	||j	_
d}t }d|_d|_d|_|s4| jj|tjdgd}d|d v r|d d D ]$}ttj|}|jj|kr|jj}qt }d|_d|_d|_g }t| j| j }|D ]&}t }|j|_|j|_| | q||_!t"||_#||_||_$|durR||_%n\|tj&krfd|_%nHtj'tj(B tj)B tj*B tj+B |_%|r| j%tj,O  _%n| j%tj-O  _%|	r| j%tj.O  _%d|_/d	|_0||_1d|_2d|_3d|_4d|j5_6d|j5_7|s|rt8| j|_3| j t9@ s\d
}t: }t;|D ]&}|d dkr0t<||t=|| q0|}d}d}d}| j>?| j@||\}}|jAdu r|jBdkrtCd|jB z| D|||||| W nj tEy& } zP| F|jGd |rtHd | jtjIO  _d}W Y d}~qhn|W Y d}~n
d}~0 0 d}||jB7 }z||jJ7 }W n tKyX   Y n0 |jLdkrjq|tM|j|jN qh||fS )zreplicate a single DN
      Nr   ZrepsFrom)r5   r6   r7   r#   i  i"    _Tz6DsGetNCChanges: NULL first_object with object_count=%uz1Missing target object - retrying with DRS_GET_TGTF)OrN   r   r   ZDsGetNCChangesRequest10rS   ZDsGetNCChangesRequest8destination_dsa_guidsource_dsa_invocation_idr$   r&   r%   ZDsReplicaHighWaterMarkrG   rH   rI   rA   r9   r:   Z
SCOPE_BASEr   r   ZrepsFromToBlobr]   ZhighwatermarkZDsReplicaCursorCtrExr8   Z	reserved1Z	reserved2r   Z_dsdb_load_udv_v2Zget_default_basednZDsReplicaCursorr=   Zcursorsr@   countZuptodateness_vectorreplica_flagsZDRSUAPI_EXOP_REPL_SECRETZDRSUAPI_DRS_INIT_SYNCZDRSUAPI_DRS_PER_SYNCZDRSUAPI_DRS_GET_ANCZDRSUAPI_DRS_NEVER_SYNCEDZ$DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIPZ%DRSUAPI_DRS_SPECIAL_SECRET_PROCESSINGZDRSUAPI_DRS_WRIT_REPZDRSUAPI_DRS_SYNC_FORCEDZmax_object_countZmax_ndr_sizeZextended_opZ	fsmo_inforB   Zpartial_attribute_set_exZmapping_ctrZnum_mappingsZmappingsrF   r   ZDsGetNCChangesRequest5dirsetattrgetattrr1   ZDsGetNCChangesrM   first_objectobject_countrQ   r_   r	   rW   argsprintrU   Zlinked_attributes_countAttributeErrorZ	more_datarK   Znew_highwatermark)r   r%   re   rd   rY   ZexopZrodcrg   Z	full_syncZsync_forcedrS   rV   rZ   ZudvrJ   rC   Zreps_from_packedZreps_from_objZ
cursors_v1Z
cursors_v2Z	cursor_v2Z	cursor_v1Zreq5aZnum_objectsZ	num_linksr^   r\   r]   r!   r   r   r   	replicate   s    





zdrs_Replicate.replicate)
r   r   r   r   r   rW   r_   r   ZDRSUAPI_EXOP_NONErq   r   r   r   r   rL      s   rL   c                       sD   e Zd ZdZ fddZdd Zdd Zdd	 Z fd
dZ  Z	S )drs_ReplicateRenamerz,Uses DRS replication to rename the entire DBc                    s0   t t| ||||| || _|| _tj| _d S r   )superrr   r   old_base_dnnew_base_dnr   rU   rS   )r   r   r   r   rA   rT   rt   ru   	__class__r   r   r   }  s    zdrs_ReplicateRenamer.__init__c                 C   s   t d| j | j|S )z/Uses string substitution to replace the base DNz%s$)resubrt   ru   )r   Zdn_strr   r   r   	rename_dn  s    zdrs_ReplicateRenamer.rename_dnc                 C   sJ   |j jD ]<}|jtkrt| j|jj}|	 }|
d|jjd _qdS )z3Updates the 'name' attribute for the base DN objectz	utf-16-ler   N)Zattribute_ctrZ
attributesrE   r
   r:   ZDnrA   
identifierr%   Zget_rdn_valueencodeZ	value_ctrvaluesZblob)r   Zbase_objattrZbase_dnnew_namer   r   r   update_name_attr  s
    
z%drs_ReplicateRenamer.update_name_attrc                 C   sJ   |j j}| |j j|j _td||j jf  |j j| jkrF| | dS )z1Renames the first/top-level object in a partitionzRenaming partition %s --> %sN)r{   r%   rz   rn   ru   r   )r   Z	first_objZold_dnr   r   r   rename_top_level_object  s    z,drs_ReplicateRenamer.rename_top_level_objectc                    sR   |j r| |j j|j _|r4|jdkr4| |jj tt| 	|||||| dS )rX   r   N)
r&   rz   r%   rl   r   rk   objectrs   rr   r_   r[   rv   r   r   r_     s    z"drs_ReplicateRenamer.process_chunk)
r   r   r   r   r   rz   r   r   r_   __classcell__r   r   rv   r   rr   z  s   rr   )Zsamba.dcerpcr   r   r   Z	samba.netr   Z	samba.ndrr   r<   r   r   r	   r:   Zsamba.dcerpc.drsuapir
   r   r   rx   r   r   r"   r,   r.   r   rF   rK   r   rL   rr   r   r   r   r   <module>   s&   
&&
 /