B
    ß%Q[Šo  ã               @   s`  d Z ddlZddl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mZmZmZ ddlmZmZmZmZ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&m'Z'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z- yddl.m/Z/ W n" e0k
�r   ddl1m/Z/ Y nX yddlm2Z2 dZ3W n e0k
�rJ   dZ3Y nX G dd„ de4ƒZ5dS )Ú
é    N)ÚLock)ÚdatetimeÚMINYEARé   )ÚDSAÚSCHEMAÚALLÚBASEÚget_config_parameterÚOFFLINE_EDIR_8_8_8ÚOFFLINE_AD_2012_R2ÚOFFLINE_SLAPD_2_4ÚOFFLINE_DS389_1_3_3ÚSEQUENCE_TYPESÚIP_SYSTEM_DEFAULTÚ
IP_V4_ONLYÚ
IP_V6_ONLYÚIP_V4_PREFERREDÚIP_V6_PREFERREDÚSTRING_TYPESé   )ÚLDAPInvalidServerErrorÚLDAPDefinitionErrorÚLDAPInvalidPortErrorÚ LDAPInvalidTlsSpecificationErrorÚLDAPSocketOpenError)Úformat_attribute_values)ÚLDAP_MAX_INT)Ú
SchemaInfoÚDsaInfo)ÚTls)ÚlogÚlog_enabledÚERRORÚBASICÚPROTOCOL)Ú
to_unicode)Úunquote)ÚAF_UNIXTFc            	   @   sÞ   e Zd ZdZdZeƒ Zdddedddedf	dd„Z	e
dd„ ƒZd	d
„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Ze
dd„ ƒZdd„ Zd*dd„Zdd„ Zd+dd„Zd,d d!„Zed"d#„ ƒZed$d%„ ƒZe
d-d&d'„ƒZd(d)„ ZdS ).ÚServera	  
    LDAP Server definition class

    Allowed_referral_hosts can be None (default), or a list of tuples of
    allowed servers ip address or names to contact while redirecting
    search to referrals.

    The second element of the tuple is a boolean to indicate if
    authentication to that server is allowed; if False only anonymous
    bind will be used.

    Per RFC 4516. Use [('*', False)] to allow any host with anonymous
    bind, use [('*', True)] to allow any host with same authentication of
    Server.
    r   NFc             C   sî  d| _ d}| ¡ }| ¡  d¡r8|dd … | _d}d}nj| ¡  d¡r^|dd … | _d}d}nD| ¡  d¡r€tr€d| _ d}d}n"| ¡  d¡rœtsœtdƒ‚n|| _| j rættkrÊt	|dd … ƒ 
d	¡| _nt	|dd … ƒ| _d | _�nªd
| jk�rh| j d
¡dk�rh| j d
¡\}}}yt|ƒ�p$|}W n4 tk
�r\   ttƒ�rPttd|ƒ tdƒ‚Y nX || _�n(|�rJ| j d¡�rJ| jdd …  d¡\}}}|dk�s¬|  |¡�sÊttƒ�rÄttd| jƒ tƒ ‚t|ƒ�rB| d
¡�s ttƒ�røttd| jƒ tdƒ‚|dd …  ¡ �s2ttƒ�r*ttd| jƒ tdƒ‚t|dd … ƒ}|| _nF|�s`|  | j¡�r`n0| j d
¡dk�r�ttƒ�rŠttd| jƒ tƒ ‚| j �s(| j d¡ |�s¶|�s¶d}n|�rÆ|�sÆd}t|tƒ�r
|tddƒk�rê|| _nttƒ�r ttd|ƒ tdƒ‚nttƒ�r ttd|ƒ tdƒ‚|d k�r8dg}t|tƒ�r„g | _xd|D ].}t|tƒ�rPt|d tƒ�rP| j |¡ �qPW n,t|tƒ�rªt|d tƒ�r°|g| _ng | _|�rºdnd| _ |�rðt|t!ƒ�sðttƒ�rèttd|ƒ t"dƒ‚| j �r|�st!ƒ n|| _#| j �sx|  | j¡�rL| j �r,dnd d! | j d" t| jƒ | _$n*| j �rXdnd d# | j d
 t| jƒ | _$n|| _$|| _%d | _&d | _'t(ƒ | _)|| _*|
| _+g | _,t-t.ddƒ| _/d | _0|| _1|	| _2|  3d ¡ tt4ƒ�rêtt4d$| ƒ d S )%NFzldap://é   Tzldaps://é   zldapi://z6LDAP over IPC not available - UNIX sockets non presentzutf-8ú:r   zport <%s> must be an integerzport must be an integerú[ú]z$invalid IPv6 server address for <%s>z#invalid URL in server name for <%s>zinvalid URL in server namez port must be an integer for <%s>zinvalid server address for <%s>ú/i…  i|  r   iÿÿ  z*port <%s> must be in range from 0 to 65535z"port must in range from 0 to 65535)Ú*Tzinvalid tls specification: <%s>zinvalid Tls objectZldapsZldapz://[z]:z://zinstantiated Server: <%r>)5ÚipcÚstripÚlowerÚ
startswithÚhostÚunix_socket_availabler   ÚstrÚbytesr(   ÚdecodeÚportÚcountÚ	partitionÚintÚ
ValueErrorr#   r$   r"   r   Ú_is_ipv6r   ÚlenÚ	isdecimalÚrstripÚ
isinstanceÚranger   Úallowed_referral_hostsÚtupleÚboolÚappendÚsslr!   r   ÚtlsÚnameÚget_infoÚ	_dsa_infoÚ_schema_infor   Údit_lockÚcustom_formatterZcustom_validatorÚ_address_infor   r   Ú_address_info_resolved_timeZcurrent_addressÚconnect_timeoutÚmodeÚget_info_from_serverr%   )Úselfr6   r;   Úuse_sslrF   rM   rK   Ú	formatterrT   rU   Ú	validatorZ	url_givenÚhostnameÚ_ÚhostportÚsepZreferral_host© r_   úTC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6i93dh7p\ldap3\ldap3\core\server.pyÚ__init__I   sÖ    















,,

zServer.__init__c          
   C   s4   yt  t j| ¡ W n t jttfk
r.   dS X dS )NFT)ÚsocketÚ	inet_ptonÚAF_INET6ÚerrorÚAttributeErrorr?   )r6   r_   r_   r`   r@   Ó   s
    zServer._is_ipv6c             C   s8   | j r*| j| jrdnd | jr"dnd }n
t | ¡}|S )Nz - sslz - cleartextz - unix socketÚ )r6   rL   rJ   r2   ÚobjectÚ__str__)rW   Úsr_   r_   r`   ri   Û   s    $
zServer.__str__c             C   s’   d  | ¡}|| jsdnd  | ¡7 }|| jd kr2dnd  | ¡7 }|| jsJdnd  | ¡7 }|| jsbdnd  | ¡7 }|| jszdnd  | ¡7 }|d7 }|S )	Nz:Server(host={0.host!r}, port={0.port!r}, use_ssl={0.ssl!r}rg   z5, allowed_referral_hosts={0.allowed_referral_hosts!r}z, tls={0.tls!r}z, get_info={0.get_info!r}z', connect_timeout={0.connect_timeout!r}z, mode={0.mode!r}ú))ÚformatrF   rK   rM   rT   rU   )rW   Úrr_   r_   r`   Ú__repr__â   s    
zServer.__repr__c          	   C   s6  t dƒ}| jr$t ¡ | j j|k�r0d }yJ| jrJtjtj	dd | j
d fg}n&t | j
| jtjtj	tjtjtjB ¡}W n tjtfk
rŒ   Y nX |sÊy t | j
| jtjtj	tj¡}W n tjk
rÈ   Y nX |rêdd„ |D ƒ| _t ¡ | _ng | _ttddƒ| _ttƒ�r0x&| jD ]}ttd| |d d… ƒ �qW | jS )NZADDRESS_INFO_REFRESH_TIMEr   c             S   s   g | ]}t |ƒd d g ‘qS )N)Úlist)Ú.0Úaddressr_   r_   r`   ú
<listcomp>  s    z'Server.address_info.<locals>.<listcomp>r   z!address for <%s> resolved as <%r>éþÿÿÿ)r   rR   r   ÚnowrS   Úsecondsr2   rb   r)   ÚSOCK_STREAMr6   Úgetaddrinfor;   Ú	AF_UNSPECÚIPPROTO_TCPÚAI_ADDRCONFIGÚAI_V4MAPPEDÚgaierrorrf   r   r#   r%   r"   )rW   Zconf_refresh_intervalÚ	addressesrq   r_   r_   r`   Úaddress_infoí   s.    * 
zServer.address_infoc             C   s\   d}xR|t | jƒk rV| j| |krL|r*dnd| j| d< t ¡ | j| d< P |d7 }qW d S )Nr   TFé   é   r   )rA   rR   r~   r   rt   )rW   rq   Ú	availableZcontr_   r_   r`   Úupdate_availability  s    zServer.update_availabilityc             C   s$   x| j D ]}d |d< d |d< qW d S )Nr   r€   )rR   )rW   rq   r_   r_   r`   Úreset_availability  s    zServer.reset_availabilityc             C   sD  t dƒ}d}|  ¡  �x(|  ¡ D �]}d}y¦tj|dd… Ž }| jrR| | j¡ n
| |¡ z2y| |d ¡ W n tjk
rŠ   d}Y nX W dz0y| tj	¡ W n tjk
r¼   d}Y nX W d| 
¡  X X W n tjk
rê   d}Y nX |�rttƒ�r
ttd| |ƒ |  |d¡ P q |  |d¡ ttƒr ttd| |ƒ q W |S )	zâ
        Tries to open, connect and close a socket to specified address
        and port to check availability. Timeout in seconds is specified in CHECK_AVAILABITY_TIMEOUT if not specified in
        the Server object
        ZCHECK_AVAILABILITY_TIMEOUTFTNé   é   zserver <%s> available at <%r>z!server <%s> not available at <%r>)r   rƒ   Úcandidate_addressesrb   rT   Ú
settimeoutÚconnectre   ÚshutdownÚ	SHUT_RDWRÚcloser|   r#   r%   r"   r‚   r$   )rW   Zconf_availability_timeoutr�   rq   Ztemp_socketr_   r_   r`   Úcheck_availability  s<    


zServer.check_availabilityc            	   C   sL   t j�: t  jd7  _t jtkr&dt _ttƒr<ttdt jƒ W dQ R X t jS )zM
        LDAP messageId is unique for all connections to same server
        r   znew message id <%d> generatedN)r*   Ú_message_id_lockÚ_message_counterr   r#   r&   r"   r_   r_   r_   r`   Únext_message_idF  s    
zServer.next_message_idc             C   sö   |j jrdS |j jsò|jddtdddddd	d
ddddddgdd�}| j�Ž t|tƒr€|rvt|j	d d |j	d d ƒn| j
| _
nR|rÒ| |¡\}}t|ƒdkrÒd|d krÒd|d krÒt|d d |d d ƒ| _
W dQ R X ttƒròttd| |ƒ dS )zJ
        Retrieve DSE operational attribute as per RFC4512 (5.1).
        Nrg   z(objectClass=*)Z	altServerZnamingContextsZsupportedControlZsupportedExtensionZsupportedFeaturesZsupportedCapabilitiesZsupportedLdapVersionZsupportedSASLMechanismsZ
vendorNameZvendorVersionÚsubschemaSubentryr1   ú+T)Zsearch_baseÚsearch_filterÚsearch_scopeÚ
attributesÚget_operational_attributesr   r”   Úraw_attributesr   zDSA info read for <%s> via <%s>)ÚstrategyÚno_real_dsaÚpooledÚsearchr
   rP   rD   rH   r    ÚresponserN   Úget_responserA   r#   r%   r"   )rW   Ú
connectionÚresultÚresultsr\   r_   r_   r`   Ú_get_dsa_infoT  s:    
,$&zServer._get_dsa_inforg   c             C   sì  |j jrdS d}| jr\|dkr\t| jjtƒrF| jjr@| jjd nd}n| jjrV| jjnd}nÒ|j|dtdgdd�}t|tƒrÄ|rÂd|j	d d krÂt
|j	d d d ƒdkrÂ|j	d d d d }nj| |¡\}}t
|ƒd	k�r.d|d k�r.d|d d
 k�r.t
|d d d ƒdk�r.|d d d d }|�rè|j j�sèt|tƒ�r`ttk	�r`t|dd�}|j|dtdddddddddddgdd�}| j��8 d| _|�rÆt|tƒ�rÚ|�rÒt||j	d d
 |j	d d ƒnd| _nV| |¡\}}t
|ƒd	k�r0d
|d k�r0d|d k�r0t||d d
 |d d ƒ| _| j�rJ| j ¡ �sJd| _| j�rÆx4| jjD ](}t| j|| jj| | jƒ| jj|< �q\W | j�rÆx4| jjD ](}t| j|| jj| | jƒ| jj|< �qšW W dQ R X ttƒ�rèttd| |ƒ dS )z�
        Retrieve schema from subschemaSubentry DSE attribute, per RFC
        4512 (4.4 and 5.1); entry = '' means DSE.
        Nrg   r   z(objectClass=*)r�   T)r”   r•   r–   r   r”   )Zfrom_serverz(objectClass=subschema)ZobjectClassesZattributeTypesZldapSyntaxesZmatchingRulesZmatchingRuleUseZdITContentRulesZdITStructureRulesZ	nameFormsZcreateTimestampZmodifyTimestampr1   )r’   r“   r”   r•   zschema read for <%s> via <%s>)r—   r˜   rN   rD   Úschema_entryr   rš   r
   rH   r›   rA   rœ   r™   r9   r8   r'   rP   rO   r   Zis_validÚotherr   ÚrawrQ   r#   r%   r"   )rW   r�   Úentryr¡   rž   rŸ   r\   Ú	attributer_   r_   r`   Ú_get_schema_infoy  sh    
.
.*(2
zServer._get_schema_infoc       
      C   s0  |r<|j s<| jttgkr"|  |¡ | jttgkr:|  |¡ nð| jtkrxddlm	}m
} |  t |¡¡ |  t |¡¡ n´| jtkr´ddlm}m} |  t |¡¡ |  t |¡¡ nx| jtkrðddlm}m} |  t |¡¡ |  t |¡¡ n<| jtk�r,ddlm}m}	 |  t |¡¡ |  t |	¡¡ dS )z8
        reads info from DSE and from subschema
        r   )Úedir_8_8_8_schemaÚedir_8_8_8_dsa_info)Úad_2012_r2_schemaÚad_2012_r2_dsa_info)Úslapd_2_4_schemaÚslapd_2_4_dsa_info)Úds389_1_3_3_schemaÚds389_1_3_3_dsa_infoN)ÚclosedrM   r   r	   r    r   r¦   r   Zprotocol.schemas.edir888r§   r¨   Úattach_schema_infor   Ú	from_jsonÚattach_dsa_infor    r   Zprotocol.schemas.ad2012R2r©   rª   r   Zprotocol.schemas.slapd24r«   r¬   r   Zprotocol.schemas.ds389r­   r®   )
rW   r�   r§   r¨   r©   rª   r«   r¬   r­   r®   r_   r_   r`   rV   º  s*    




zServer.get_info_from_serverc             C   s(   t |tƒr$|| _ttƒr$ttd| ƒ d S )Nz attached DSA info to Server <%s>)rD   r    rN   r#   r%   r"   )rW   Údsa_infor_   r_   r`   r²   Ô  s    
zServer.attach_dsa_infoc             C   s(   t |tƒr|| _ttƒr$ttd| ƒ d S )Nz#attached schema info to Server <%s>)rD   r   rO   r#   r%   r"   )rW   Ú
dsa_schemar_   r_   r`   r°   Ú  s    
zServer.attach_schema_infoc             C   s   | j S )N)rN   )rW   r_   r_   r`   Úinfoà  s    zServer.infoc             C   s   | j S )N)rO   )rW   r_   r_   r`   Úschemaä  s    zServer.schemac             C   s6  t | tƒr$t| d ||||td�}nt| ||||td�}t |tƒrJ||_n<t |tƒr†yt |¡|_W n  tk
r„   t 	|¡|_Y nX |j
s¨ttƒr ttd| ƒ tdƒ‚t |tƒrº||_n<t |tƒröyt |¡|_W n  tk
rô   t 	|¡|_Y nX |j�sttƒ�rttd| ƒ tdƒ‚ttƒ�r2ttd|ƒ |S )a¬  
        Define a dummy server with preloaded schema and info
        :param host: host name
        :param dsa_info: DsaInfo preloaded object or a json formatted string or a file name
        :param dsa_schema: SchemaInfo preloaded object or a json formatted string or a file name
        :param port: dummy port
        :param use_ssl: use_ssl
        :param formatter: custom formatter
        :return: Server object
        r   )r6   r;   rX   rY   rZ   rM   zinvalid DSA info for %szinvalid dsa infozinvalid schema info for %szinvalid schema infoz#created server <%s> from definition)rD   r   r*   r	   r    rN   r   r±   Ú	ExceptionÚ	from_filerµ   r#   r$   r"   r   r   rO   r¶   r%   )r6   r³   r´   r;   rX   rY   rZ   Údummyr_   r_   r`   Úfrom_definitionè  s8    






zServer.from_definitionc             C   s†  t dƒ}| jr0| j}ttƒr,ttd| | jƒ �nRx<| jD ]2}|d r8t ¡ |d  j	|kr8d |d< d |d< q8W | jd d … }g }|�rN| j
tkr | |d ¡ n®| j
tkrºdd„ |D ƒ}n”| j
tkrÔdd„ |D ƒ}nz| j
tk�rd	d„ |D ƒ}|d
d„ |D ƒ7 }nL| j
tk�r0dd„ |D ƒ}|dd„ |D ƒ7 }nttƒ�rFttd| ƒ tdƒ‚ttƒ�r‚x(|D ] }ttd| |d d… | j
ƒ �q^W |S )NZRESET_AVAILABILITY_TIMEOUTz6candidate address for <%s>: <%s> with mode UNIX_SOCKETr€   r   r   c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   ÚAF_INET)rp   rq   r_   r_   r`   rr   +  s    z.Server.candidate_addresses.<locals>.<listcomp>c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   rd   )rp   rq   r_   r_   r`   rr   -  s    c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   r»   )rp   rq   r_   r_   r`   rr   /  s    c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   rd   )rp   rq   r_   r_   r`   rr   0  s    c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   rd   )rp   rq   r_   r_   r`   rr   2  s    c             S   s2   g | ]*}|d  t jkr|d s*|d dkr|‘qS )r   r   N)rb   r»   )rp   rq   r_   r_   r`   rr   3  s    zinvalid server mode for <%s>zinvalid server modez6obtained candidate address for <%s>: <%r> with mode %srs   )r   r2   r~   r#   r%   r"   rL   r   rt   ru   rU   r   rI   r   r   r   r   r$   r   )rW   Zconf_reset_availability_timeoutÚ
candidatesrq   r}   Ú	candidater_   r_   r`   r†     s>    





 zServer.candidate_addresses)rg   )N)N)NFNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rŽ   r   r�   r   r   ra   Ústaticmethodr@   ri   rn   Úpropertyr~   r‚   rƒ   rŒ   r�   r    r¦   rV   r²   r°   rµ   r¶   rº   r†   r_   r_   r_   r`   r*   4   s>     	+%
A

.r*   )6rÁ   rb   Ú	threadingr   r   r   rg   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   Ú
exceptionsr   r   r   r   r   Zprotocol.formatters.standardr   Zprotocol.rfc4511r   Zprotocol.rfc4512r   r    rK   r!   Z	utils.logr"   r#   r$   r%   r&   Z
utils.convr'   Úurllib.parser(   ÚImportErrorÚurllibr)   r7   rh   r*   r_   r_   r_   r`   Ú<module>   s*   H
