HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //proc/self/root/lib/python3.6/site-packages/ipapython/__pycache__/ipautil.cpython-36.opt-1.pyc
3

�d[e��@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlmZddlmZmZddlZddlZddlZddlZddlmZyddl Z Wne!k
�rdZ YnXddl"m#Z#ddl$m%Z%ddl&m'Z'm(Z(ej)e*�Z+d	Z,ej-d
ej.diZ/ej0dd
dg�Z1Gdd�dej2�Z3Gdd�de3�Z4Gdd�de4�Z5dd�Z6dsdd�Z7dd�Z8dd�Z9dd�Z:dd �Z;d!d"�Z<d#d$�Z=d%d&�Z>d'd(�Z?Gd)d*�d*ej0d*d+��Z@Gd,d-�d-ejA�ZAdd.fdd/d/ddfd/dd/dd/d/fd0d1�ZBd2d3�ZCd4d5�ZDd6d7�ZEGd8d9�d9eF�ZGGd:d;�d;ejH�ZId<d=�ZJdtd@dA�ZKdudBdC�ZLej-dd/ejMfdDdE�ZNej-fdFdG�ZOeF�eF�dfdHdI�ZPeF�eF�fdJdK�ZQeF�eF�fdLdM�ZRdvdNdO�ZSdwdPdQ�ZTdRdS�ZUdTdU�ZVedxdVdW��ZWedydYdZ��ZXejY�rDd[d\�ZZne	jZZZd]d^�Z[d_d`�Z\dadb�Z]Gdcdd�dde^�Z_dedf�Z`dzdgdh�Zadidj�Zbdkdl�Zcd{dmdn�ZdGdodp�dp�Zedqdr�ZfdS)|�)�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.csHt|t�r,|j|_tt|�j||jd�dSt|tj�rXd|_tt|�j||jd�dSt|tj�r�||_tt|�j|jj	|jd�dSd|_t
|�}yfytj||jd�}WnLtjk
r�|jd�\}}}|dkr؂tj||jd�}|j
dkr�YnXWn0tk
�r,tj||jd�|_|jj	}YnXtt|�j||jd�dS)N)�flags�%�)�
isinstancer�_net�super�__init__�netaddr_ip_flags�netaddr�	IPAddress�	IPNetwork�ip�str�AddrFormatError�	partition�version�
ValueError)�self�addr�sepZ_foo)�	__class__��/usr/lib/python3.6/ipautil.pyrVs@




zUnsafeIPAddress.__init__cs|jtt|�j�d�}|S)N)r�super_state)rrr�__getstate__)r!�state)r$r%r&r(szUnsafeIPAddress.__getstate__cs"tt|�j|d�|d|_dS)Nr'r)rr�__setstate__r)r!r))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.
    TFcshytt|�j|�Wn.tjjk
rB}zt|��WYdd}~XnXt|t�rZ|j|_dS|rt|j	rttdj
|���|jd
kr�tdj
|j���|r�|j�r�tdj
|���|j�r�|j
�s�|tjjkr�tdj
|���|j�r�tdj
|���|o�|j��r
tdj
|���|j	dk�rZ|jdk�r:tjtjt|���|_	n |jdk�rZtjt|�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 {}z/64)r1r)rr0rrZcorerr r�	prefixlenr�formatr�is_loopbackZis_reservedrZ	IPV4_6TO4Z
is_link_localZis_multicastrZcidr_abbrev_to_verboser)r!r"�
parse_netmask�allow_loopback�allow_multicast�e)r$r%r&r�s<

zCheckedIPAddress.__init__cs|jtt|�j�d�}|S)N)r2r')r2rr0r()r!r))r$r%r&r(�szCheckedIPAddress.__getstate__cs"tt|�j|d�|d|_dS)Nr'r2)rr0r*r2)r!r))r$r%r&r*�szCheckedIPAddress.__setstate__cCs||jjkS)N)rZnetwork)r!r%r%r&�is_network_addr�sz CheckedIPAddress.is_network_addrcCs|jdko||jjkS)Nr1)rrZ	broadcast)r!r%r%r&�is_broadcast_addr�sz"CheckedIPAddress.is_broadcast_addrcCs�tdkrtd��tjd|�|jdkr.tj}n"|jdkr@tj}ntdj|j���x�tj	�D]�}xztj
|�j|g�D]d}|djdd	�d
}|djd�d}d
j||d�}tjd||�t
j|�}|j|krrt||�SqrWqZWdS)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: %sr1rzUnsupported address family ({})r"r�r�netmask�/z{addr}/{netmask})r"r=z,Testing local IP address: %s (interface: %s)���)r;�ImportError�logger�debugr�AF_INET�AF_INET6r r3Z
interfacesZifaddresses�get�splitrrrr)r!ZfamilyZ	interfaceZifdataZifaddrZifmaskZ
ifaddrmaskrr%r%r&�get_matching_interface�s.



z'CheckedIPAddress.get_matching_interfacecCs
||_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)r)r!rr%r%r&�
set_ip_net�szCheckedIPAddress.set_ip_net)TFF)r+r,r-r.rr(r*r9r:rGrHr/r%r%)r$r&r0�s'+r0cs"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�|j�r4tdj|�tjd�dS)NT)r5r7r6z(WARNING: You are using a loopback IP: {})�file)rrIrr4�printr3�sys�stderr)r!r"r5r7)r$r%r&rs

z!CheckedIPAddressLoopback.__init__)TF)r+r,r-r.rr/r%r%)r$r&rI�srIcCstj|�ptj|�S)N)rZ
valid_ipv4Z
valid_ipv6)r"r%r%r&�valid_ipsrNcCsZt|�}ytjtj|�d|}Wntjk
r8YnX|dkrF|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_ptonrD�error)�host�portr%r%r&�
format_netlocsrScCs |jd�}tdd�|D��}|S)z)Convert a kerberos realm to a IPA suffix.�.cSsg|]}d|j�f�qS)Zdc)�lower)�.0�xr%r%r&�
<listcomp>*sz#realm_to_suffix.<locals>.<listcomp>)rFr)Z
realm_name�s�	suffix_dnr%r%r&�realm_to_suffix's
r[cCsdjdd�|D��}|S)z)Convert a IPA suffix to a kerberos realm.rTcSsg|]
}|j�qSr%)�value)rVrWr%r%r&rX0sz#suffix_to_realm.<locals>.<listcomp>)�join)rZ�realmr%r%r&�suffix_to_realm-sr_cCs.tj|�j|�}tjd�}|jdd�|�}|S)Nz(eval\s*\(([^()]*)\))cSstt|jd���S)N�)r�eval�group)rWr%r%r&�<lambda>:sztemplate_str.<locals>.<lambda>)�stringZTemplateZ
substitute�re�compile�sub)�txt�vars�val�patternr%r%r&�template_str3s
rlc
Cs"t|��}t|j�|�SQRXdS)z.Read a file and perform template substitutionsN)�openrl�read)�
infilenameri�fr%r%r&�
template_file>s
rqc	Cs.t||�}t|d��}|j|�WdQRXdS)z.Copy a file, performing template substitutions�wN)rqrm�write)roZoutfilenamerirhrJr%r%r&�copy_template_fileCs
rtcCs tjd�}|j|�|j�|S)Nzw+)�tempfile�NamedTemporaryFilers�flush)rh�fdr%r%r&�write_tmp_fileJs

rycCs`|j�tj|j��tjjtjj|j��}tj|tj	tj
B�}ztj|�Wdtj|�XdS)zSFlush and fsync file to disk

    :param f: a file object with fileno and name
    N)rw�os�fsync�fileno�path�dirname�abspathr
rm�O_RDONLY�O_DIRECTORY�close)rpr~�dirfdr%r%r&�
flush_syncRsr�cCs6t|t�rd|jdd�dSd|jdd�dSdS)N�'z'\''�'s'\'')rr�replace)rdr%r%r&�shell_quoteds
r�c@seZdZdZdS)�
_RunResultzResult of ipautil.runN)r+r,r-r.r%r%r%r&r�ksr�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|�j|||�||_dS)N)rr�rrM)r!�
returncode�cmd�outputrM)r$r%r&ruszCalledProcessError.__init__cCsN|jjdj|j�dj|j�g}|jdk	r:|jdj|j��|jd�dj|�S)Nz(Command {!s} z"returned non-zero exit status {!r}z: {!r}�)�)r$r+r3r�r�rM�appendr])r!�argsr%r%r&�__str__ys


zCalledProcessError.__str__)NN)r+r,r-r.rr��__repr__r/r%r%)r$r&r�psr�TFcsfd}d}d}t|t�rtd��|r2|s*|
r2td��|rF|s>|
rFtd��|rV|rVtd��|dkrrtjtj�}d|d<|r|tj}|r�t	tj
d�}}n|r�tj}tj
}ntj}tj}|dkr�tj�}tjr�t|t�r�|j|�}tt|�|�}tjd	�tjd
|��dk	�rft���dd�|	D�}	d
d�|	D��tjd��j�j�|	�rfx|	D]}tjd||j��qLW�dk	�sz�dk	�r����fdd�}nd}z|y,tj||||d|||d�}|j|�\}}WnJtk
�r�tjd�|j��Yn"tk
�rtjd��YnXWd|�r|j �Xtjd|j!�|�s8|�rBd}d}n�tj�r^|j"tj�dd�}n|}tj�r~|j"tj�dd�}n|}t||�}|�r�tjd�ntjd|�t||�}|�r�tjd�ntjd|�|�r�tj#�r�|}n
|j"|�}nd}|
�rtj#�r
|}n
|j"|�}nd}|j!dk�r<|�r<t$|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�PATHrrzStarting external processzargs=%scSsg|]}t|��qSr%)r
)rVrbr%r%r&rX�szrun.<locals>.<listcomp>cSsg|]
}|j�qSr%)�gid)rVrbr%r%r&rX�szrunas=%s (UID %d, GID %s)zsupplementary_group=%s (GID %d)csH�dk	r2tj��tj�j�j�tj�j�j��dk	rDtj��dS)N)rz�	setgroups�setregid�pgid�setreuid�uid�umaskr%)�runas�suplementary_gidsr�r%r&�
preexec_fn
s
zrun.<locals>.preexec_fnT)�stdin�stdoutrMZ	close_fds�env�cwdr�zProcess interruptedzProcess execution failedz Process finished, return code=%sr�)�errorszstdout=<REDACTED>z	stdout=%szstderr=<REDACTED>z	stderr=%sr)*rrr �copy�deepcopyrz�environ�
subprocess�PIPErm�devnullrLr�rM�locale�getpreferredencoding�sixZPY3�encode�
nolog_replace�reprrArBr	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_errZ
arg_stringrbr��pr�rMr�r�r�Zerror_output�resultr%)r�r�r�r&�run�s�C




	








r�cCsZxT|D]L}|st|t�rqtjj|�}t|�}x|||fD]}|j|d�}q>WqW|S)z<Replace occurences of strings given in `nolog` with XXXXXXXXZXXXXXXXX)rr�urllib�parseZquoter�r�)rdr�r\ZquotedZshquotedZnolog_valuer%r%r&r�cs
r�cCs6tjj|�rtj||d�tj||�tj|�dS)Nz.orig)rzr}�isfile�rename�shutilr��remove)�fname�destr%r%r&�install_filepsr�cCs tjj|�rtj||d�dS)Nz.orig)rzr}r�r�)r�r%r%r&�backup_filexs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|�j�i|_|r"|j|�|r0|j|�dS)N)rr�r�_keys�update)r!�default�kwargs)r$r%r&r�s
zCIDict.__init__cstt|�j|j��S)N)rr��__getitem__rU)r!�key)r$r%r&r��szCIDict.__getitem__csJ|j�}|dk	r.||kr$td|��|j|�||j|<tt|�j||�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)rUr �addr�rr��__setitem__)r!r�r\Z	seen_keys�	lower_key)r$r%r&r��s

zCIDict.__setitem__cs |j�}|j|=tt|�j|�S)N)rUr�rr��__delitem__)r!r�r�)r$r%r&r��szCIDict.__delitem__c
Ks�t�}|rZy
|j}Wn"tk
r6|jt|��Yn$Xx |�D]}|j||||�q@Wt�}x"|j�D]\}}|j|||�qjWdS)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�r\r%r%r&r��s
z
CIDict.updatecstt|�j|j��S)N)rr��__contains__rU)r!r�)r$r%r&r��szCIDict.__contains__cstt|�j|j��S)N)rr��has_keyrU)r!r�)r$r%r&r��szCIDict.has_keycCs"y||Stk
r|SXdS)N)�KeyError)r!r�Zfailobjr%r%r&rE�sz
CIDict.getcCstj|j�S)N)r��
itervaluesr�)r!r%r%r&�__iter__�szCIDict.__iter__cCstjrt|j��S|j�SdS)N)r�r��list�iterkeys)r!r%r%r&r��szCIDict.keyscCstjrt|j��S|j�SdS)N)r�r�r��	iteritems)r!r%r%r&r��szCIDict.itemscCstjrt|j��S|j�SdS)N)r�r�r�r�)r!r%r%r&�values�sz
CIDict.valuescCstt|j���S)z%Returns a shallow copy of this CIDict)r�r�r�)r!r%r%r&r��szCIDict.copycs�fdd�tj�j�D�S)Nc3s|]}|�|fVqdS)Nr%)rV�k)r!r%r&�	<genexpr>�sz#CIDict.iteritems.<locals>.<genexpr>)r�r�r�)r!r%)r!r&r��szCIDict.iteritemscCstj|j�S)N)r�r�r�)r!r%r%r&r��szCIDict.iterkeyscCsdd�tj|�D�S)Ncss|]\}}|VqdS)Nr%)rVr��vr%r%r&r��sz$CIDict.itervalues.<locals>.<genexpr>)r�r�)r!r%r%r&r��szCIDict.itervaluescCs*y||Stk
r$|||<|SXdS)N)r�)r!r�r\r%r%r&�
setdefault�s
zCIDict.setdefaultcGsBy||}||=|Stk
r<t|�dkr6|dS�YnXdS)Nr<r)r��len)r!r�r�r\r%r%r&�pop�sz
CIDict.popcs,tt|�j�\}}|j|}|j|=||fS)N)rr��popitemr�)r!r�r\r�)r$r%r&r��s
zCIDict.popitemcs|jj�tt|�j�S)N)r��clearrr�)r!)r$r%r&r�s
zCIDict.clearcCstd��dS)Nz#CIDict.viewitems is not implemented)�NotImplementedError)r!r%r%r&�	viewitems	szCIDict.viewitemscCstd��dS)Nz"CIDict.viewkeys is not implemented)r�)r!r%r%r&�viewkeysszCIDict.viewkeyscCstd��dS)Nz%CIDict.viewvvalues is not implemented)r�)r!r%r%r&�viewvvaluesszCIDict.viewvvalues)N)N)N)N)N)r+r,r-r.rr�r�r�r�r�r�r�r�rEr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r/r%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|�j�||_d|_d|_|dkr6d|_d|_n~t|�dkrltjd|�rlt	|dd��|_|dd�}t|�dkr�tjd|�r�t	|dd��|_|dd�}t|�dkr�t
��|jdkr�|jd9_dS)	Nrr��z[-+]\d\dr`z\d\dr<r?)rr�rr
�
houroffset�	minoffsetr�re�match�intr )r!Z	offsetstr)r$r%r&rs"
zGeneralizedTimeZone.__init__cCstj|j|jd�S)N)ZhoursZminutes)�datetime�	timedeltar�r�)r!Zdtr%r%r&�	utcoffset,szGeneralizedTimeZone.utcoffsetcCs
tjd�S)Nr)r�r�)r!r%r%r&�dst/szGeneralizedTimeZone.dstcCs|jS)N)r
)r!r%r%r&�tzname2szGeneralizedTimeZone.tzname)r�)	r+r,r-r.rr�r�r�r/r%r%)r$r&r�s
r�cCst|�dkrdS�y�|dd�}|dd�}t|dd��}t|dd��}t|dd��}d}}}}	d}
t|�dko�tjd|d��r:t|dd��}|dd�}t|�dko�|ddks�|dd	k�r:d	}|d
d�}x:t|�dko�tjd|d��r||d7}|d
d�}q�Wtt|�d�}t|d�\}}t|�dk�rtjd|d��rt|dd��}|dd�}t|�dk�r|ddk�s�|dd	k�rd	}
|d
d�}x>t|�dk�r�tjd|d��r�|
|d7}
|d
d�}�q�Wtt|
�d�}t|�dk�r�tjd|d��r�t|dd��}|dd�}t|�dk�r�|ddk�sf|dd	k�r�d	}|d
d�}x>t|�dk�r�tjd|d��r�||d7}|d
d�}�qxWtt|�d
�}	t|�dk�r�t|�}
tj|||||||	|
�Stk
�rdSXdS)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...�Nr1rrr`z\d�,rTr<i�<i@B)	r�r�rer��float�divmodr�r�r )ZtimestrZdate�timeZyearZmonthZdayZhour�minZsecZmsecZtzoneZ
hour_fractionZ
total_secsZmin_fractionZsec_fractionr%r%r&�parse_generalized_time6s\&  *" *"r�r<csrd}tjtjttj�d�d�tjtjttj�d�d�tjtjttj�d�d�|tjt|�d�d�d�}t||||d��ddj�fdd�|j	�D��i|d	<tjt|d	d�d�|d	d
<t
j�}|}	d}
x\dD]T}||}�|}
|
dkr�q�x4|
dk�r"|
|j|d�7}
|	|d
8}	|
d8}
q�Wq�W|d	}x<|	dk�sJt|
�|k�rl|
|j|d�7}
|	|d
8}	�q2W|
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!$%&()*+,-./:;<>?@[]^_{|}~r`)�chars�entropy)�	uppercase�	lowercase�digits�specialrr�cs$g|]\}}�|dk	r|d�qS)Nrr%)rV�charclass_name�	charclass)�req_classesr%r&rX�sz)ipa_generate_password.<locals>.<listcomp>�allrrrrrNrr<)rrrr)
rdZascii_uppercase�math�logr�Zascii_lowercaserr�r]r��randomZSystemRandom�choice)Zentropy_bitsrrrrZmin_lenZ
special_charsZpwd_charsetsZrndZtodo_entropyZpasswordr	r
Ztodo_charactersZallcharsr%)rr&�ipa_generate_passwordvsH

rcCs�|dkrXxNy$td|�}|s$|j�r,|j�SWq
tk
rR|rFdStd��Yq
Xq
Wt|t�r�xPy6td||f�}|r�|s�|r�|S|j�r�|j�SWqdtk
r�|SXqdWt|t��r:|r�dnd}xlyPtd||f�}|j�}|s�|S|j�ddk�rd	S|j�dd
k�rdSWq�tk
�r4|SXq�Wt|t��r�xdy.td||f�}|j�}|�sl|St|�}Wn*t	k
�r�Yntk
�r�|SX|S�qHWdS)Nz%s: r�zFailed to get user inputz	%s [%s]: �yes�nor�yT�nF)
r�strip�EOFError�RuntimeErrorrr�boolrUr�r )�promptr�Zallow_empty�retrr%r%r&�
user_input�s`



rcCs�d}x�tj||tj|�D]�}|\}}	}
}}d}
z�yLtj||	|
�}
|dk	rR|
j|�|
j|�|tjkrz|
jd�|
jd�WnDtjk
r�d}|r�dt	|t
||dd�}tj||�YnXWd|
dk	r�|
j
�XqW|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
    TN�iFz8Failed to connect to port %(port)s %(proto)s on %(addr)sr)rR�protor")rOZgetaddrinfoZ	AF_UNSPECZ
settimeout�connect�
SOCK_DGRAM�sendZrecvrPr��PROTOCOL_NAMESrArr�)rQrR�socket_typeZsocket_timeout�
log_errorsZ	log_level�	port_open�resZafZsocktyperZ
_canonnameZsarY�msgr%r%r&�host_port_opens.	



r(cCs|tjkrd}n|tjkr d}nt|��y"tjtj|�}d}tjd|�Wn4tjk
r~tjtj|�}d}tjd|�YnXzxy.|tjkr�|j	tj
tjd�|j||f�Wn2tjk
r�}ztjd|||�d	Sd
}~XnXtjd||�dSWd
|j
�Xd
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: %sFNz(check_port_bindable: bind success: %i/%s)rO�SOCK_STREAMr r rDrArBrPrCZ
setsockoptZ
SOL_SOCKETZSO_REUSEADDRZbindr�)rRr#rrYZanyaddrr8r%r%r&�check_port_bindable,s8





r*cCs�tjdtj�}tj|�}t�}d}tjddd����}|j}t	|d���}	x�|	D]�}
|
}|j
|
�}|�r
|jdd�\}
}|
dk	�r
|r�|
|kr�d	|
||
f}|||
<|r�|
|kr�|s�d	|
||
f}n$|j||
�dkr�d|
|||
f}|||
<|o�|
|k�r
|||
<d}|dk	rL|j
|�qLWWdQRX|j�}|j|�t|j��t|j��}t|j��|}x$|D]}|j
d	|||f��qjWx$|D]}|j
d	|||f��q�W|j�tj|j�|j�tj|j�|j|j�WdQRXt||�|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*((\#|;).*)?)?
$)NrrF)�mode�delete�r�optionr\z%s=%s
r<z	%s=%s %s
r?)rerf�VERBOSErz�statr�rurvr
rmr�rb�findrsr�r�r�r�rw�fchmodr|�st_mode�fchown�st_uid�st_gidr�)�filepath�replacevars�
appendvarsZ
removevarsrk�	orig_stat�
old_values�
temp_filename�
new_configrp�line�new_line�mr.r\�new_vars�newvars_view�append_view�itemr%r%r&�config_replace_variables]sR







 
rEcCs�tjdtj�}dd�}tj|�}t�}d}tjddd����}	|	j}t	|d���Z}
d}d}d	}
�x|
D�]}|
d	}
|}|j
|�}|rd|jd
dd�\}}}|r�|dk	r�||	|||�d
}|dk	r�t|�j
�t|�j
�k}|dk	o�|�r`|o�||k�r
d|||f}|||<|�r`||k�r`|�s2d|||f}n&|j||�dk�rXd||||f}|||<|	j|�qdW|�pv|�s�|	jd|�|�s�|�r�||	|||�WdQRX|	j�tj|	j�|j�tj|	j�|j|j�WdQRXt||�|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�|j�}|j|�t|j��t|j��}t|j��|}x"|D]}|jd|||f�q@Wx"|D]}|jd|||f�qdWdS)Nz%s=%s
)r�r�r�r�rs)�configr8r9ZoldvarsrArBrCrDr%r%r&�add_options�s


z.inifile_replace_variables.<locals>.add_optionsNrrF)r+r,r-r<�sectionr.r\Tz%s=%s
z	%s=%s %s
z[%s]
r?)rerfr/rzr0r�rurvr
rmr�rbrrUr1rsrwr2r|r3r4r5r6r�)r7rHr8r9rkrGr:r;r<r=rpZ
in_sectionZfinishedZline_idxr>r?r@Zsectr.r\r%r%r&�inifile_replace_variables�sV


 
rIcCs|j|�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�rE)Zfstorer7r8r9r;r%r%r&�#backup_config_and_replace_variables
s
rJcCs�t|�}t|ttf�s|g}tjd|||�tj�|}xj|D]b}tjd|�d}xLt|||d�}d}|rxtjd|�P|r�tj�|kr�tj	d��tj
d�qTWq>Wd	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 exceededr<N)r�r�tupler�rArBr�r(rO�timeout�sleep)rQZportsrL�
op_timeoutrRZ	log_errorr%r%r%r&�wait_for_open_ports&s"

rOcCs�t|�}tj�|}x|y$tjtj�}|j|�|j�PWqtjk
r�}z4|jdkrx|rltj�|krl|�tjd�n|�WYdd}~XqXqWdS)z
    Wait until the specified socket on the local host is open. Timeout
    in seconds may be specified to limit the wait.
    r`�or<N)r`rP)	r�r�rOZAF_UNIXrr�rP�errnorM)Zsocket_namerLrNrYr8r%r%r&�wait_for_open_socketBs

rRcs"�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 |dk	rt|�}t|�|�dS)N)r�setattr)r!r\)�private_namer%r&�setterjsz%dn_attribute_property.<locals>.settercst|��}|dk	r|S)N)�getattr)r!r\)rTr%r&�getteros
z%dn_attribute_property.<locals>.getter)�property)rTrUrWr%)rTr&�dn_attribute_propertyYsrYcCs.dd�}|jdd�}djt||��}|jd�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|j�p|dkS)N�_rT�-)rZrTr[)�isalnum)�charr%r%r&�
valid_char�szposixify.<locals>.valid_char� rZr�r[)r�r]�filter�lstrip)rdr^ZreplacedZomittedr%r%r&�posixifywsrbccs�|dkr$tjdd�}tjj|d�}nd}tjjdd�}|tjd<z
|VWd|dk	r`|tjd<ntjjdd�tjj|�r�tj	|�|dk	r�ytj
|�Wntk
r�YnXXdS)NZkrbcc)�prefixZccacheZ
KRB5CCNAME)ruZmkdtemprzr}r]r�rEr��existsr��rmdir�OSError)r}Zdir_path�original_valuer%r%r&�private_ccache�s$


rh�/run/ipac	cs�tj}d}|rltjd�|j�|f}tj|ddd�\}}tj|ddd��}|j	|�WdQRXd	j
||g�}tjj
d
d�}|tjd
<z$y
|VWntk
r�YnXWd|dk	r�|tjd
<ntjjd
d�|dk	r�tjj|�r�tj|�XdS)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)�dirrc�textrrzutf-8)r+r��:ZKRB5_CONFIG)rZ	KRB5_CONF�textwrap�dedent�upperruZmkstemp�iormrsr]rzr�rE�
GeneratorExitr�r}rdr�)	r^ZserverrjZcfgZtcfgZcontentrx�orgr%r%r&�private_krb5_config�s,


rscCsFt|t�r|jtj��St|t�r&|Stdjtjtjt	|�j���dS)zw
        Decode argument using the file system encoding, as returned by
        `sys.getfilesystemencoding()`.
        zexpect {0} or {1}, not {2}N)
r�bytesr�rL�getfilesystemencodingr�	TypeErrorr3r+�type)r\r%r%r&�fsdecode�s

rxcs(tjdj����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|]}tj��|�VqdS)N)rerg)rV�a)�seq�unescape_rer%r&r��szunescape_seq.<locals>.<genexpr>)rerfr3rK)rzr�r%)rzr{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 |]}|j�dj���VqdS)z\{}N)r�r3)rVry)rzr%r&r�szescape_seq.<locals>.<genexpr>)rK)rzr�r%)rzr&�
escape_seq�s
r}cCs&dd�}t|t�r|S|j||�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-sigr1rr<z	utf-16-bez	utf-32-ber`r�z	utf-16-lez	utf-32-lezutf-8)�
startswith�codecs�BOM_UTF32_BE�BOM_UTF32_LE�BOM_UTF16_BE�BOM_UTF16_LE�BOM_UTF8r�)�bZbstartswithr%r%r&�detect_encodings$
z$decode_json.<locals>.detect_encoding�
surrogatepass)rrr�)�datar�r%r%r&�decode_jsons
r�c@sLeZdZdZfZdd�Zdd�Zdd�Zdd	�Ze	d
d��Z
e	dd
��ZdS)�
APIVersionzzAPI version parser and handler

    The class is used to parse ipapython.version.API_VERSION and plugin
    versions.
    cCs8|jd�\}}}t|�}|r$t|�nd}tj|||f�S)NrTr)rr�rK�__new__)�clsr�major�dot�minorr%r%r&r�DszAPIVersion.__new__cCs
dj|�S)Nz{}.{})r3)r!r%r%r&r�JszAPIVersion.__str__cCs
dj|�S)Nz<APIVersion('{}.{}')>)r3)r!r%r%r&r�MszAPIVersion.__repr__cCs
t|�fS)N)r)r!r%r%r&�__getnewargs__PszAPIVersion.__getnewargs__cCs|dS)Nrr%)r!r%r%r&r�SszAPIVersion.majorcCs|dS)Nr<r%)r!r%r%r&r�WszAPIVersion.minorN)r+r,r-r.�	__slots__r�r�r�r�rXr�r�r%r%r%r&r�<sr�cCsfytjd|�tj|�WnFtk
r`}z*|jtjkrPtjd||�tjd�WYdd}~XnXdS)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)rArBrzr�rfrQ�ENOENT�warning)Zkeytab_pathr8r%r%r&�
remove_keytab\sr�cCsztjd�tjg}|dk	r4tjd|�|jd|g�yt||id�Wn.tk
rt}ztjd|�WYdd}~XnXdS)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)rArBrZKDESTROY�extendr�r�r�)Zccache_pathZrun_asZkdestroy_cmdr8r%r%r&�
remove_ccachels
r�cCsZytj|�WnFtk
rT}z*t|dd�tjkrDtjd|t|��WYdd}~XnXdS)z1Remove a file and log any exceptions raised.
    rQNzError removing %s: %s)	rz�unlink�	ExceptionrVrQr�rArPr)�filenamer8r%r%r&�remove_file�s
r�cCsTytjj|�rtj|�Wn4tk
rN}ztjd|t|��WYdd}~XnXdS)zE
    Remove a directory structure and log any exceptions raised.
    zError removing %s: %sN)	rzr}rdr��rmtreer�rArPr)r}r8r%r%r&r��s
r�cCsft|tj�rttj|��}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�r<)�tzinfo)Zseconds)rr�Zstruct_timer�Zmktimer�rvr�ZtimezoneZutcr�)�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)
    r`N)�raisescCsT|dkrtd|����|dkr.td|�d���||_||_||_tj�|j|_dS)Nrzinvalid timeout g{�G�z�?zsleep duration z is too short.)r rLrMr�r��	monotonic�deadline)r!rMrLr�r%r%r&r�szSleeper.__init__cCstj�|jkS)N)r�r�r�)r!r%r%r&�__bool__�szSleeper.__bool__cCsHtj�}||jkr(|jdk	r$|j�ndSt|j||j�}tj|�dS)NFT)r�r�r�r�rrM)r!ZnowZdurr%r%r&�__call__�s


zSleeper.__call__)r+r,r-r.Z
multiplierrr�r�r%r%r%r&r��s
r�cCsvd}tjjdddd|�}t�}y|j|�Wntk
rBdSX|j|�sRdS|j|d�sbdS|j|d�j	�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.
    �globalr>ZetcZipaz%s.confFrB�true)
rzr}r]rrnrZhas_sectionZ
has_optionrErU)�contextZCONFIG_SECTIONZconfig_file�parserr%r%r&�get_config_debug�s
r�)N)rr<r<r<r<r)NT)r)r)N)ri)NN)r<)gZ
__future__rrZloggingrdrur�rr
rzrLrQr�r�rOrer�rr�rmrp�
contextlibrZconfigparserrrr��collectionsr�r�Z	six.movesrr;r@Zipapython.dnrZipaplatform.pathsrZipaplatform.constantsr	r
Z	getLoggerr+rAZTMP_PWD_ENTROPY_BITSr)r r"�
namedtuplerrrr0rIrNrSr[r_rlrqrtryr�r�r�r�r�r�r�r�r�r�r�r�rrr�DEBUGr(r*rErIrJrOrRrYrbrhrsr�rxr|r}r�rKr�r�r�r�r�r�r�r�r%r%r%r&�<module>s�


=t
Y
#@
T
8'1Mc

/

1 

5