B
    à%Q[Î»  ã               @   s\  d 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mZmZmZmZmZmZ d	dlmZmZ d	dlmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% d	dl&m'Z' d	dl(m)Z)m*Z*m+Z+m,Z, d	dl-m.Z.m/Z/ d	dl0m1Z1m2Z2 d	dl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; d	dl<m=Z=m>Z>m?Z?m@Z@mAZA d	dlBmCZCmDZD d	dlEmFZFmGZGmHZHmIZImJZJ d	dlKmLZL d	dlMmNZNmOZO d	dlPmQZQmRZR d	dlSmTZTmUZU d	dlVmWZW d	dlXmYZY d	dlZm[Z[ d	dl\m]Z] d	dl^m_Z_ d	dl`maZambZbmcZcmdZdmeZemfZfmgZgmhZh d	dlimjZjmkZkmlZlmmZm d	d lnmoZo d!Zpd"Zqd#ZrG d$d%„ d%esƒZtdS )&Ú
é    N)Úpack)Úsystem)Úexc_info)Úsleep)Úchoice)Údatetimeé   )ÚSYNCÚ	ANONYMOUSÚget_config_parameterÚBASEÚALL_ATTRIBUTESÚALL_OPERATIONAL_ATTRIBUTESÚNO_ATTRIBUTES)ÚDO_NOT_RAISE_EXCEPTIONSÚRESULT_REFERRAL)ÚLDAPOperationResultÚLDAPSASLBindInProgressErrorÚLDAPSocketOpenErrorÚ"LDAPSessionTerminatedByServerErrorÚLDAPUnknownResponseErrorÚLDAPUnknownRequestErrorÚLDAPReferralErrorÚcommunication_exception_factoryÚLDAPSocketSendErrorÚLDAPExceptionErrorÚLDAPControlErrorÚLDAPResponseTimeoutErrorÚLDAPTransactionError)Ú	parse_uri)ÚLDAPMessageÚ
ProtocolOpÚ	MessageIDÚSearchResultEntry)Úadd_response_to_dictÚadd_request_to_dict)Úmodify_request_to_dictÚmodify_response_to_dict)Ú(search_result_reference_response_to_dictÚ#search_result_done_response_to_dictÚ$search_result_entry_response_to_dictÚsearch_request_to_dictÚ)search_result_entry_response_to_dict_fastÚ-search_result_reference_response_to_dict_fastÚattributes_to_dictÚattributes_to_dict_fast)Úbind_response_to_dictÚbind_request_to_dictÚsicily_bind_response_to_dictÚbind_response_to_dict_fastÚ!sicily_bind_response_to_dict_fast)Úcompare_response_to_dictÚcompare_request_to_dict)Úextended_request_to_dictÚextended_response_to_dictÚintermediate_response_to_dictÚextended_response_to_dict_fastÚ"intermediate_response_to_dict_fast)ÚServer)Úmodify_dn_request_to_dictÚmodify_dn_response_to_dict)Údelete_response_to_dictÚdelete_request_to_dict)Úprepare_changes_for_requestÚbuild_controls_list)Úabandon_request_to_dict)ÚTls)ÚOids)ÚRealSearchControlValue)ÚDirSyncControlResponseValue)ÚlogÚlog_enabledÚERRORÚBASICÚPROTOCOLÚNETWORKÚEXTENDEDÚformat_ldap_message)ÚencodeÚdecoderÚldap_result_to_dict_fastÚdecode_sequence)Ú
to_unicodeZTERMINATED_BY_SERVERÚTRANSACTION_ERRORZRESPONSE_FROM_SERVER_COMPLETEc               @   s
  e Zd ZdZdd„ Zdd„ Zd=dd„Zd	d
„ Zd>dd„Zdd„ Z	dd„ Z
d?dd„Zd@dd„Zedd„ ƒZdd„ Zdd„ Zedd„ ƒZedd „ ƒZedAd!d"„ƒZd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z dS )BÚBaseStrategyz,
    Base class for connection strategy
    c             C   sN   || _ d | _g | _d | _d | _d | _d | _i | _tt	ƒrJt
t	d| jj| ƒ d S )Nzinstantiated <%s>: <%s>)Ú
connectionÚ_outstandingÚ
_referralsÚsyncÚno_real_dsaÚpooledÚ
can_streamÚreferral_cacherJ   rL   rI   Ú	__class__Ú__name__)ÚselfZldap_connection© rc   úVC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6i93dh7p\ldap3\ldap3\strategy\base.pyÚ__init__J   s    zBaseStrategy.__init__c             C   sP   | j rt| j ƒnd| jrdnd| jr(dnd| jr4dnd| jr@dnd	g}d
 |¡S )NÚNoner[   Úasynczno real DSAzreal DSAr]   z
not pooledzcan stream outputzcannot stream outputz - )rX   Ústrr[   r\   r]   r^   Újoin)rb   Úsrc   rc   rd   Ú__str__V   s    zBaseStrategy.__str__Tc             C   s�  t tƒrttd| jƒ | jjrP| jjsPd| j_d| j_t tƒrLttd| jƒ �n<| jjsh| jjsh|  ¡  t	ƒ | _
| jjr’|s†| jjjs’| jj ¡  | jjrØ| jj | j¡}| jj|krØ|| j_| jjrØ| jj jd7  _g }| j�sZx¼| jj ¡ D ]¬}yZt tƒ�rttd|dd… ƒ | j|| jjj| jjjd	� || jj_| jj |d¡ P W qò tk
�rœ   | jj |d¡ | t ¡ tƒ d
 tƒ d |d f¡ Y qòX qòW | jjj�s.|�r.t |ƒdk�r
t t!ƒ�rðtt!d|d
 d |d
 d ƒ| jƒ |d
 d |d
 d ƒ‚n"t t!ƒ�r"tt!d| jƒ t"d|ƒ‚n,| jjj�sZt t!ƒ�rRtt!d| jƒ t"dƒ‚d| j_|  #¡  | j $¡  t tƒ�rŒttd| jƒ dS )z^
        Open a socket to a server. Choose a server from the server pool if available
        zopening connection for <%s>TFz"deferring open connection for <%s>é   z try to open candidate address %sNéþÿÿÿ)Úunix_socketr   é   z<%s> for <%s>r	   zunable to open socket for <%s>zunable to open socketzinvalid server address for <%s>zinvalid server addresszconnection open for <%s>)%rJ   rN   rI   rX   ÚlazyÚ_executing_deferredÚ_deferred_openÚclosedÚcloseÚdictrY   ÚusageÚ_usageZinitial_connection_start_timeÚstartZserver_poolZ
get_serverÚserverZservers_from_poolr\   Zcandidate_addressesrL   Ú_open_socketÚsslZipcÚcurrent_addressZupdate_availabilityÚ	ExceptionÚappendr   Únowr   ÚlenrK   r   Ú_start_listenZdo_auto_bind)rb   Zreset_usageZread_server_infoZ
new_serverZexception_historyZcandidate_addressrc   rc   rd   Úopen`   sb    

0
$



zBaseStrategy.openc             C   sê   t tƒrttd| jƒ | jjr^| jjs^| jjs6| jjr^d| j_d| j_	t tƒr’ttd| jƒ n4| jj	s||  
¡  | js||  ¡  t tƒr’ttd| jƒ d| j_d| j_d| j_d| j_d| _g | _| jjjsÒd| jj_| jjræ| jj ¡  dS )z"
        Close connection
        zclosing connection for <%s>FTz#deferred connection closed for <%s>zconnection closed for <%s>N)rJ   rN   rI   rX   rp   rq   Z_deferred_bindrr   Ú	listeningrs   Ú_stop_listenr\   Ú_close_socketÚboundÚrequestÚresponseÚtls_startedrY   rZ   Ústrategyry   r|   rv   rw   Ústop)rb   rc   rc   rd   rt   �   s.     

zBaseStrategy.closeFc          
   C   sì  d}yt j |dd… Ž | j_ W n6 tk
rT } zdt|ƒ | j_|}W dd}~X Y nX |rˆttƒrvttd| jj| jƒ tt	|ƒ| jjƒ‚y4| jj
jr¨| jj  | jj
j¡ | jj  |d ¡ W n8 t jk
rô } zdt|ƒ | j_|}W dd}~X Y nX |�r,ttƒ�rttd| jj| jƒ tt	|ƒ| jjƒ‚| jjdk	�râyl| jj  | jj¡ tƒ  ¡ dk�r‚| jj  t jt jtd| jj ƒ¡ n"| jj  t jt jtd	| jjd
ƒ¡ W n: t jk
�rà } zdt|ƒ | j_|}W dd}~X Y nX |�rttƒ�rttd| jj| jƒ tt	|ƒ| jjƒ‚|�rÄy6| jj
jj| jdd� | jj�rR| jj jd7  _W n8 tk
�rŒ } zdt|ƒ | j_|}W dd}~X Y nX |�rÄttƒ�r²ttd| jj| jƒ tt	|ƒ| jjƒ‚| jj�rà| jj jd7  _d| j_dS )z…
        Tries to open and connect a socket to a Server
        raise LDAPExceptionError if unable to open or connect socket
        Né   zsocket creation error: z<%s> for <%s>ro   z'socket connection error while opening: Zwindowsiè  ZLLr   z5unable to set receive timeout for socket connection: T)Údo_handshakerl   zsocket ssl wrapping error: F)ÚsocketrX   r}   rh   Ú
last_errorrJ   rK   rI   r   r   ry   Úconnect_timeoutÚ
settimeoutÚconnectÚerrorÚreceive_timeoutr   ÚlowerÚ
setsockoptÚ
SOL_SOCKETÚSO_RCVTIMEOÚintr   ÚtlsÚwrap_socketrv   rw   Zwrapped_socketsZopen_socketsrs   )rb   ÚaddressÚuse_sslrn   ÚexcÚerc   rc   rd   rz   ¼   sb    

$&



zBaseStrategy._open_socketc             C   s~   y| j j tj¡ W n tk
r(   Y nX y| j j ¡  W n tk
rN   Y nX d| j _d| j _| j jrz| j j j	d7  _	dS )z€
        Try to close a socket
        don't raise exception if unable to close socket, assume socket is already closed
        NTrl   )
rX   rŽ   ÚshutdownÚ	SHUT_RDWRr}   rt   rs   rv   rw   Zclosed_sockets)rb   rc   rc   rd   r…     s    zBaseStrategy._close_socketc             C   s   d| j _d S )NF)rX   rƒ   )rb   rc   rc   rd   r„     s    zBaseStrategy._stop_listenNc             C   sø   d| j _| j jrÄ| j jrP|dkrPd| j _ttƒrDttd| j j| j ƒ t| j jƒ‚| j j	 
¡ }tƒ }t|ƒ|d< tƒ  ||¡|d< t|ƒ}|dk	r˜||d< t |||¡| j _| j j| j|< |  |¡ n0d| j _ttƒrèttd| j j| j ƒ t| j jƒ‚|S )	zE
        Send an LDAP message
        Returns the message_id
        N)ÚbindRequestz=cannot send operation requests while SASL bind is in progressz<%s> for <%s>Z	messageIDÚ
protocolOpÚcontrolsz*unable to send message, socket is not open)rX   r‡   rƒ   Zsasl_in_progressr�   rJ   rK   rI   r   ry   Znext_message_idr!   r#   r"   ZsetComponentByNamerC   rW   Údecode_requestrY   Úsendingr   )rb   Úmessage_typer‡   r¤   Ú
message_idÚldap_messageZmessage_controlsrc   rc   rd   Úsend  s,    zBaseStrategy.sendc          	   C   sp  t dƒ}|dkrt dƒ}d}d}d}| j�r4|| jk�r4�x‚|dk�r¼|  |¡}|sft|ƒ ||8 }q<|tkrÈy|  ¡  W n tjtfk
r”   Y nX d| j	_
ttƒrºttd| j	j
| j	ƒ t| j	j
ƒ‚n:|tk�rd| j	_
ttƒröttd| j	j
| j	ƒ t| j	j
ƒ‚|d d	 tk�r�| j	j�r0| j	j jd
7  _| j	j�r�|  | j| |d d ¡\}	}
|	dk	�rx|	|
g }| t¡ n|
dk	�rŠ|
tg}g | _|r<|d }|dd… }d| j	_d| j	_P q<W |dk�rèttƒ�ràttd| j	ƒ tdƒ‚| j	j�rR|�rR|d	 tk�rRttƒ�r ttd|| j	ƒ | j  |¡ t!|d	 |d |d |d |d d�‚| j	j"�rt#| dƒ�st$dd„ |D ƒƒ�r| %¡ | _&|dd… }|  '| j| |¡�rxR|D ]J}|d dk�r¬dd„ |d D ƒ}x"|D ]}|d |= |d |= �qÖW �q¬W |}| j&}| `&| j	j(�r&�x|D �]}|d dk�rxj| j| d D ]X}||d k�r>|t)t*t+fk�r>t,ƒ |d |< t,ƒ |d |< ttƒ�r>ttd|| ƒ �q>W | j	j"�sg }x:|d D ].}d| -¡ k�r²| .d¡\}}}| |¡ �q²W x:|D ]2}ttƒ�rttd|| ƒ |d |= |d |= �qêW �qW | j  |¡}n ttƒ�rLttd | j	ƒ td!ƒ‚|�rd|||fS ||fS dS )"aŠ  
        Get response LDAP messages
        Responses are returned by the underlying connection strategy
        Check if message_id LDAP message is still outstanding and wait for timeout to see if it appears in _get_response
        Result is stored in connection.result
        Responses without result is stored in connection.response
        A tuple (responses, result) is returned
        ZRESPONSE_SLEEPTIMENZRESPONSE_WAITING_TIMEOUTr   zsession terminated by serverz<%s> for <%s>ztransaction errorrm   Úresultrl   Ú	referralsz0socket timeout, no response from server for <%s>zno response from serverzoperation result <%s> for <%s>ÚdescriptionÚdnÚmessageÚtype)r«   r­   r®   r¯   Zresponse_typeÚ_auto_range_searchingc             s   s0   | ](}d |kr|d  D ]}d|krdV  qqdS )Úraw_attributesz;range=TNrc   )Ú.0ÚrespÚnamerc   rc   rd   ú	<genexpr>ƒ  s    z,BaseStrategy.get_response.<locals>.<genexpr>ÚsearchResEntryc             S   s   g | ]}d |kr|‘qS )z;range=rc   )r³   Úkeyrc   rc   rd   ú
<listcomp>‰  s    z-BaseStrategy.get_response.<locals>.<listcomp>r²   Ú
attributesz>attribute set to empty list for missing attribute <%s> in <%s>z;rangeú;ziattribute type <%s> removed in response because of same attribute returned as range by the server in <%s>z,message id not in outstanding queue for <%s>z#message id not in outstanding queue)/r   rY   Ú_get_responser   ÚSESSION_TERMINATED_BY_SERVERrt   rŽ   r“   r   rX   r�   rJ   rK   rI   r   rV   r   r   rv   rw   Zreferrals_receivedÚauto_referralsÚdo_operation_on_referralr~   ÚRESPONSE_COMPLETErZ   r«   rˆ   r   Úraise_exceptionsr   rM   Úpopr   Z
auto_rangeÚhasattrÚanyÚcopyr±   Údo_search_on_auto_rangeZempty_attributesr   r   r   Úlistr•   Ú	partition)rb   r¨   ÚtimeoutÚget_requestZconf_sleep_intervalrˆ   r«   r‡   Ú	responsesZref_responseZ
ref_resultZtemp_responser´   Úkeysr¸   ÚentryZattribute_typeZattrs_to_removeZ	orig_attrÚ_rc   rc   rd   Úget_response:  sº    	









&*











zBaseStrategy.get_responsec             C   s¢   t | tƒrt| ƒ} d}t| ƒdkrž| d dkr<| d d }nb| d d }t| ƒ|d kržd}|}x0| dd| … D ]}|d8 }||d|  7 }qrW |d | }|S )z�
        Compute LDAP Message size according to BER definite length rules
        Returns -1 if too few data to compute message length
        éÿÿÿÿr	   rl   é   é€   r   é   )Ú
isinstancerh   Ú	bytearrayr€   )ÚdataZ	ret_valueZbytes_lengthZvalue_lengthZcontZbyterc   rc   rd   Úcompute_ldap_message_size²  s    
z&BaseStrategy.compute_ldap_message_sizec             C   sŠ  |  d¡ ¡ }|d  ¡ }|d }|dkrPt|d ƒ d¡sFt|ƒ}nt|ƒ}nð|dkrxt|| jj	j
| jj	j| jjƒ}nÈ|dkrŠt|ƒ}n¶|dkrœt|ƒ}n¤|d	kr®t|ƒ}n’|d
krÀt|ƒ}n€|dkrÒt|ƒ}nn|dkrät|ƒ}n\|dkröt|ƒ}nJ|dk�r
t|ƒ}n6|dk�rt|ƒ}n"ttƒ�r8ttd|| jƒ tdƒ‚||d< |�r†tƒ |d< x,|D ]$}|  |¡}|d |d |d < �q^W |S )z8
        Convert received LDAPMessage to a dict
        r£   r¤   ÚbindResponseZ	matchedDNs   NTLMr·   ÚsearchResDoneÚsearchResRefÚmodifyResponseÚaddResponseÚdelResponseÚmodDNResponseÚcompareResponseÚextendedRespÚintermediateResponsezunknown response <%s> for <%s>zunknown responser°   rl   r   )ZgetComponentByNameÚgetNameZgetComponentÚbytesÚ
startswithr1   r3   r+   rX   ry   ÚschemaÚcustom_formatterÚcheck_namesr*   r)   r(   r%   r@   r?   r6   r9   r:   rJ   rK   rI   r   ru   Údecode_control)rb   r©   r§   Ú	componentr¤   r«   ÚcontrolÚdecoded_controlrc   rc   rd   Údecode_responseË  sJ    

 














zBaseStrategy.decode_responsec             C   s8  |d dkrH|d d d   d¡s0t|d ƒ}nt|d ƒ}d|d< �n¢|d dkr‚t|d | jjj| jjj| jjƒ}d	|d< �nh|d d
kr¦t	|d ƒ}d|d< �nD|d dkrÊt
|d ƒ}d|d< �n |d dkrìt	|d ƒ}d|d< nþ|d dk�rt	|d ƒ}d|d< nÚ|d dk�r4t	|d ƒ}d|d< n¶|d dk�rXt	|d ƒ}d|d< n’|d dk�r|t	|d ƒ}d|d< nn|d dk�r t|d ƒ}d|d< nJ|d dk�rÄt|d ƒ}d|d< n&ttƒ�râttd|d | jƒ tdƒ‚|d �r4tƒ |d< x4|d D ](}|  |d ¡}|d |d |d < �qW |S ) zN
        Convert received LDAPMessage from fast ber decoder to a dict
        r£   rl   ÚpayloadrŒ   s   NTLMrØ   r°   ro   r·   é   rÙ   é   rÚ   é   rÛ   é	   rÜ   é   rÝ   é   rÞ   é   rß   é   rà   é   rá   zunknown response <%s> for <%s>zunknown responser¤   r   )rä   r4   r5   r-   rX   ry   rå   ræ   rç   rS   r.   r;   r<   rJ   rK   rI   r   ru   Údecode_control_fast)rb   r©   r«   rê   rë   rc   rc   rd   Údecode_response_fast÷  sX    "









z!BaseStrategy.decode_response_fastc             C   s$  t | d ƒ}t| d ƒ}t| d ƒ}d}|dkrltj|tƒ d�\}}tƒ }t|d ƒ|d< t|d ƒ|d< n~|d	kr°tj|tƒ d�\}}tƒ }t|d
 ƒ|d< t|d ƒ|d< n:|dksÀ|dkrêtj|t	ƒ d�\}}tƒ }t
|d ƒ|d< |�rttƒ�rttdƒ tdƒ‚|t |d¡||dœfS )zØ
        decode control, return a 2-element tuple where the first element is the control oid
        and the second element is a dictionary with description (from Oids), criticality and decoded control value
        ZcontrolTypeÚcriticalityZcontrolValueNz1.2.840.113556.1.4.319)Zasn1SpecÚsizeÚcookiez1.2.840.113556.1.4.841ZMoreResultsÚmore_resultsZCookieServerz1.3.6.1.1.13.1z1.3.6.1.1.13.2rº   r«   z)unprocessed control response in substrateÚ )r­   rù   Úvalue)rh   Úboolrã   rR   ÚdecoderG   ru   r™   rH   r$   r/   rJ   rK   rI   r   rF   Úget)rê   Úcontrol_typerù   Úcontrol_valueZunprocessedÚcontrol_resprc   rc   rd   rè   *  s.    

zBaseStrategy.decode_controlc             C   sp  t t| d d dd�ƒ}d}d}x>| dd… D ].}|d d	krH|d }q.|d dkrXdnd}q.W |d
kr¸t|dt|ƒƒ}tƒ }t|d d d d ƒ|d< t|d d d d ƒ|d< n |dk�rt|dt|ƒƒ}tƒ }|d d d d rðdnd|d< |d d d d |d< nF|dk�s&|dk�rXt|dt|ƒƒ}tƒ }t|d d d d ƒ|d< |t 	|d¡||dœfS )zØ
        decode control, return a 2-element tuple where the first element is the control oid
        and the second element is a dictionary with description (from Oids), criticality and decoded control value
        r   rŒ   T)Zfrom_serverFNrl   r	   ro   z1.2.840.113556.1.4.319rú   rû   z1.2.840.113556.1.4.841rü   z1.3.6.1.1.13.1z1.3.6.1.1.13.2r«   rý   )r­   rù   rþ   )
rh   rU   rT   r€   ru   r™   rã   r0   rF   r  )rê   r  rù   r  Úrr  rc   rc   rd   r÷   H  s,    

 z BaseStrategy.decode_control_fastc             C   sâ   | dkrt |ƒ}n¼| dkr"tƒ }n¬| dkr4t|ƒ}nš| dkrFt|ƒ}nˆ| dkrXt|ƒ}nv| dkrjt|ƒ}nd| dkr|t|ƒ}nR| dkrŽt|ƒ}n@| d	kr t|ƒ}n.| d
kr²t	|ƒ}nt
tƒrÆttd| ƒ tdƒ‚| |d< ||d< |S )Nr¢   ZunbindRequestÚ
addRequestÚcompareRequestÚ
delRequestÚextendedReqÚmodifyRequestÚmodDNRequestÚsearchRequestZabandonRequestzunknown request <%s>zunknown requestr°   r¤   )r2   ru   r&   r7   rA   r8   r'   r>   r,   rD   rJ   rK   rI   r   )r§   ré   r¤   r«   rc   rc   rd   r¥   f  s4    








zBaseStrategy.decode_requestc             C   sz   g }xp|D ]h}t |ƒ}|r
xV| jjjD ]H}|d |d ksF|d dkr&|d | jkr&|d  |d< | |¡ P q&W q
W |S )Nr   ÚhostÚ*rl   ÚanonymousBindOnly)r    rX   ry   Úallowed_referral_hostsrZ   r~   )rb   r¬   Zreferral_listÚreferralZcandidate_referralZref_hostrc   rc   rd   Úvalid_referral_list‡  s    


z BaseStrategy.valid_referral_listc          	   C   s’  d}|}�x‚|�sŒ|  d¡\}}}|  d¡\}}}	|d |  |d | 7  < |d |  |d | 7  < |	dk�r†ttƒr˜ttdtt|	ƒd ƒ| jƒ |d tt|	ƒd ƒ d	 }
| jj|d
 dt|d |d tt|	ƒd ƒ d	 gd�}t	|t
ƒ�r|�r| jjd }nd}n|  |¡\}}|d }|�s†|
|d k�rft|d |
 ƒdk�rf|d |
= |d |
= ttdd„ |d  ¡ ƒƒd }qd}qW d S )NFz;range=ú-r²   rº   r  z2performing next search on auto-range <%s> via <%s>rl   z-*r®   z(objectclass=*)ÚdereferenceAlias)Zsearch_baseZsearch_filterZsearch_scopeZdereference_aliasesrº   r   Tc             S   s   d| kS )Nz;range=rc   )Úarc   rc   rd   Ú<lambda>³  s    z3BaseStrategy.do_next_range_search.<locals>.<lambda>)rÈ   rJ   rM   rI   rh   r™   rX   Úsearchr   rÔ   rÿ   rˆ   rÏ   r€   rÇ   ÚfilterrÌ   )rb   r‡   rˆ   Ú	attr_nameÚdoneZcurrent_responseÚ	attr_typerÎ   Zreturned_rangeZ
high_rangeÚrequested_ranger«   rc   rc   rd   Údo_next_range_search•  s:    

"$

z!BaseStrategy.do_next_range_searchc             C   s¼   x¶dd„ |D ƒD ]¤}xžt |d  ¡ ƒD ]Š}d|kr&| d¡\}}}|dkrNdS ||d ksj|d | d krxt ƒ |d |< ||d ks”|d | d kr¢t ƒ |d |< |  |||¡ q&W qW dS )	Nc             S   s   g | ]}|d  dkr|‘qS )r°   r·   rc   )r³   r  rc   rc   rd   r¹   ¹  s    z8BaseStrategy.do_search_on_auto_range.<locals>.<listcomp>r²   z;range=)z1-1z0-0Frº   T)rÇ   rÌ   rÈ   r  )rb   r‡   rˆ   r´   r  r  rÎ   Zrange_valuesrc   rc   rd   rÆ   ¸  s    z$BaseStrategy.do_search_on_auto_rangec                sT  t tƒrttdˆ jƒ ˆ  |¡}|�rD‡ fdd„|D ƒ}|rDt|ƒnt|ƒ}|d |d pbˆ jjj|d f}ˆ jjrŒ|ˆ j	krŒˆ j	| }�nrt
|d |d p¤ˆ jjj|d ˆ jjjˆ jjjˆ jjjˆ jjjˆ jjj|d �rtˆ jjjjˆ jjjjˆ jjjjˆ jjjjˆ jjjjd�nd d�	}d	d
lm}	 |	||d �s@ˆ jjnd |d �sTˆ jjnd ˆ jj|d �snˆ jjnttdˆ jjˆ jjˆ jj ˆ jj!ˆ jj"ˆ jj#ˆ jj$d�}ˆ jj%�rÀˆ jj& j'd7  _'| (¡  ˆ j)|j*_)ˆ jj+�rì|j,�sì| -¡  ˆ jj.�rþ| /¡  ˆ jj%�rˆ jj& j0d7  _0|d dk�r”|j1|d �p<|d |d �pL|d |d �p\|d |d |d �pr|d |d |d |d |d d�	 �n„|d dk�rÎ|j2|d �p¶|d d |d |d d� �nJ|d dk�r|j3|d �pð|d |d |d |d d� �n|d d k�r<|j4|d �p.|d |d d� nÜ|d d!k�rj|j5|d" |d |d dd#� n®|d d$k�r¤|j6|d �pŒ|d t7|d% ƒ|d d� nt|d d&k�ræ|j8|d �pÆ|d |d' |d( |d) |d d� n2d*ˆ j_9t t:ƒ�rtt:d+ˆ jj9ˆ jƒ t;ˆ jj9ƒ‚|j<}
|j=}ˆ jj�r:|ˆ j	|< n| >¡  nd }
d }|
|fS ),Nzfollowing referral for <%s>c                s"   g | ]}|d  ˆ j jjkr|‘qS )r{   )rX   ry   r{   )r³   r  )rb   rc   rd   r¹   Ê  s    z9BaseStrategy.do_operation_on_referral.<locals>.<listcomp>r  Úportr{   )Zlocal_private_key_fileZlocal_certificate_fileÚvalidateÚversionÚca_certs_file)	r  r  r�   Úget_infoÚ	formatterr�   Úmoder  rš   r	   )Ú
Connectionr  T)ry   ÚuserÚpasswordr   ÚauthenticationZclient_strategyr¾   Ú	read_onlyrç   rÁ   Úfast_decoderr”   Úsasl_mechanismÚsasl_credentialsrl   r°   r  Úbaser  Úscoper  rº   Z	sizeLimitZ	timeLimitZ	typesOnlyr¤   )r¤   r  rÍ   r  Ú	attributerþ   r  r	  rµ   )r¤   Z	no_encoder
  Zchangesr  ZnewRdnZdeleteOldRdnZnewSuperiorz referral operation not permittedz<%s> for <%s>)?rJ   rM   rI   rX   r  r   ry   r  Zuse_referral_cacher_   r=   r"  ræ   r�   r$  r  rE   rš   Zprivate_key_fileZcertificate_filer  r   r!  Zcore.connectionr%  r&  r'  r(  r   r
   r)  rç   rÁ   r*  r”   r+  r,  rv   rw   Zreferrals_connectionsr‚   rZ   rŠ   r‰   r{   Z	start_tlsr†   ÚbindZreferrals_followedr  ÚaddÚcompareÚdeleteÚextendedÚmodifyrB   Z	modify_dnr�   rK   r   rˆ   r«   Úunbind)rb   r‡   r¬   r  Zpreferred_referral_listZselected_referralÚcachekeyÚreferral_connectionZreferral_serverr%  rˆ   r«   rc   )rb   rd   r¿   Å  sº    
 L









z%BaseStrategy.do_operation_on_referralc          
   C   s  d }t tƒrttd| jƒ yTt|ƒ}| jj |¡ t tƒrPttd| jt|dƒƒ t tƒrlttdt	|ƒ| jƒ W n< tj
k
rª } zdt|ƒ | j_|}d }W d d }~X Y nX |rÞt tƒrÌttd| jj| jƒ tt|ƒ| jjƒ‚| jjrþ| jj | jjt	|ƒ¡ d S )Nzsending 1 ldap message for <%s>zldap message sent via <%s>:%sz>>zsent %d bytes via <%s>zsocket sending errorz<%s> for <%s>)rJ   rN   rI   rX   rQ   rŽ   ÚsendallrO   rP   r€   r“   rh   r�   rK   r   r   rv   rw   Zupdate_transmitted_messager‡   )rb   r©   rž   Zencoded_messagerŸ   rc   rc   rd   r¦   7  s(    zBaseStrategy.sendingc             C   s   t ‚d S )N)ÚNotImplementedError)rb   rc   rc   rd   r�   O  s    zBaseStrategy._start_listenc             C   s   t ‚d S )N)r:  )rb   r¨   rc   rc   rd   r¼   S  s    zBaseStrategy._get_responsec             C   s   t ‚d S )N)r:  )rb   rc   rc   rd   Ú	receivingW  s    zBaseStrategy.receivingc             C   s   t ‚d S )N)r:  )rb   r¨   rc   rc   rd   Úpost_send_single_response[  s    z&BaseStrategy.post_send_single_responsec             C   s   t ‚d S )N)r:  )rb   r¨   rc   rc   rd   Úpost_send_search_  s    zBaseStrategy.post_send_searchc             C   s   t ‚d S )N)r:  )rb   rc   rc   rd   Ú
get_streamc  s    zBaseStrategy.get_streamc             C   s   t ‚d S )N)r:  )rb   rþ   rc   rc   rd   Ú
set_streamf  s    zBaseStrategy.set_streamc             C   s.   x(t | jƒdkr(| j ¡ \}}| ¡  qW d S )Nr   )r€   r_   Úpopitemr6  )rb   r7  r8  rc   rc   rd   Úunbind_referral_cachei  s    z"BaseStrategy.unbind_referral_cache)TT)FF)N)NF)N)!ra   Ú
__module__Ú__qualname__Ú__doc__re   rk   r‚   rt   rz   r…   r„   rª   rÏ   Ústaticmethodr×   rì   rø   rè   r÷   r¥   r  r  rÆ   r¿   r¦   r�   r¼   r;  r<  r=  r>  r?  rA  rc   rc   rc   rd   rW   E   s<   

=
G

x,3 #rrW   )urD  rŽ   Ústructr   Úplatformr   Úsysr   Útimer   Úrandomr   r   rý   r
   r   r   r   r   r   r   Zcore.resultsr   r   Zcore.exceptionsr   r   r   r   r   r   r   r   r   r   r   r   r   Z	utils.urir    Zprotocol.rfc4511r!   r"   r#   r$   Zoperation.addr%   r&   Zoperation.modifyr'   r(   Zoperation.searchr)   r*   r+   r,   r-   r.   r/   r0   Zoperation.bindr1   r2   r3   r4   r5   Zoperation.comparer6   r7   Zoperation.extendedr8   r9   r:   r;   r<   Zcore.serverr=   Zoperation.modifyDnr>   r?   Zoperation.deleter@   rA   Zprotocol.convertrB   rC   Zoperation.abandonrD   Zcore.tlsrE   Zprotocol.oidrF   Zprotocol.rfc2696rG   Zprotocol.microsoftrH   Z	utils.logrI   rJ   rK   rL   rM   rN   rO   rP   Z
utils.asn1rQ   rR   rS   rT   Z
utils.convrU   r½   rV   rÀ   ÚobjectrW   rc   rc   rc   rd   Ú<module>   sD   $<((