HEX
Server: LiteSpeed
System: Linux shams.tasjeel.ae 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 11 08:09:09 EST 2025 x86_64
User: infowars (1469)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //usr/lib/python3.9/site-packages/ipapython/__pycache__/ipautil.cpython-39.pyc
a

�N(iS��@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlmZddlmZmZddlZddlZddlZddlZddlmZzddl Z Wne!�ydZ Yn0ddl"m#Z#ddl$m%Z%ddl&m'Z'm(Z(e�)e*�Z+d	Z,ej-d
ej.diZ/e�0dd
dg�Z1Gdd�dej2�Z3Gdd�de3�Z4Gdd�de4�Z5Gdd�de6�Z7dd�Z8dxdd�Z9dd�Z:dd�Z;dd �Z<d!d"�Z=d#d$�Z>d%d&�Z?d'd(�Z@d)d*�ZAGd+d,�d,e�0d,d-��ZBGd.d/�d/ejC�ZCdyd3d4�ZDd5d6�ZEd7d8�ZFd9d:�ZGGd;d<�d<eH�ZIGd=d>�d>ejJ�ZKd?d@�ZLdzdCdD�ZMd{dEdF�ZNej-dd2ejOfdGdH�ZPej-fdIdJ�ZQeH�eH�dfdKdL�ZReH�eH�fdMdN�ZSeH�eH�fdOdP�ZTd|dQdR�ZUd}dSdT�ZVdUdV�ZWdWdX�ZXed~dYdZ��ZYedd\d]��ZZej[�r4d^d_�Z\ne	j\Z\d`da�Z]dbdc�Z^ddde�Z_Gdfdg�dge`�Zadhdi�Zbd�djdk�Zcd�dldm�Zddndo�Zedpdq�Zfd�drds�ZgGdtdu�du�Zhdvdw�ZidS)��)�print_functionN)�contextmanager)�RawConfigParser�ParsingError)�input)�DN)�paths)�User�Group�ZtcpZudp�InterfaceDetails�name�ifnetcs>eZdZdZejZ�fdd�Z�fdd�Z�fdd�Z	�Z
S)�UnsafeIPAddressz-Any valid IP address with or without netmask.csBt|t�r,|j|_tt|�j||jd�dSt|tj�rXd|_tt|�j||jd�dSt|tj�r�||_tt|�j|jj	|jd�dSd|_t
|�}zdztj||jd�}WnJtjy�|�d�\}}}|dkrւtj||jd�}|j
dkr�Yn0Wn,t�y&tj|dd�|_|jj	}Yn0tt|�j||jd�dS)N)�flags�%�r)�
isinstancer�_net�super�__init__�netaddr_ip_flags�netaddr�	IPAddress�	IPNetwork�ip�str�AddrFormatError�	partition�version�
ValueError)�self�addr�sepZ_foo��	__class__��5/usr/lib/python3.9/site-packages/ipapython/ipautil.pyrVsH
���
�zUnsafeIPAddress.__init__cs|jtt|���d�}|S)N)r�super_state)rrr�__getstate__�r!�stater$r&r'r)s�zUnsafeIPAddress.__getstate__cs"tt|��|d�|d|_dS)Nr(r)rr�__setstate__rr*r$r&r'r,�szUnsafeIPAddress.__setstate__)�__name__�
__module__�__qualname__�__doc__rZ	INET_PTONrrr)r,�
__classcell__r&r&r$r'rNs
)rcsZeZdZdZd�fdd�	Z�fdd�Z�fdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
�ZS)�CheckedIPAddresszpIPv4 or IPv6 address with additional constraints.

    Reserved or link-local addresses are never accepted.
    TFc
sdztt|��|�Wn0tjjyD}zt|��WYd}~n
d}~00t|t�r\|j|_dS|st|j	rttd�
|���|jdvr�td�
|j���|s�|��r�td�
|���|��s�|�
�s�|tjjvr�td�
|���|��r�td�
|���|�s|���rtd�
|���|j	du�rV|jdk�r6t�t�t|���|_	n |jd	k�rVt�t|�d
�|_	|j	j|_dS)Nz.netmask and prefix length not allowed here: {})�rzunsupported IP version {}z!cannot use loopback IP address {}z&cannot use IANA reserved IP address {}z#cannot use link-local IP address {}z"cannot use multicast IP address {}r3rz/64)rr2rrZcorerr r�	prefixlenr�formatr�is_loopback�is_reservedrZ	IPV4_6TO4�
is_link_local�is_multicastrZcidr_abbrev_to_verboser)r!r"�
parse_netmask�allow_loopback�allow_multicast�er$r&r'r�sF

�

����zCheckedIPAddress.__init__cs|jtt|���d�}|S)N)r4r()r4rr2r)r*r$r&r'r)�s�zCheckedIPAddress.__getstate__cs"tt|��|d�|d|_dS)Nr(r4)rr2r,r4r*r$r&r'r,�szCheckedIPAddress.__setstate__cCs||jjkS�N)r�network�r!r&r&r'�is_network_addr�sz CheckedIPAddress.is_network_addrcCs|jdko||jjkS)Nr3)rr�	broadcastr@r&r&r'�is_broadcast_addr�sz"CheckedIPAddress.is_broadcast_addrcCs�tdurtd��t�d|�|jdkr.tj}n"|jdkr@tj}ntd�|j���t�	�D]�}t�
|��|g�D]l}|d�dd	�d
}|d�d�d
}dj||d�}t�d||�t
�|�}|j|krnt||�SqnqXdS)z�Find matching local interface for address
        :return: InterfaceDetails named tuple or None if no interface has
        this address
        N�	netifacesz,Searching for an interface of IP address: %sr3rzUnsupported address family ({})r"r�r�netmask�/���z{addr}/{netmask})r"rFz,Testing local IP address: %s (interface: %s))rD�ImportError�logger�debugr�AF_INET�AF_INET6r r5Z
interfacesZifaddresses�get�splitrrrr)r!ZfamilyZ	interfaceZifdataZifaddrZifmaskZ
ifaddrmaskrr&r&r'�get_matching_interface�s4


���

z'CheckedIPAddress.get_matching_interfacecCst|tj�sJ�||_dS)aSet IP Network details for this address. IPNetwork is valid only
        locally, so this should be set only for local IP addresses

        :param ifnet: netaddr.IPNetwork object with information about IP
        network where particula address belongs locally
        N)rrrr)r!rr&r&r'�
set_ip_net�szCheckedIPAddress.set_ip_net)TFF)r-r.r/r0rr)r,rArCrPrQr1r&r&r$r'r2�s�(+r2cs"eZdZdZd�fdd�	Z�ZS)�CheckedIPAddressLoopbackz�IPv4 or IPv6 address with additional constraints with
    possibility to use a loopback IP.
    Reserved or link-local addresses are never accepted.
    TFcs8tt|�j|||dd�|��r4td�|�tjd�dS)NT)r:r<r;z(WARNING: You are using a loopback IP: {})�file)rrRrr6�printr5�sys�stderr)r!r"r:r<r$r&r'rs
�
�z!CheckedIPAddressLoopback.__init__)TF)r-r.r/r0rr1r&r&r$r'rR�srRc@seZdZdZdd�ZdS)�IPAddressDoTForwarderz~IPv4 or IPv6 address with added hostname as needed for DNS over TLS
    configuration. Example: 1.2.3.4#dns.hostname.test
    cCs.|�d�}t|�dks"t|d�s*td��dS)N�#�rzBDoT forwarder must be in the format of '1.2.3.4#dns.example.test'.)rO�len�valid_ipr )r!r"Z
addr_splitr&r&r'rs

�zIPAddressDoTForwarder.__init__N)r-r.r/r0rr&r&r&r'rWsrWcCst�|�pt�|�Sr>)rZ
valid_ipv4Z
valid_ipv6)r"r&r&r'r[sr[cCsXt|�}zt�tj|�d|}Wntjy6Yn0|durD|Sd|t|�fSdS)z�
    Format network location (host:port).

    If the host part is a literal IPv6 address, it must be enclosed in square
    brackets (RFC 2732).
    z[%s]Nz%s:%s)r�socketZ	inet_ptonrM�error)�host�portr&r&r'�
format_netloc"sr`cCs |�d�}tdd�|D��}|S)z)Convert a kerberos realm to a IPA suffix.�.cSsg|]}d|��f�qS)Zdc)�lower��.0�xr&r&r'�
<listcomp>7�z#realm_to_suffix.<locals>.<listcomp>)rOr)Z
realm_name�s�	suffix_dnr&r&r'�realm_to_suffix4s
rjcCs&t|t�sJ�d�dd�|D��}|S)z)Convert a IPA suffix to a kerberos realm.racSsg|]
}|j�qSr&��valuercr&r&r'rf=rgz#suffix_to_realm.<locals>.<listcomp>)rr�join)ri�realmr&r&r'�suffix_to_realm:srocCs.t�|��|�}t�d�}|�dd�|�}|S)Nz(eval\s*\(([^()]*)\))cSstt|�d���S)NrY)r�eval�group)rer&r&r'�<lambda>Grgztemplate_str.<locals>.<lambda>)�stringZTemplateZ
substitute�re�compile�sub)�txt�vars�val�patternr&r&r'�template_str@s
r{cCs:t|��}t|��|�Wd�S1s,0YdS)z.Read a file and perform template substitutionsN)�openr{�read)�
infilenamerx�fr&r&r'�
template_fileKs
r�cCsBt||�}t|d��}|�|�Wd�n1s40YdS)z.Copy a file, performing template substitutions�wN)r�r|�write)r~ZoutfilenamerxrwrSr&r&r'�copy_template_filePs
r�cCs t�d�}|�|�|��|S)Nzw+)�tempfile�NamedTemporaryFiler��flush)rw�fdr&r&r'�write_tmp_fileWs

r�c	Csj|��t�|���tj�tj�|j��}t�|tj	tj
B�}zt�|�Wt�|�nt�|�0dS)zSFlush and fsync file to disk

    :param f: a file object with fileno and name
    N)r��os�fsync�fileno�path�dirname�abspathr
r|�O_RDONLY�O_DIRECTORY�close)rr��dirfdr&r&r'�
flush_sync_sr�cCs6t|t�rd|�dd�dSd|�dd�dSdS)N�'z'\''�'s'\'')rr�replace)rsr&r&r'�shell_quoteqs
r�c@seZdZdZdS)�
_RunResultzResult of ipautil.runN)r-r.r/r0r&r&r&r'r�xsr�zoutput error_output returncodecs.eZdZdZd�fdd�	Zdd�ZeZ�ZS)�CalledProcessErrorzqCalledProcessError with stderr

    Hold stderr of failed call and print it in repr() to simplify debugging.
    Ncstt|��|||�||_dSr>)rr�rrV)r!�
returncode�cmd�outputrVr$r&r'r�szCalledProcessError.__init__cCsN|jjd�|j�d�|j�g}|jdur:|�d�|j��|�d�d�|�S)Nz(Command {!s} z"returned non-zero exit status {!r}z: {!r}�)�)r%r-r5r�r�rV�appendrm)r!�argsr&r&r'�__str__�s
�
�

zCalledProcessError.__str__)NN)r-r.r/r0rr��__repr__r1r&r&r$r'r�}sr�Tr&Fc
s~t|	ttf�sJ�d}d}d}t|t�r0td��|rD|s<|
rDtd��|rX|sP|
rXtd��|rh|rhtd��|dur�t�tj�}d|d<|r�t	j
}|r�ttjd�}}n|r�t
j}t
j}nt	j
}t	j
}|dur�t��}tjr�t|t�r�|�|�}tt|�|�}t�d	�t�d
|��du�rtt���dd�|	D�}	d
d�|	D��t�d��j�j�|	�rt|	D]}t�d||j��q\�du�s��du�r����fdd�}nd}z�z,t	j||||d|||d�}|�|�\}}WnFt�y�t�d�|� ��Yn t!�yt�d��Yn0W|�r6|�"�n|�r4|�"�0t�d|j#�|�sP|�rZd}d}n�tj�rv|j$t��dd�}n|}tj�r�|j$t��dd�}n|}t||�}|�r�t�d�nt�d|�t||�}|�r�t�d�nt�d|�|�r
tj%�r�|}n
|�$|�}nd}|
�r.tj%�r"|}n
|�$|�}nd}|j#dk�rT|�rTt&|j#|||��t'|||j#�}||_(||_)||_*||_+|S)a�

    Execute an external command.

    :param args: List of arguments for the command
    :param stdin: Optional input to the command
    :param raiseonerr: If True, raises an exception if the return code is
        not zero
    :param nolog: Tuple of strings that shouldn't be logged, like passwords.
        Each tuple consists of a string to be replaced by XXXXXXXX.

        Example:
        We have a command
            ['/usr/bin/setpasswd', '--password', 'Secret123', 'someuser']
        and we don't want to log the password so nolog would be set to:
        ('Secret123',)
        The resulting log output would be:

        /usr/bin/setpasswd --password XXXXXXXX someuser

        If a value isn't found in the list it is silently ignored.
    :param env: Dictionary of environment variables passed to the command.
        When None, current environment is copied
    :param capture_output: Capture stdout
    :param skip_output: Redirect the output to /dev/null and do not log it
    :param cwd: Current working directory
    :param runas: Name or User object of a user that the command should be
        run as. The spawned process will have both real and effective UID and
        GID set.
    :param suplementary_groups: List of group names or Group object that will
        be used as suplementary groups for subporcess. The option runas must
        be specified together with this option.
    :param capture_error: Capture stderr
    :param nolog_output: do not log stdout even if it is being captured
    :param nolog_error: do not log stderr even if it is being captured
    :param encoding: For Python 3, the encoding to use for output,
        error_output, and (if it's not bytes) stdin.
        If None, the current encoding according to locale is used.
    :param redirect_output: Redirect (error) output to standard (error) output.
    :param umask: Set file-creation mask before running the command.

    :return: An object with these attributes:

        `returncode`: The process' exit status

        `output` and `error_output`: captured output, as strings. Under
        Python 3, these are encoded with the given `encoding`.
        None unless `capture_output` or `capture_error`, respectively, are
        given

        `raw_output`, `raw_error_output`: captured output, as bytes.

        `output_log` and `error_log`: The captured output, as strings, with any
        unencodable characters discarded. These should only be used
        for logging or error messages.

    If skip_output is given, all output-related attributes on the result
    (that is, all except `returncode`) are None.

    For backwards compatibility, the return value can also be used as a
    (output, error_output, returncode) triple.
    Nz!nolog must be a tuple of strings.z@skip_output is incompatible with capture_output or capture_errorzDredirect_output is incompatible with capture_output or capture_errorz0skip_output is incompatible with redirect_outputzB/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:/usr/bin:/usr/sbin�PATHr�zStarting external processzargs=%scSsg|]}t|��qSr&)r
�rdrqr&r&r'rf	rgzrun.<locals>.<listcomp>cSsg|]
}|j�qSr&)�gidr�r&r&r'rf
rgzrunas=%s (UID %d, GID %s)zsupplementary_group=%s (GID %d)csH�dur2t���t��j�j�t��j�j��durDt���dSr>)r��	setgroups�setregid�pgid�setreuid�uid�umaskr&��runasZsuplementary_gidsr�r&r'�
preexec_fns
zrun.<locals>.preexec_fnT)�stdin�stdoutrVZ	close_fds�env�cwdr�zProcess interruptedzProcess execution failedz Process finished, return code=%sr�)�errorszstdout=<REDACTED>z	stdout=%szstderr=<REDACTED>z	stderr=%sr),r�tuple�listrr �copy�deepcopyr��environ�
subprocess�PIPEr|�devnullrUr�rV�locale�getpreferredencoding�sixZPY3�encode�
nolog_replace�reprrJrKr	r�r�r��PopenZcommunicate�KeyboardInterrupt�wait�
BaseExceptionr�r��decode�PY2r�r�Z
raw_outputZraw_error_output�
output_log�	error_log)r�r�Z
raiseonerr�nologr�Zcapture_outputZskip_outputr�r�Zsuplementary_groupsZ
capture_error�encodingZredirect_outputr�Znolog_outputZnolog_errorZp_inZp_outZp_err�
arg_stringrqr��pr�rVr�r�r�Zerror_output�resultr&r�r'�run�s�B



��	�



�

�
�


�r�cCsN|D]D}|rt|t�sqtj�|�}t|�}|||fD]}|�|d�}q6q|S)z<Replace occurences of strings given in `nolog` with XXXXXXXXZXXXXXXXX)rr�urllib�parse�quoter�r�)rsr�rlZquotedZshquotedZnolog_valuer&r&r'r�psr�cCs6tj�|�rt�||d�t�||�t�|�dS�Nz.orig)r�r��isfile�rename�shutilr��remove)�fname�destr&r&r'�install_file}sr�cCs tj�|�rt�||d�dSr�)r�r�r�r�)r�r&r&r'�backup_file�sr�cs�eZdZdZd1�fdd�	Z�fdd�Zd2�fdd�	Z�fd	d
�Zd3dd�Z�fd
d�Z	e
jrh�fdd�Zd4dd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd5d#d$�Zd%d&�Z�fd'd(�Z�fd)d*�Zd+d,�Zd-d.�Zd/d0�Z�ZS)6�CIDicta>
    Case-insensitive but case-respecting dictionary.

    This code is derived from python-ldap's cidict.py module,
    written by stroeder: http://python-ldap.sourceforge.net/

    This version extends 'dict' so it works properly with TurboGears.
    If you extend UserDict, isinstance(foo, dict) returns false.
    Ncs4tt|���i|_|r"|�|�|r0|�|�dSr>)rr�r�_keys�update)r!�default�kwargsr$r&r'r�s
zCIDict.__init__cstt|��|���Sr>)rr��__getitem__rb�r!�keyr$r&r'r��szCIDict.__getitem__csJ|��}|dur.||vr$td|��|�|�||j|<tt|��||�S)z�cidict[key] = value

        The ``seen_keys`` argument is used by ``update()`` to keep track of
        duplicate keys. It should be an initially empty set that is
        passed to all calls to __setitem__ that should not set duplicate keys.
        NzDuplicate key in update: %s)rbr �addr�rr��__setitem__)r!r�rlZ	seen_keys�	lower_keyr$r&r'r��s

zCIDict.__setitem__cs |��}|j|=tt|��|�Sr>)rbr�rr��__delitem__)r!r�r�r$r&r'r��szCIDict.__delitem__cKs~t�}|rTz
|j}Wn ty4|�t|��Yn 0|�D]}|�||||�q<t�}|��D]\}}|�|||�qbdS)z�Update self from dict/iterable new and kwargs

        Functions like ``dict.update()``.

        Neither ``new`` nor ``kwargs`` may contain two keys that only differ in
        case, as this situation would result in loss of data.
        N)�set�keys�AttributeErrorr��dictr��items)r!�newr��seenr�r�rlr&r&r'r��s

z
CIDict.updatecstt|��|���Sr>)rr��__contains__rbr�r$r&r'r��szCIDict.__contains__cstt|��|���Sr>)rr��has_keyrbr�r$r&r'r��szCIDict.has_keycCs&z
||WSty |YS0dSr>��KeyError)r!r�Zfailobjr&r&r'rN�s
z
CIDict.getcCst�|j�Sr>�r��
itervaluesr�r@r&r&r'�__iter__�szCIDict.__iter__cCstjrt|���S|��SdSr>)r�r�r��iterkeysr@r&r&r'r��szCIDict.keyscCstjrt|���S|��SdSr>)r�r�r��	iteritemsr@r&r&r'r��szCIDict.itemscCstjrt|���S|��SdSr>)r�r�r�r�r@r&r&r'�values�sz
CIDict.valuescCstt|����S)z%Returns a shallow copy of this CIDict)r�r�r�r@r&r&r'r��szCIDict.copycs�fdd�t��j�D�S)Nc3s|]}|�|fVqdSr>r&)rd�kr@r&r'�	<genexpr>�rgz#CIDict.iteritems.<locals>.<genexpr>r�r@r&r@r'r��szCIDict.iteritemscCst�|j�Sr>r�r@r&r&r'r��szCIDict.iterkeyscCsdd�t�|�D�S)Ncss|]\}}|VqdSr>r&)rdr��vr&r&r'r��rgz$CIDict.itervalues.<locals>.<genexpr>)r�r�r@r&r&r'r��szCIDict.itervaluescCs.z
||WSty(|||<|YS0dSr>r�)r!r�rlr&r&r'�
setdefault�s

zCIDict.setdefaultcGsFz||}||=|WSty@t|�dkr:|dYS�Yn0dS)NrEr)r�rZ)r!r�r�rlr&r&r'�popsz
CIDict.popcs,tt|���\}}|j|}|j|=||fSr>)rr��popitemr�)r!r�rlr�r$r&r'r�
s
zCIDict.popitemcs|j��tt|���Sr>)r��clearrr�r@r$r&r'r�s
zCIDict.clearcCstd��dS)Nz#CIDict.viewitems is not implemented��NotImplementedErrorr@r&r&r'�	viewitemsszCIDict.viewitemscCstd��dS)Nz"CIDict.viewkeys is not implementedrr@r&r&r'�viewkeysszCIDict.viewkeyscCstd��dS)Nz%CIDict.viewvvalues is not implementedrr@r&r&r'�viewvvaluesszCIDict.viewvvalues)N)N)N)N)N)r-r.r/r0rr�r�r�r�r�r�r�r�rNr�r�r�r�r�r�r�r�r�r�r�r�rrrr1r&r&r$r'r��s2




r�cs:eZdZdZd�fdd�	Zdd�Zdd�Zd	d
�Z�ZS)�GeneralizedTimeZonezrThis class is a basic timezone wrapper for the offset specified
       in a Generalized Time.  It is dst-ignorant.�Zcs�tt|���||_d|_d|_|dkr6d|_d|_n~t|�dkrlt�d|�rlt	|dd��|_|dd�}t|�dkr�t�d|�r�t	|dd��|_|dd�}t|�dkr�t
��|jdkr�|jd9_dS)Nrr�z[-+]\d\drYz\d\drH)rrrr
�
houroffset�	minoffsetrZrt�match�intr )r!Z	offsetstrr$r&r'r%s"
zGeneralizedTimeZone.__init__cCstj|j|jd�S)N)ZhoursZminutes)�datetime�	timedeltarr	)r!Zdtr&r&r'�	utcoffset;szGeneralizedTimeZone.utcoffsetcCs
t�d�S�Nr)rr
r@r&r&r'�dst>szGeneralizedTimeZone.dstcCs|jSr>)r
r@r&r&r'�tznameAszGeneralizedTimeZone.tzname)r)	r-r.r/r0rrrrr1r&r&r$r'r"s
rc
Cs
t|�dkrdS�z�|dd�}|dd�}t|dd��}t|dd��}t|dd��}d}}}}	d}
t|�dk�r<t�d|d��r<t|dd��}|dd�}t|�dk�r<|ddks�|dd	k�r<d	}|d
d�}t|�dk�rt�d|d��r||d7}|d
d�}q�tt|�d�}t|d�\}}t|�dk�r�t�d|d��r�t|dd��}|dd�}t|�dk�r�|ddk�s�|dd	k�r�d	}
|d
d�}t|�dk�r�t�d|d��r�|
|d7}
|d
d�}�q�tt|
�d�}t|�dk�r�t�d|d��r�t|dd��}|dd�}t|�dk�r�|ddk�sd|dd	k�r�d	}|d
d�}t|�dk�r�t�d|d��r�||d7}|d
d�}�qttt|�d
�}	t|�dk�r�t|�}
t�|||||||	|
�WSt�yYdS0dS)a>Parses are Generalized Time string (as specified in X.680),
       returning a datetime object.  Generalized Times are stored inside
       the krbPasswordExpiration attribute in LDAP.

       This method doesn't attempt to be perfect wrt timezones.  If python
       can't be bothered to implement them, how can we...�Nr3rrrYz\d�,rarEi�<i@B)	rZrrtr
�float�divmodrrr )Ztimestr�date�timeZyearZmonthZdayZhour�minZsecZmsecZtzoneZ
hour_fractionZ
total_secsZmin_fractionZsec_fractionr&r&r'�parse_generalized_timeEs\ (  *  * r�rEcsdd}tjt�ttj�d�d�tjt�ttj�d�d�tjt�ttj�d�d�|t�t|�d�d�d�}t||||d��dd��fdd�|�	�D��i|d	<t�t|d	d�d�|d	d
<t
��}|}	d}
dD]N}||}�|}
|
dur�q�|
d
kr�|
|�|d�7}
|	|d
8}	|
d8}
q�q�|d	}|	d
k�s>t|
�|k�r`|
|�|d�7}
|	|d
8}	�q&|
S)a�
    Generate token containing at least `entropy_bits` bits and with the given
    character restraints.

    :param entropy_bits:
        The minimal number of entropy bits attacker has to guess:
           128 bits entropy: secure
           256 bits of entropy: secure enough if you care about quantum
                                computers

    Integer values specify minimal number of characters from given
    character class and length.
    Value None prevents given character from appearing in the token.

    Example:
    TokenGenerator(uppercase=3, lowercase=3, digits=0, special=None)

    At least 3 upper and 3 lower case ASCII chars, may contain digits,
    no special chars.
    z!$%&()*+,-./:;<>?@[]^_{|}~rY)�chars�entropy)�	uppercase�	lowercase�digits�specialrr�cs$g|]\}}�|dur|d�qS)Nrr&)rd�charclass_name�	charclass�Zreq_classesr&r'rf�s�z)ipa_generate_password.<locals>.<listcomp>�allr)r rrr!NrrE)
rsZascii_uppercase�math�logrZZascii_lowercaser r�rmr��randomZSystemRandom�choice)Zentropy_bitsrrr r!Zmin_lenZ
special_charsZpwd_charsetsZrndZtodo_entropy�passwordr"r#Ztodo_charactersZallcharsr&r$r'�ipa_generate_password�sX������	���r+cCs�|durVz&td|�}|s"|��r,|��WSWqtyR|rFYdStd��Yq0qt|t�r�z8td||f�}|s�|s~|r�|WS|��r�|��WSWq`ty�|YS0q`t|t��r<|r�dnd}zVtd||f�}|��}|s�|WS|��ddk�rWd	S|��dd
k�rWdSWq�t�y8|YS0q�t|t��r�z0td||f�}|��}|�sn|WSt|�}Wn*t	�y�Ynt�y�|YS0|S�qHdS)Nz%s: r�zFailed to get user inputz	%s [%s]: Zyes�nor�yT�nF)
r�strip�EOFError�RuntimeErrorrr�boolrbrr )�promptr�Zallow_empty�retr)r&r&r'�
user_input�sX


r5c
Cs�d}t�||tj|�D]�}|\}}	}
}}d}
z�zLt�||	|
�}
|durP|
�|�|
�|�|tjkrx|
�d�|
�d�WnBtjy�d}|r�dt	|t
||dd�}t�||�Yn0W|
dur�|
�
�q|
dur�|
�
�0q|S)	z�
    host: either hostname or IP address;
          if hostname is provided, port MUST be open on ALL resolved IPs

    returns True is port is open, False otherwise
    TNrgiFz8Failed to connect to port %(port)s %(proto)s on %(addr)sr)r_�protor")r\ZgetaddrinfoZ	AF_UNSPECZ
settimeout�connect�
SOCK_DGRAM�sendZrecvr]r��PROTOCOL_NAMESrJr'r�)r^r_�socket_typeZsocket_timeout�
log_errorsZ	log_level�	port_open�res�afZsocktyper6Z
_canonnameZsarh�msgr&r&r'�host_port_opens6	



��
�rAc
Cs(|tjkrd}n|tjkr d}nt|��z"t�tj|�}d}t�d|�Wn2tjy|t�tj|�}d}t�d|�Yn0z�z.|tjkr�|�	tj
tjd�|�||f�WnBtjy�}z(t�d|||�WYd	}~W|�
�d
Sd	}~00t�d||�W|�
�dSW|�
�n
|�
�0d	S)z�Check if a port is free and not bound by any other application

    :param port: port number
    :param socket_type: type (SOCK_STREAM for TCP, SOCK_DGRAM for UDP)

    Returns True if the port is free, False otherwise
    ZTCPZUDPz::z9check_port_bindable: Checking IPv4/IPv6 dual stack and %sr�z.check_port_bindable: Checking IPv4 only and %sTz5check_port_bindable: failed to bind to port %i/%s: %sNFz(check_port_bindable: bind success: %i/%s)r\�SOCK_STREAMr8r rMrJrKr]rLZ
setsockoptZ
SOL_SOCKETZSO_REUSEADDRZbindr�)r_r;r6rhZanyaddrr=r&r&r'�check_port_bindable;sF

�
����rCc	Cst�dtj�}t�|�}t�}d}tjddd����}|j}t	|d���}	|	D]�}
|
}|�
|
�}|�r
|�dd�\}
}|
du�r
|r�|
|vr�d	|
||
f}|||
<|r�|
|vr�|s�d	|
||
f}n$|�||
�d
kr�d|
|||
f}|||
<|�r
|
|v�r
|||
<d}|durJ|�
|�qJWd�n1�s40Y|��}|�|�t|���t|���}t|���|}|D]}|�
d	|||f��q||D]}|�
d	|||f��q�|��t�|��|j�t�|��|j|j�Wd�n1�s0Yt||�|S)a�
    Take a key=value based configuration file, and write new version
    with certain values replaced, appended, or removed.

    All (key,value) pairs from replacevars and appendvars that were not found
    in the configuration file, will be added there.

    All entries in set removevars are removed.

    It is responsibility of a caller to ensure that replacevars and
    appendvars do not overlap.

    It is responsibility of a caller to back up file.

    returns dictionary of affected keys and their previous values

    One have to run restore_context(filepath) afterwards or
    security context of the file will not be correct after modification
    z�
(^
                        \s*
        (?P<option>     [^\#;]+?)
                        (\s*=\s*)
        (?P<value>      .+?)?
                        (\s*((\#|;).*)?)?
$)Nr�F��mode�delete�r�optionrl�%s=%s
rH�	%s=%s %s
)rtru�VERBOSEr��statr�r�r�r
r|r
rq�findr�r�r�r�r�r��fchmodr��st_mode�fchown�st_uid�st_gidr�)�filepath�replacevars�
appendvarsZ
removevarsrz�	orig_stat�
old_values�
temp_filename�
new_configr�line�new_line�mrHrl�new_vars�newvars_view�append_view�itemr&r&r'�config_replace_variableslsT�


,
6
rac	Cst�dtj�}dd�}t�|�}t�}d}tjddd����}	|	j}t	|d���`}
d}d}d	}
|
D�]}|
d	}
|}|�
|�}|r`|�d
dd�\}}}|r�|dur�||	|||�d
}|dur�t|��
�t|��
�k}|du�r`|�r`|�r
||v�r
d|||f}|||<|�r`||v�r`|�s2d|||f}n&|�||�dk�rXd||||f}|||<|	�|�q`|�s�|�s�|	�d|�|�s�|�s�||	|||�Wd�n1�s�0Y|	��t�|	��|j�t�|	��|j|j�Wd�n1�s0Yt||�|S)a�
    Take a section-structured key=value based configuration file, and write new version
    with certain values replaced or appended within the section

    All (key,value) pairs from replacevars and appendvars that were not found
    in the configuration file, will be added there.

    It is responsibility of a caller to ensure that replacevars and
    appendvars do not overlap.

    It is responsibility of a caller to back up file.

    returns dictionary of affected keys and their previous values

    One have to run restore_context(filepath) afterwards or
    security context of the file will not be correct after modification
    a
(^
                        \[
        (?P<section>    .+) \]
                        (\s+((\#|;).*)?)?
$)|(^
                        \s*
        (?P<option>     [^\#;]+?)
                        (\s*=\s*)
        (?P<value>      .+?)?
                        (\s*((\#|;).*)?)?
$)cSs~|��}|�|�t|���t|���}t|���|}|D]}|�d|||f�q>|D]}|�d|||f�q^dS)NrI)r�r�r�r�r�)ZconfigrTrUZoldvarsr]r^r_r`r&r&r'�add_options�s
z.inifile_replace_variables.<locals>.add_optionsNr�FrDrGrE�sectionrHrlTrIrHrJz[%s]
)rtrurKr�rLr�r�r�r
r|r
rqrrbrMr�r�rNr�rOrPrQrRr�)rSrcrTrUrzrbrVrWrXrYrZ
in_section�finishedZline_idxrZr[r\ZsectrHrlr&r&r'�inifile_replace_variables�sX�


.6
recCs|�|�t|||�}|S)aj
    Take a key=value based configuration file, back up it, and
    write new version with certain values replaced or appended

    All (key,value) pairs from replacevars and appendvars that
    were not found in the configuration file, will be added there.
    The file must exist before this function is called.

    It is responsibility of a caller to ensure that replacevars and
    appendvars do not overlap.

    returns dictionary of affected keys and their previous values

    One have to run restore_context(filepath) afterwards or
    security context of the file will not be correct after modification
    )r�ra)ZfstorerSrTrUrWr&r&r'�#backup_config_and_replace_variabless
rfcCs�t|�}t|ttf�s|g}t�d|||�t��|}|D]^}t�d|�d}t|||d�}d}|rtt�d|�q<|r�t��|kr�t�	d��t�
d�qPq<d	S)
z�
    Wait until the specified port(s) on the remote host are open. Timeout
    in seconds may be specified to limit the wait. If the timeout is
    exceeded, socket.timeout exception is raised.
    z%wait_for_open_ports: %s %s timeout %dzwaiting for port: %sT)r<FzSUCCESS: port: %szTimeout exceededrEN)rrr�r�rJrKrrAr\�timeout�sleep)r^Zportsrg�
op_timeoutr_Z	log_errorr=r&r&r'�wait_for_open_ports5s 
rjc
Cs�t|�}t��|}z&t�tj�}|�|�|��Wq�Wqtjy�}z:|jdvrv|rjt��|krj|�t�d�n|�WYd}~qd}~00qdS)z
    Wait until the specified socket on the local host is open. Timeout
    in seconds may be specified to limit the wait.
    )rY�orEN)	rrr\ZAF_UNIXr7r�r]�errnorh)Zsocket_namergrirhr=r&r&r'�wait_for_open_socketQs

rmcs"�fdd�}�fdd�}t||�S)a8
    Create a property for a dn attribute which assures the attribute
    is a DN or None. If the value is not None the setter converts it to
    a DN. The getter assures it's either None or a DN instance.

    The private_name parameter is the class internal attribute the property
    shadows.

    For example if a class has an attribute called base_dn, then:

        base_dn = dn_attribute_property('_base_dn')

    Thus the class with have an attriubte called base_dn which can only
    ever be None or a DN instance. The actual value is stored in _base_dn.
    cs |durt|�}t|�|�dSr>)r�setattr�r!rl��private_namer&r'�setterysz%dn_attribute_property.<locals>.settercs$t|��}|dur t|t�s J�|Sr>)�getattrrrrorpr&r'�getter~s
z%dn_attribute_property.<locals>.getter)�property)rqrrrtr&rpr'�dn_attribute_propertyhsrvcCs.dd�}|�dd�}d�t||��}|�d�S)a�
    Convert a string to a more strict alpha-numeric representation.

    - Alpha-numeric, underscore, dot and dash characters are accepted
    - Space is converted to underscore
    - Other characters are omitted
    - Leading dash is stripped

    Note: This mapping is not one-to-one and may map different input to the
    same result. When using posixify, make sure the you do not map two different
    entities to one unintentionally.
    cSs|��p|dvS)N)�_ra�-)�isalnum)�charr&r&r'�
valid_char�szposixify.<locals>.valid_char� rwr�rx)r�rm�filter�lstrip)rsr{ZreplacedZomittedr&r&r'�posixify�srccs|dur$tjdd�}tj�|d�}nd}tj�dd�}|tjd<zl|VW|dur^|tjd<ntj�dd�tj�|�r�t�	|�|dur�zt�
|�Wnty�Yn0nh|dur�|tjd<ntj�dd�tj�|�r�t�	|�|du�rzt�
|�Wnt�yYn00dS)NZkrbcc)�prefixZccacheZ
KRB5CCNAME)r�Zmkdtempr�r�rmr�rNr��existsr��rmdir�OSError)r�Zdir_path�original_valuer&r&r'�private_ccache�s8

�

r��/run/ipac	
csHtj}d}|r�t�d�|��|f}tj|ddd�\}}tj|ddd��}|�	|�Wd�n1sh0Yd	�
||g�}tj�
d
d�}|tjd
<zbz
|VWnty�Yn0W|dur�|tjd
<ntj�d
d�|dur�tj�|�r�t�|�nH|du�r|tjd
<ntj�d
d�|du�rBtj�|��rBt�|�0dS)a�Generate override krb5 config file for a trusted domain DC access
    Provide a context where environment variable KRB5_CONFIG is set
    with the overlay on top of paths.KRB5_CONF. Overlay's file path
    is passed to the context in case it is needed for something else

    :param realm: realm of the trusted AD domain
    :param server: server to override KDC to
    :param dir: path where to create a temporary krb5.conf overlay
    Nze
            [realms]
               %s = {
                   kdc = %s
               }
            Zkrb5confT)�dirr��textr��utf-8)rEr��:ZKRB5_CONFIG)rZ	KRB5_CONF�textwrap�dedent�upperr�Zmkstemp�ior|r�rmr�r�rN�
GeneratorExitr�r�r�r�)	rnZserverr�ZcfgZtcfgZcontentr��or�r&r&r'�private_krb5_config�s8��
(

�
r�cCsFt|t�r|�t���St|t�r&|Std�tjtjt	|�j���dS)zw
        Decode argument using the file system encoding, as returned by
        `sys.getfilesystemencoding()`.
        zexpect {0} or {1}, not {2}N)
r�bytesr�rU�getfilesystemencodingr�	TypeErrorr5r-�typerkr&r&r'�fsdecode�s

�r�cs(t�d�����t��fdd�|D��S)z�
    unescape (remove '\') all occurences of sequence in input strings.

    :param seq: sequence to unescape
    :param args: input string to process

    :returns: tuple of strings with unescaped sequences
    z\\{}c3s|]}t���|�VqdSr>)rtrv�rd�a��seqZunescape_rer&r'r�
rgzunescape_seq.<locals>.<genexpr>)rtrur5r��r�r�r&r�r'�unescape_seq�s	r�cst�fdd�|D��S)z�
    escape (prepend '\') all occurences of sequence in input strings

    :param seq: sequence to escape
    :param args: input string to process

    :returns: tuple of strings with escaped sequences
    c3s |]}|��d����VqdS)z\{}N)r�r5r��r�r&r'r�rgzescape_seq.<locals>.<genexpr>)r�r�r&r�r'�
escape_seq
s
r�cCs&dd�}t|t�r|S|�||�d�S)abDecode JSON bytes to string with proper encoding

    Only for supporting Py 3.5

    Py 3.6 supports bytes as parameter for json.load, we can drop this when
    there is no need for python 3.5 anymore

    Code from:
        https://bugs.python.org/file43513/json_detect_encoding_3.patch

    :param data: JSON bytes
    :return: return JSON string
    cSs�|j}|tjtjf�rdS|tjtjf�r.dS|tj�r<dSt|�dkr�|ds`|dr\dSdS|ds�|d	sx|d
r|dSdSn$t|�d	kr�|ds�dS|ds�dSd
S)Nzutf-32zutf-16z	utf-8-sigr3rrEz	utf-16-bez	utf-32-berYrz	utf-16-lez	utf-32-ler�)�
startswith�codecs�BOM_UTF32_BE�BOM_UTF32_LE�BOM_UTF16_BE�BOM_UTF16_LE�BOM_UTF8rZ)�bZbstartswithr&r&r'�detect_encoding)s$
z$decode_json.<locals>.detect_encoding�
surrogatepass)rrr�)�datar�r&r&r'�decode_jsons
r�c@sLeZdZdZdZdd�Zdd�Zdd�Zd	d
�Ze	dd��Z
e	d
d��ZdS)�
APIVersionzzAPI version parser and handler

    The class is used to parse ipapython.version.API_VERSION and plugin
    versions.
    r&cCs8|�d�\}}}t|�}|r$t|�nd}t�|||f�S)Nrar)rrr��__new__)�clsr�major�dot�minorr&r&r'r�SszAPIVersion.__new__cCs
dj|�S)Nz{}.{}�r5r@r&r&r'r�YszAPIVersion.__str__cCs
dj|�S)Nz<APIVersion('{}.{}')>r�r@r&r&r'r�\szAPIVersion.__repr__cCs
t|�fSr>)rr@r&r&r'�__getnewargs___szAPIVersion.__getnewargs__cCs|dSrr&r@r&r&r'r�bszAPIVersion.majorcCs|dS)NrEr&r@r&r&r'r�fszAPIVersion.minorN)r-r.r/r0�	__slots__r�r�r�r�rur�r�r&r&r&r'r�Ks
r�c
Cshzt�d|�t�|�WnHtyb}z0|jtjkrNt�d||�t�d�WYd}~n
d}~00dS)z|
    Remove Kerberos keytab and issue a warning if the procedure fails

    :param keytab_path: path to the keytab file
    zRemoving service keytab: %sz)Failed to remove Kerberos keytab '%s': %sz"You may have to remove it manuallyN)rJrKr�r�r�rl�ENOENT�warning)Zkeytab_pathr=r&r&r'�
remove_keytabks�r�c
Cs|t�d�tjg}|dur4t�d|�|�d|g�zt||id�Wn0tyv}zt�d|�WYd}~n
d}~00dS)z�
    remove Kerberos credential cache, essentially a wrapper around kdestroy.

    :param ccache_path: path to the ccache file
    :param run_as: run kdestroy as this user
    z"Removing service credentials cacheNzCcache path: '%s'z-c)r�r�z.Failed to clear Kerberos credentials cache: %s)rJrKrZKDESTROY�extendr�r�r�)Zccache_pathZrun_asZkdestroy_cmdr=r&r&r'�
remove_ccache{s
�r�c
Cs�|r4tj�|�r4t�|�}|jdkr4t�d|�dSzt�|�WnHty�}z0t	|dd�t
jkrvt�d|t
|��WYd}~n
d}~00dS)zwRemove a file and log any exceptions raised.

       :only_if_empty: only remove the file if empty. Default False.
    rz%s is not empty.Nrl�Error removing %s: %s)r�r�r�rL�st_sizerJrK�unlink�	Exceptionrsrlr�r]r)�filenameZ
only_if_emptyZ	file_statr=r&r&r'�remove_file�s

r�c
CsVzt�|�WnBtyP}z*|jtjtjhvr<t�d|�WYd}~n
d}~00dS)zRemove an empty directory.zFailed to remove directory %sN)r�r�r�rlr�Z	ENOTEMPTYrJr])r�r=r&r&r'�remove_directory�s
r�c
CsVztj�|�rt�|�Wn6tyP}zt�d|t|��WYd}~n
d}~00dS)zE
    Remove a directory structure and log any exceptions raised.
    r�N)	r�r�r�r��rmtreer�rJr]r)r�r=r&r&r'r��s
r�cCsft|tj�rtt�|��}n t|ttf�r4t|�}nt|��tjdddtjj	d�}|tj
||d�S)a�
    Convert a timestamp or a time.struct_time to a datetime.datetime
    object down to seconds, with UTC timezone

    The conversion is safe for year 2038 problem

    :param t: int or float timestamp in (milli)seconds since UNIX epoch
              or time.struct_time
    :param units: normalizing factor for the timestamp
                  (1 for seconds, 1000 for milliseconds)
                  defaults to 1
    :return: datetime.datetime object in UTC timezone
    i�rE)�tzinfo)Zseconds)rr�struct_timer�mktimerr�r�timezoneZutcr
)�tZunitsr�Zepochr&r&r'�datetime_from_utctimestamp�s
r�c@s2eZdZdZdZdd�dd�Zdd�Zd	d
�ZdS)�Sleepera�Helper for time.sleep() loop with timeout

    A sleeper object sleeps *sleep* seconds when it is called. Close to its
    deadline it sleeps shorter to not oversleep the *timeout* deadline. A
    sleeper object is *True* and returns *True* before it reaches *timeout*
    deadline. After its deadline a sleeper raises the exception object/class
    in *raises*. If *raises* is not given, it returns False instead.

    sleep = Sleeper(sleep=1, timeout=60, raises=TimeoutError)
    while True:
        do_something()
        sleep()

    sleep = Sleeper(sleep=0.5, timeout=60)
    while True:
        do_something
        if not sleep():
            log.info("timeout")
            break

    longsleep = Sleeper(sleep=1, timeout=sys.maxsize)
    rYN)�raisescCsT|dkrtd|����|dkr.td|�d���||_||_||_t��|j|_dS)Nrzinvalid timeout g{�G�z�?zsleep duration z is too short.)r rgrhr�r�	monotonic�deadline)r!rhrgr�r&r&r'r�szSleeper.__init__cCst��|jkSr>)rr�r�r@r&r&r'�__bool__�szSleeper.__bool__cCsHt��}||jkr(|jdur$|j�ndSt|j||j�}t�|�dS)NFT)rr�r�r�rrh)r!ZnowZdurr&r&r'�__call__�s


zSleeper.__call__)r-r.r/r0Z
multiplierrr�r�r&r&r&r'r��s
r�cCsvd}tj�dddd|�}t�}z|�|�WntyBYdS0|�|�sRdS|�|d�sbdS|�|d��	�dkS)	a!A simplified version of ipalib/config in order to determine if the
       API should be bootstrapped in debug mode or not.

       A number of daemons setup logging, then bootstrap the API in order
       to capture the startup. This presents a chicken-and-egg problem
       over debug output.

       Debug is rather spammy and probably shouldn't be enabled by default
       but if some problem is occuring during startup we want a way to
       see that.

       So use this limited function to pluck out the debug value out of
       the system context config file (in_tree is not supported, another
       chicken-and-egg).

       This isn't more generalized for two reasons:
           1. There is currently only a need for 'debug'
           2. Type conversion. They will all be strings.
    �globalrG�etcZipaz%s.confFrK�true)
r�r�rmrr}rZhas_sectionZ
has_optionrNrb)�contextZCONFIG_SECTIONZconfig_file�parserr&r&r'�get_config_debugs
r�)N)NTr&NFFNNr&FNFNFF)rrErErErEr)NT)r)r)N)r�)NN)F)rE)jZ
__future__rr�Zloggingrsr�r�r(r&r�rUrlr�r�r\rtrrrr�r��
contextlibrZconfigparserrrr��collectionsr�r�Z	six.movesrrDrIZipapython.dnrZipaplatform.pathsrZipaplatform.constantsr	r
Z	getLoggerr-rJZTMP_PWD_ENTROPY_BITSrBr8r:�
namedtuplerrrr2rRrrWr[r`rjror{r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr+r5�DEBUGrArCrarerfrjrmrvrr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r&r&r&r'�<module>s�

���=t

��
]
#@�
U
8�
)1�
Nc�


/

1 

	
5