o
    ji8                     @   s   d Z ddlmZmZmZ ddlmZ ddlmZ dZ	dZ
dZdd Zd$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 Zd'ddZd'ddZd(dd Zd!d" Zd#S ))
    )	hexdigitsascii_lettersdigits   )SEQUENCE_TYPES)LDAPInvalidDnError   c           	      C   s   | sdS |rdnd}|  d\}}}|r&|r | | f}|S ||f}|S |r8| | d | |  }|S || d | | }|S )N  =)	partitionstrip)	ava	decomposeremove_spacespace_around_equalspace	attr_name_value	component r   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/ldap3/utils/dn.py_add_ava%   s   	r   Fc           	      C   s   g }d}d}| D ]>}|dkrd}n1|r|dkrd}n(|dkr-|r-| t|||| d}q|dkrBd|v rB| t|||| d}q||7 }q| t|||| |S )	ac  
    Convert an iterator to a list of dn parts
    if decompose=True return a list of tuple (one for each dn component) else return a list of strings
    if remove_space=True removes unneeded spaces
    if space_around_equal=True add spaces around equal in returned strings
    if separate_rdn=True consider multiple RDNs as different component of DN
    r
   F\Tr   +,r   )appendr   )	iteratorr   r   r   separate_rdndnr   escape_sequencecr   r   r   to_dn9   s(   
r$   c                 C   s   	 |  ||}|dkr	 |S |dkr| |d  dkr	 |S |dkrD| |d  dkrDd}| |d dd D ]
}|dkr>| }q4 |sD	 |S |d7 }qNTr   r	   r   r   )find)r!   charposescapedr#   r   r   r   _find_first_unescapedY   s&   r+   c                 C   s   	 |  |||}|dkr	 |S |dkr| |d  dkr	 |S |dkrE| |d  dkrEd}| |d dd D ]
}|dkr?| }q5 |sE	 |S ||k rNd}	 |S qr%   )rfind)r!   r(   startstopr*   r#   r   r   r   _find_last_unescapedn   s,   r/   c                 C   s   t | dd}t | dd}|dkr5||k s|dkr5t | d|d }||d kr5t| d||}| d | dfS |dkrVt | d|d }||d krVt| d||}| d | dfS | dfS )Nr   r   r   r&   r   r	   r
   )r+   r/   )r!   commaplusequalr   r   r   _get_next_ava   s   r3   Tc                 C   s   |  d}|dkra| |d  dkrU|r7| d|  }|r)t| |d d   n	| |d d   }||fS | d| }|rIt| |d d  n| |d d  }||fS |  d|d }|dks	d|rh| jfS | fS )Nr   r   r	   r   r
   )r'   r   _escape_attribute_value)r   escaper   r2   attribute_typeattribute_valuer   r   r   
_split_ava   s   
0(r8   c                 C   sz   | st d| dkrdS | D ]}|tv s$|tv s$|dks$t d| d q| d tv s1| d dkr;t d| d  d dS )	Nzattribute type not presentz<GUIDT-zcharacter 'z' not allowed in attribute typer   z2' not allowed as first character of attribute type)r   r   r   )r6   r#   r   r   r   _validate_attribute_type   s   r:   c                 C   s"  | sdS | d dkr'| D ]}|t vrtd| d qt| d dkr'td| d dkr1td	| dr?| d
s?tdt}| D ]C}|tkr]|dkrPt}qC|dv r\td| d qC|tkru|t v rht}qC|dv rot}qCtd| |tkr|t v rt}qCtd| qC|tkrtddS )NFr   #z
character z5 not allowed in hex representation of attribute valuer   z:hex representation must be in the form of <HEX><HEX> pairsr   z=SPACE must be escaped as leading character of attribute value\ z>SPACE must be escaped as trailing character of attribute valuer   	"#+,;<=> zspecial character z must be escaped "#+,;<=>\ zinvalid escaped character zinvalid final characterT)r   r   lenendswith	STATE_ANYSTATE_ESCAPESTATE_ESCAPE_HEX)r7   r#   stater   r   r   _validate_attribute_value   sF   rE   c                 C   s  | sdS | d dkr)d}t | d dkrd}|r%| D ]
}|tvr$d} nq|r)| S t}d}d}| D ][}|tkrN|dkr>t}q1|dv rI|d| 7 }q1||7 }q1|tkro|tv r[|}t}q1|d	v rh|d| 7 }t}q1|d
| 7 }q1|tkr|tv r|d| | 7 }n|d
| | 7 }d}t}q1|tkr|d
7 }n
|tkr|d
| 7 }|d dkrd| }|d dkrt |dkr|d dkr|d d d }|S )Nr
   r   r;   Tr   Fr   r=   r>   z\\r   r&   r	   r<   )r?   r   rA   rB   rC   )r7   	valid_hexr#   rD   r*   
tmp_bufferr   r   r   r4      s`   

$r4   c           	      C   s  g }g }| rLt | \}}| t|d d } t|dddks$t|dkr,|||f n|t|d  d |t|d  d  | |f|t|d < | s|D ]2\}}t|||\}}t|sdtd| t|sntd| ||||f | t|d d } qN|std|S )a  
    Parses a DN into syntactic components
    :param dn:
    :param escape:
    :param strip:
    :return:
    a list of tripels representing `attributeTypeAndValue` elements
    containing `attributeType`, `attributeValue` and the following separator (`COMMA` or `PLUS`) if given, else an empty `str`.
    in their original representation, still containing escapes or encoded as hex.
    r	   Nr   r   z%unable to validate attribute type in z&unable to validate attribute value in zempty dn)r3   r?   r+   r   r8   r:   r   rE   )	r!   r5   r   rdnsavasr   	separatorr6   r7   r   r   r   parse_dn"  s(   <	rL   c                 C   sT  t | trdd | D }|rdt|} nd|} |r g }nd}| dr0| dr0| }|S | dr>| dr>| }|S | drL| drL| }|S d	| vr|t| d
dD ]#}|ri||d |d |d f qV||d d |d  |d  7 }qV|S d	| v rd| vrt| 	d	dkrt
dd| v rd| vrt| 	ddkrt
d| }|S )z
    normalize and escape a dn, if dn is a sequence it is joined.
    the reverse parameter changes the join direction of the sequence
    c                 S   s   g | ]}|qS r   r   ).0rdnr   r   r   
<listcomp>P  s    zsafe_dn.<locals>.<listcomp>r   r
   z<GUID=>z<WKGUID=z<SID=@Tr5   r   r	   r   r   z@Active Directory User Principal Name must consist of name@domainr   zDActive Directory Domain Level Logon Name must consist of name\domain)
isinstancer   joinreversed
startswithr@   rL   r   r?   splitr   )r!   r   reverse
components
escaped_dnr   r   r   r   safe_dnJ  s:   

"""r[   c                 C   s   g }d}t | ddD ]2}|d dks|r<|r"||d |d f n||d d |d   |d dkr8d}q
d} nq
|rGtd	t|  |S )
ztReturns a list of rdn for the dn, usually there is only one rdn, but it can be more than one when the + sign is usedTrR   r   r   r   r	   r   Fzbad dn )rL   r   r   str)r!   r   escaped_rdnone_morer   r   r   r   safe_rdnp  s   r_   c                 C   sf   dD ]
}|  |d| } q| d dks| d dkr dd| f} | d dkr1d| dd d	f} | S )
zK
    Escape rdn characters to prevent injection according to RFC 4514.
    )	r   r   r   "<rP   ;r    r   r   r;   r   r
   r&   Nr<   )replacerT   )rN   r(   r   r   r   
escape_rdn  s   re   N)FFFF)r   )FT)FF)F)__doc__stringr   r   r   r
   r   core.exceptionsr   rA   rB   rC   r   r$   r+   r/   r3   r8   r:   rE   r4   rL   r[   r_   re   r   r   r   r   <module>   s(    
 

*
=
(
&