%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python3/dist-packages/samba/kcc/__pycache__/
Upload File :
Create Path :
Current File : //lib/python3/dist-packages/samba/kcc/__pycache__/__init__.cpython-312.pyc

�

�I�d����R�ddlZddlZddlmZddlZddlmZmZddlmZm	Z	m
Z
ddlmZddl
mZddlmZmZddlmZmZmZmZdd	lmZmZmZmZdd
lmZmZmZddlmZddl m!Z!dd
l"m#Z#ddl$m%Z%ddlm&Z&m'Z'ddlm(Z(ddl)m*Z*m+Z+m,Z,ddl$m-Z-ddl.m/Z/d�Z0d�Z1Gd�de2�Z3y)�N)�
cmp_to_key)�unix2nttime�nttime2unix)�ldb�dsdb�	drs_utils)�system_session)�SamDB)�drsuapi�misc)�Site�	Partition�	Transport�SiteLink)�	NCReplica�NCType�
nctype_lut�	GraphNode)�
RepsFromTo�KCCError�KCCFailedObject)�convert_schedule_to_repltimes)�ndr_pack)�verify_and_dot)�ldif_import_export)�setup_graph�get_spanning_tree_edges)�Vertex)�DEBUG�DEBUG_FN�logger)�debug)�cmpc���|j�r|j�sy|j�s|j�rytt|j�t|j��S)aHelper to sort DSAs by guid global catalog status

    GC DSAs come before non-GC DSAs, other than that, the guids are
    sorted in NDR form.

    :param dsa1: A DSA object
    :param dsa2: Another DSA
    :return: -1, 0, or 1, indicating sort order.
    ����)�is_gcr#r�dsa_guid)�dsa1�dsa2s  �4/usr/lib/python3/dist-packages/samba/kcc/__init__.py�sort_dsa_by_gc_and_guidr,2sK���z�z�|�D�J�J�L���:�:�<�D�J�J�L���x��
�
�&�����(?�@�@�c��y)z�Can the KCC use SMTP replication?

    Currently always returns false because Samba doesn't implement
    SMTP transfer for NC changes between DCs.

    :return: Boolean (always False)
    F�r/r-r+�is_smtp_replication_availabler0Cs��r-c��eZdZdZ		d+d�Zd�Zd�Zd�Zd�Zd�Z	d	�Z
d
�Zd,d�Zd�Z
d
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd,d�Zd,d�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Z d �Z!d-d!�Z"d"�Z#d#�Z$d$�Z%d%�Z&d.d&�Z'd/d'�Z(			d0d(�Z)d,d)�Z*d*�Z+y)1�KCCa;The Knowledge Consistency Checker class.

    A container for objects and methods allowing a run of the KCC.  Produces a
    set of connections in the samdb for which the Distributed Replication
    Service can then utilize to replicate naming contexts

    :param unix_now: The putative current time in seconds since 1970.
    :param readonly: Don't write to the database.
    :param verify: Check topological invariants for the generated graphs
    :param debug: Write verbosely to stderr.
    :param dot_file_dir: write diagnostic Graphviz files in this directory
    Nc��i|_i|_d|_i|_i|_i|_|j
j|_|jj|_i|_	t�|_t�|_d|_
d|_d|_d|_d|_||_t'|�|_||_||_||_||_y)z�Initializes the partitions class which can hold
        our local DCs partitions or all the partitions in
        the forest
        N)�
part_table�
site_table�ip_transport�sitelink_table�dsa_by_dnstr�dsa_by_guid�get�get_dsa_by_guidstr�get_dsa�kcc_failed_links�set�kcc_failed_connections�kept_connections�my_dsa_dnstr�my_dsa�
my_site_dnstr�my_site�samdb�unix_nowr�nt_now�readonly�verifyr"�dot_file_dir)�selfrFrHrIr"rJs      r+�__init__zKCC.__init__[s��������� ��� ���������"&�"2�"2�"6�"6����(�(�,�,���
!#���&)�e��#�
!$���� ������!��������
� ��
�!�(�+��� ��
������
�(��r-c�t�	|jjd|jj�ztjd��}|D]�}t|j�}t|�}|j|j�|jdk(r||_
�U|jdk(rtjd��ztj d	|j�d
����|j�td��y#tj
$r"}|j\}}td|z��d}~wwxYw)z�Loads the inter-site transport objects for Sites

        :return: None
        :raise KCCError: if no IP transport is found
        �$CN=Inter-Site Transports,CN=Sites,%sz (objectClass=interSiteTransport)��scope�
expressionz+Unable to find inter-site transports - (%s)N�IP�SMTPz2Samba KCC is ignoring the obsolete SMTP transport.z0Samba KCC does not support the transport called �.z(there doesn't seem to be an IP transport)rE�search�get_config_basednr�
SCOPE_SUBTREE�LdbError�argsr�str�dnr�load_transport�namer6r!r"�warning)rK�res�e2�enum�estr�msg�dnstr�	transports        r+�load_ip_transportzKCC.load_ip_transport�s)��	!��*�*�#�#�$J�$(�J�J�$@�$@�$B�%C�*-�*;�*;�/Q�$�S�C��	A�C�����K�E�!�%�(�I��$�$�T�Z�Z�0��~�~��%�$-��!����6�)����/�0����/8�~�~� @�A�	A� ���$��E�F�F�%��+�|�|�	!��7�7�L�T�4��H�� �!�
!��	!�s�AD�D7�D2�2D7c���	|jjd|jj�ztjd��}|D][}t|j�}||jvr�'t|�}|j|j�||j|<�]y#tj
$r"}|j\}}td|z��d}~wwxYw)zyLoads the inter-site siteLink objects

        :return: None
        :raise KCCError: if site-links aren't found
        rNz(objectClass=siteLink)rOz*Unable to find inter-site siteLinks - (%s)N)
rErUrVrrWrXrYrrZr[r7r�
load_sitelink)rKr_�e3rarbrcrd�sitelinks        r+�load_all_sitelinkszKCC.load_all_sitelinks�s���	P��*�*�#�#�$J�$(�J�J�$@�$@�$B�%C�*-�*;�*;�/G�$�I�C��
	2�C�����K�E���+�+�+�����H��"�"�4�:�:�.�*2�D����&�
	2��	�|�|�	P��7�7�L�T�4��G�$�N�O�O��	P���AB*�*C�=C�Cc��t||j�}|j|j�t	|j
�}||jvrn||j|<|jj|j�|jjd�|jj�D��|j|S)z�Helper for load_my_site and load_all_sites.

        Put all the site's DSAs into the KCC indices.

        :param dn_str: a site dn_str
        :return: the Site object pertaining to the dn_str
        c3�JK�|]}t|j�|f���y�w�N�rZr(��.0�xs  r+�	<genexpr>z KCC.load_site.<locals>.<genexpr>�s'����$F�()�&)����_�a�$8�$F�s�!#)r
rF�	load_siterErZ�	site_guidr5r8�update�	dsa_tabler9�values)rK�dn_str�site�guids    r+ruz
KCC.load_site�s����F�D�M�M�*�����t�z�z�"�
�4�>�>�"���t���&�$(�D�O�O�D�!����$�$�T�^�^�4����#�#�$F�-1�^�^�-B�-B�-D�$F�
F����t�$�$r-c��d|jj��d|jj���|_|j	|j�|_y)zGLoad the Site object for the local DSA.

        :return: None
        zCN=z
,CN=Sites,N)rE�server_site_namerVrCrurD�rKs r+�load_my_sitezKCC.load_my_site�sF��
�J�J�'�'�)��J�J�(�(�*�,����~�~�d�&8�&8�9��r-c�^�	|jjd|jj�ztjd��}|D](}t|j�}|j|��*y#tj
$r"}|j\}}td|z��d}~wwxYw)z|Discover all sites and create Site objects.

        :return: None
        :raise: KCCError if sites can't be found
        zCN=Sites,%sz(objectClass=site)rOzUnable to find sites - (%s)N)rErUrVrrWrXrYrrZr[ru)rKr_�e4rarbrc�sitestrs       r+�load_all_siteszKCC.load_all_sites�s���	A��*�*�#�#�M�$(�J�J�$@�$@�$B�%C�*-�*;�*;�/C�$�E�C��	$�C��#�&�&�k�G��N�N�7�#�	$��	�|�|�	A��7�7�L�T�4��8�4�?�@�@��	A�s�AA7�7B,�
B'�'B,c
��d|jj�z}tj|j|�}	|jj	|tj
dg��}t|�dk7rtd|j�z��tj|jj��}	tj|d
dd
�|	k7rtd��t|d
j �|_|j$j'|j"�|_|j"|j*vr|t-j.d|j"z�|j(|j*|j"<|j(|j0t|j(j2�<y
y
#tj$r�}|j\}}td|�d|�d|�d��	|jj	dtj
d	g��}tj|j|d
d	d
jd��}|jj	|tj
dg��}n8#tj$r"}|j\}}td|z��d
}~wwxYwYd
}~��hd
}~wwxYw)z|Discover my nTDSDSA dn thru the rootDSE entry

        :return: None
        :raise: KCCError if DSA can't be found
        z	<GUID=%s>�
objectGUID)�baserP�attrszSearch for dn 'z' [from z
] failed: zL. This typically happens in --importldif mode due to lack of module support.��
dsServiceNamer�utf8z Unable to find my nTDSDSA - (%s)Nr&zUnable to find my nTDSDSA at %sz>Did not find the GUID we expected, perhaps due to --importldifz�my_dsa %s isn't in self.dsas_by_dnstr: it must be RODC.
Let's add it, because my_dsa is special!
(likewise for self.dsa_by_guid))rE�
get_ntds_GUIDr�DnrU�
SCOPE_BASErXrYr �decoder�len�extended_strr�GUIDrZr[rArDr<rBr8r"�DEBUG_DARK_YELLOWr9r()
rK�dn_queryr[r_�e5rarb�service_name_res�e�	ntds_guids
          r+�load_my_dsazKCC.load_my_dsa�s�������!9�!9�!;�;��
�V�V�D�J�J��
)��	J��*�*�#�#��3�>�>�+7�.�$�:�C�4�s�8�q�=��<��?�?�,�-�.�
.��I�I�d�j�j�6�6�8�9�	��9�9�S��V�L�)�!�,�-��:��:�;�
;� ��A��	�	�N����l�l�*�*�4�+<�+<�=������D�$5�$5�5��#�#�%H�%)�$5�$5�	%6�
7�48�;�;�D���d�/�/�0�:>�+�+�D���S����!5�!5�6�7�6��K�|�|�	J��7�7�L�T�4��57��4�I�
J�
J�$(�:�:�#4�#4�"�;>�>�>�<K�;L�$5�$N� ��V�V�D�J�J�,�Q�/��@��C�J�J�6�R�T���j�j�'�'�R�s�~�~�/;�n�(�>����<�<�
J� �v�v���t��A�D�H�I�I��
J����%	J�s<�-G�K�$K�BJ�K�K�)K�K�K�Kc���	|jjd|jj�ztjd��}|D][}t|j�}||jvr�'t|�}|j|j�||j|<�]y#tj
$r"}|j\}}td|z��d}~wwxYw)z�Discover and load all partitions.

        Each NC is inserted into the part_table by partition
        dn string (not the nCName dn string)

        :return: None
        :raise: KCCError if partitions can't be found
        zCN=Partitions,%sz(objectClass=crossRef)rOz Unable to find partitions - (%s)N)
rErUrVrrWrXrYrrZr[r4r�load_partition)rKr_�e6rarbrc�partstr�parts        r+�load_all_partitionszKCC.load_all_partitions5s���	F��*�*�#�#�$6�$(�J�J�$@�$@�$B�%C�*-�*;�*;�/G�$�I�C��
	,�C��#�&�&�k�G��$�/�/�)���W�%�D�����
�
�+�'+�D�O�O�G�$�
	,��	�|�|�	F��7�7�L�T�4��=��D�E�E��	F�rlc	�0�i|_|jj�\}}|j�D]�}|jD]�}|j
}|dkr�t
|j�}|j}|j}	|j}
|jj|�}|�t||||	|
�}||j|<��t|j|�|_t|j |�|_|	|_����t%�}|�Vt'd�|j(D];}
||
j*�r|j-|
��'|
xjdz
c_�=nt'd�|j(j/|�y)z�Ensure the failed links list is up to date

        Based on MS-ADTS 6.2.2.1

        :param ping: An oracle function of remote site availability
        :return: None
        rNz6refresh_failed_links: checking if links are still downr&zdrefresh_failed_links: not checking live links because we
weren't asked to --attempt-live-connections)r=rB�get_rep_tablesry�rep_repsFrom�consecutive_sync_failuresrZ�source_dsa_obj_guid�last_success�last_attempt�	dns_name1r:r�max�
failure_count�min�time_first_failure�last_resultr>rr?�dns_name�add�difference_update)rK�ping�current�needed�replica�	reps_fromr�r(r�r�r��f�restore_connections�
connections              r+� refresh_failed_links_connectionsz$KCC.refresh_failed_links_connectionsSs���!#����+�+�4�4�6�����~�~�'�	0�G�$�1�1�
0�	� )� C� C�
� �A�%���y�<�<�=��%.�%;�%;�"�'�4�4��$�.�.���)�)�-�-�h�7���9�'��-�(:�K�(0�2�A�78�D�)�)�(�3�&)�!�/�/�=�&I�A�O�+.�q�/C�/C�/A�,C�A�(�$/�A�M�)
0�	0�2"�e�����J�K�"�9�9�
2�
��
�+�+�,�'�+�+�J�7��,�,��1�,�
2�
�@�
A�	
�#�#�5�5�6I�Jr-c��|jjt|j��}|r[|jdkDrLt|j�}||jkDrtjd�|j|z
dkDryy)aLCheck whether a link to a remote DSA is stale

        Used in MS-ADTS 6.2.2.2 Intrasite Connection Creation

        Returns True if the remote seems to have been down for at
        least two hours, otherwise False.

        :param target_dsa: the remote DSA object
        :return: True if link is stale, otherwise False
        rz_The last success time attribute for                                  repsFrom is in the future!i TF)
r=r:rZr(r�rr�rFr!�error)rK�
target_dsa�failed_link�unix_first_failures    r+�is_stale_link_connectionzKCC.is_stale_link_connection�s����+�+�/�/��J�4G�4G�0H�I����(�(�1�,��� >� >�?�#�&��
�
�5��L�L�"=�>��M�M�$6�6�+�E��r-c��yror/rs r+�(remove_unneeded_failed_links_connectionsz,KCC.remove_unneeded_failed_links_connections�s��	
r-c��|D]}}|j��|jrGtjt	tj���|_|j|_�c|j|j��y)aTLoad or fake-load NTDSConnections lacking GUIDs

        New connections don't have GUIDs and created times which are
        needed for sorting. If we're in read-only mode, we make fake
        GUIDs, otherwise we ask SamDB to do it for us.

        :param connections: an iterable of NTDSConnection objects.
        :return: None
        N)r|rHrr�rZ�uuid�uuid4rG�whenCreated�load_connectionrE)rK�connections�cn_conns   r+�_ensure_connections_are_loadedz"KCC._ensure_connections_are_loaded�s]��#�	8�G��|�|�#��=�=�#'�9�9�S�����->�#?�G�L�*.�+�+�G�'��+�+�D�J�J�7�
	8r-c��|jjj�D]6}|j�}|��t	|j�d|���d|_�8y)z�Find NTDS Connections that lack a remote

        I'm not sure how they appear. Let's be rid of them by marking
        them with the to_be_deleted attribute.

        :return: None
        Nz has phantom connection T)rB�
connect_tablery�get_from_dnstrr �
to_be_deleted)rKr��s_dnstrs   r+�_mark_broken_ntdsconnzKCC._mark_broken_ntdsconn�sY���{�{�0�0�7�7�9�	-�G��,�,�.�G����4�;�;�;B�D�E�(,��%�	-r-c�L�|jj�rtd|jz�y|j}	|j	|j
j
��g}|j
j
�D]x}|j�}||jjvs�,|j�xs|j�}t|j�}|j||||f��zt!|�dkryt#j$|d�D]Z\}}|\}}}}|\}	}
}}|r||
k(r|j&|	j&ks |j&|	j&k(s�N||ks�Td|_�\y#t$r|j�rYyY��8wxYw)aFind unneeded intrasite NTDS Connections for removal

        Based on MS-ADTS 6.2.2.4 Removing Unnecessary Connections.
        Every DC removes its own unnecessary intrasite connections.
        This function tags them with the to_be_deleted attribute.

        :return: None
        z>not doing ntdsconn cleanup for site %s, because it is disabledN�T)rD�is_cleanup_ntdsconn_disabledr rBr�r�ryr�is_ror�rx�is_generated�is_rodc_topologyrr|�appendr��	itertools�permutationsr�r�)
rK�mydsa�local_connectionsr�r��	removable�packed_guid�a�b�cn_conn2�s_dnstr2�packed_guid2�
removable2s
             r+�_mark_unneeded_local_ntdsconnz!KCC._mark_unneeded_local_ntdsconn�s����<�<�4�4�6��.�04���=�
>������	��/�/��0C�0C�0J�0J�0L�M����*�*�1�1�3�	C�G��,�,�.�G��$�,�,�0�0�0�!(�!5�!5�!7�"<�!(�!9�!9�!;�=�	�&�w�|�|�4��!�(�(�'�7�*5�y�*B�C�
	C�
�!�"�Q�&���*�*�+<�a�@�	-�D�A�q�78�4�G�W�k�9�;<�8�H�h��j���8�#��#�#�h�&:�&:�:��$�$��(<�(<�<��|�+�(,��%�	-��+�	��{�{�}���	�s�)F�F#�"F#c�`�|jj�ry|jj}g}|j	�D]�}|j
j	�D]r}|jr�|j�}|��#||vs�(|j|�}|�d|vr tjd|z�d|_�_|j|||f��t��|jd�|D��|D]�\}}}|j�r|j�r�(||jvr%|j!|d�s|j!|d�s�[|j"}|j$j	�D]7}	||	j&vs�|D]!\}
}}||
us�||	j&vs�d|_�#�9��y)a(find unneeded intersite NTDS Connections for removal

        Based on MS-ADTS 6.2.2.4 Removing Unnecessary Connections. The
        intersite topology generator removes links for all DCs in its
        site. Here we just tag them with the to_be_deleted attribute.

        :return: None
        N�\0ADELz+DSA appears deleted, removing connection %sTc3�&K�|]	}|d���y�w)rNr/rqs  r+rtz8KCC._mark_unneeded_intersite_ntdsconn.<locals>.<genexpr>'s����+O�Q�A�a�D�+O�s�)rBr�rDrxryr�r�r�r<r!�infor�r�r�r�r@�is_bridgehead_failed�	dsa_dnstrr5�rw_dsa_table)
rK�
local_dsas�connections_and_dsas�dsa�cnr��from_dsa�to_dsa�
from_dnstrr{�cn2�to_dsa2�	from_dsa2s
             r+�!_mark_unneeded_intersite_ntdsconnz%KCC._mark_unneeded_intersite_ntdsconns����;�;������\�\�+�+�
�!���$�$�&�	E�C��'�'�.�.�0�
E���#�#���+�+�-���?���*�,�#�|�|�G�4�H��'�9��+?����$Q�&-�%.�/�+/��(� �(�/�/��S�(�0C�D�
E�	E�"	
�+�+�+O�:N�+O�O�$8�	4� �B����?�?�$��(;�(;�(=���d�+�+�+��.�.�v�t�<��.�.�x��>��
"�+�+�J����.�.�0�
4����!2�!2�2�3G�4�/��W�i��c�M�%��):�):�:�/3�B�,�4�
4�	4r-c���|j�s|jr�|jj�D]o}|jrtjd|z�|jrtjd|z�|js�Xtjd|z��q|j|jd��y|j|j�y)N�TO BE DELETED:
%s�TO BE ADDED:
%s�TO BE MODIFIED:
%sT��ro)r�rHr�ryr�r!r��to_be_added�to_be_modified�commit_connectionsrE)rKr��connects   r+�_commit_changeszKCC._commit_changes>s����9�9�;�$�-�-��,�,�3�3�5�
A���(�(��K�K� 4�w� >�?��&�&��K�K� 2�W� <�=��)�)��K�K� 5�� ?�@�

A�
�"�"�4�:�:�$�"�7�
�"�"�4�:�:�.r-c��|j�|j�|jj�r|r|j	�|j
jj�D]}|j|��y)z�Remove unneeded NTDS Connections once topology is calculated

        Based on MS-ADTS 6.2.2.4 Removing Unnecessary Connections

        :param all_connected: indicates whether all sites are connected
        :return: None
        N)	r�r�rB�is_istgr�rDrxryr�)rK�
all_connectedr�s   r+�remove_unneeded_ntdsconnzKCC.remove_unneeded_ntdsconnOsl��	
�"�"�$��*�*�,��;�;��� �]��2�2�4��<�<�)�)�0�0�2�	&�C�� � ��%�	&r-c��|j}||jjv}t|j�}||jk7r||_|j
tjzdk(r#|xj
tjzc_|j�rC|j
tjzdk(r#|xj
tjzc_|s|j|�rC|j
tjzdk(r#|xj
tjzc_|jtjzdk7rd|jtjzdk(r�|j
tj zdk(ri|xj
tj zc_nE|sC|j
tj zdk(r#|xj
tj zc_|sc|jtj"zdk(rC|j
tj$zdk(r#|xj
tj$zc_|jtj&zdk7rC|j
tj(zdk(r#|xj
tj(zc_|j+�s�|j
tj,zdk(r#|xj
tj,zc_|j
tj.zdk(r#|xj
tj.zc_|j0�d|j2j5���}	|j
tj6zdk7r$|xj
tj6zc_t9j:�|_|j>|	k7r|	|_|j@dkDr|jB|	k7r|	|_!|jE�rtGd|z�yy)a$Update an repsFrom object if required.

        Part of MS-ADTS 6.2.2.5.

        Update t_repsFrom if necessary to satisfy requirements. Such
        updates are typically required when the IDL_DRSGetNCChanges
        server has moved from one site to another--for example, to
        enable compression when the server is moved from the
        client's site to another site.

        The repsFrom.update_flags bit field may be modified
        auto-magically if any changes are made here. See
        kcc_utils.RepsFromTo for gory details.


        :param n_rep: NC replica we need
        :param t_repsFrom: repsFrom tuple to modify
        :param s_rep: NC replica at source DSA
        :param s_dsa: source DSA
        :param cn_conn: Local DSA NTDSConnection child

        :return: None
        rz._msdcs.r&zmodify_repsFrom(): %sN)$r�rDrxr�schedule�
replica_flagsr�DRSUAPI_DRS_ADD_REF�!is_schedule_minimum_once_per_week�DRSUAPI_DRS_PER_SYNC�is_fsmo_role_owner�DRSUAPI_DRS_INIT_SYNC�optionsr�$NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT�NTDSCONN_OPT_USE_NOTIFY�DRSUAPI_DRS_NEVER_NOTIFY�*NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION�DRSUAPI_DRS_USE_COMPRESSION�NTDSCONN_OPT_TWOWAY_SYNC�DRSUAPI_DRS_TWOWAY_SYNC�
is_enabled�DRSUAPI_DRS_DISABLE_AUTO_SYNC�!DRSUAPI_DRS_DISABLE_PERIODIC_SYNCr(rE�forest_dns_name�DRSUAPI_DRS_MAIL_REPrr��transport_guidr��version�	dns_name2�is_modifiedr )
rK�n_rep�
t_repsFrom�s_rep�s_dsar�r��	same_site�times�nastrs
          r+�modify_repsFromzKCC.modify_repsFromas���0�/�/���t�|�|�5�5�5�	�.�g�.>�.>�?���J�'�'�'�"'�J���
%�
%�
�
(�
(�)�-0�
1��$�$��(C�(C�C�$��4�4�6��)�)��-�-�.�25�6��(�(�G�,H�,H�H�(���0�0��9��)�)��.�.�/�36�7��(�(�G�,I�,I�I�(��_�_�
�
6�
6�7�;>�
?����$�">�">�>�3�F� �-�-��5�5�6�:=�>��,�,��8�8�9�,���)�)��1�1�2�69�:��(�(�G�,L�,L�L�(��
�_�_�
�
<�
<�=�AD�
E��)�)��4�4�5�9<�=��(�(�G�,O�,O�O�(�
�O�O�d�;�;�;��C��)�)��0�0�1�58�9��(�(�G�,K�,K�K�(��!�!�#��)�)��6�6�7�;>�?��(�(��9�9�:�(��)�)��:�:�;�?B�C��(�(��=�=�>�(�~#(�.�.�$�*�*�2L�2L�2N�O��
�
%�
%�
�
)�
)�*�.1�
2��$�$��)E�)E�(E�E�$�$(�I�I�K�
�!����5�(�#(�J� �����#�
�(<�(<��(E�#(�J� ��!�!�#��,�z�9�:�$r-c�,�|j�r|j�ry|j�}|j|�}|�y|j	|j
�}|�2|j
�r"|j�r|j�r|Sy)a�If a connection imply a replica, find the relevant DSA

        Given a NC replica and NTDS Connection, determine if the
        connection implies a repsFrom tuple should be present from the
        source DSA listed in the connection to the naming context. If
        it should be, return the DSA; otherwise return None.

        Based on part of MS-ADTS 6.2.2.5

        :param n_rep: NC replica
        :param cn_conn: NTDS Connection
        :return: source DSA or None
        N)	rr�r�r<�get_current_replica�nc_dnstr�
is_presentr��
is_partial)rKrr�r�r rs      r+�get_dsa_for_implied_replicazKCC.get_dsa_for_implied_replica0s���*�!�!�#�w�'?�'?�'A���(�(�*�����W�%���=���)�)�%�.�.�9������������%�"2�"2�"4��L�r-c	��d}|�|j}|j�rd}|j�rtd�ytd�|j	�\}}t�}|D]�}|r�||}|j
|j�|jD]m}tjtjztjztjztjz}	|j|	k7s�g|	|_�o|j!|j|j"����||vs��|j%|���tdt'|�t'|�t'|�fz�|rt)d|z�|D]}||=�|j+�D�]�}
|
j
|j�|
j-|j�|
jD]�}t/|j0�}|j3|�}|� t5j6d	|z�d|_�K|j:}
|j=|
�}|D]}|j?�r�n	d|_��|jA|
jB�}|�0|jE�r |
j�s|jG�rd|_��|jI|
||||���|jJj+�D]�}|jM|
|�}|��|
jD].}t/|j0�}||j3|�us�,d}n|��XtO|
jB�}|jP|_|jA|
jB�}|jI|
||||�|jS�s��|
jjU|���|j"s|rs|
jW�}|rt5jXd
|z�|
j[�}|rt5jXd|z�|
j!|jd�����|
j!|j����|ry|j+�D�]T}
|
j]|j�|
j^D]�}t/|j0�}|j3|�}|� t5j6d|z�d|_�K|j:}
d
|
vr t5j6d|z�d|_�{|j=|j`�}t'|�dkDr��d|_��|j"rU|
j^D]'}|j8s�t5jXd|z��)|
jc|jd����:|
jc|j���Wy)a[Adjust repsFrom to match NTDSConnections

        This function adjusts values of repsFrom abstract attributes of NC
        replicas on the local DC to match those implied by
        nTDSConnection objects.

        Based on [MS-ADTS] 6.2.2.5

        :param current_dsa: optional DSA on whose behalf we are acting.
        :return: None
        FNTz;skipping translate_ntdsconn() because disabling flag is setztranslate_ntdsconn(): enterr�zcurrent %d needed %d delete %dzdeleting these reps: %sz'repsFrom source DSA guid (%s) not foundr�r�z%repsTo source DSA guid (%s) not foundr�z+repsTo source DSA guid (%s) appears deletedrzREMOVING REPS-TO: %s)2rBr��is_translate_ntdsconn_disabledr r�r>�
load_repsFromrEr�rrr	r�%DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING�DRSUAPI_DRS_NONGC_RO_REPr�commit_repsFromrHr�r�rry�load_fsmo_rolesrZr�r;r!r^r�r��get_connection_by_from_dnstrr�r&r'r(r)r$r�r*rr(rr��dumpstr_to_be_deletedr��dumpstr_to_be_modified�load_repsTo�
rep_repsTorA�
commit_repsTo)rK�current_dsar��current_rep_table�needed_rep_table�delete_repsrd�c_reprrr�guidstrr r�r�r�r�text�t_repsTo�rts                    r+�translate_ntdsconnzKCC.translate_ntdsconnWs��������+�+�K������B��5�5�7��5�
6���.�/�.9�.H�.H�.J�+��+��e��"'�	+�E��)�%�0���#�#�D�J�J�/�"'�"4�"4�A�J�%,�%B�%B�%,�%A�%A�&B�%,�%@�%@�&A�&-�%R�%R�&S�&-�%E�%E�	&F�M�
"�/�/�=�@�3@�
�0�A��%�%�d�j�j�T�]�]�%�C�� 0�0��O�O�E�*�!	+�$	�1�S�9J�5K��%�&��K�(8�5:�:�	;���+�k�9�:�$�
-��%�e�,�
-�&�,�,�.�k	2�E�
����
�
�+��!�!�$�*�*�-�
$�0�0�-
O�
��j�<�<�=���/�/��8���=��N�N�#L�#*�$+�,�/3�J�,��
 �/�/��)�F�F�w�O��*��G�"�3�3�5���
04�J�,���1�1�%�.�.�A���=��(8�(8�(:����
�%�*:�*:�*<�/3�J�,���$�$�U�J��u�g�N�[-
O�d'�4�4�;�;�=�
:���8�8���H���=��#(�"4�"4��J�!�*�"@�"@�A�G��� 7� 7�� @�@� $���	��=��(����7�
�16���
�.��1�1�%�.�.�A���$�$�U�J��u�g�N��)�)�+��&�&�-�-�j�9�?
:�B�}�}���2�2�4����K�K� 4�t� ;�<��3�3�5����K�K� 5�� <�=��%�%�d�j�j�T�%�:��%�%�d�j�j�1�Wk	2�h��%�,�,�.�5	0�E�
���d�j�j�)�
"�,�,�
2���h�:�:�;���/�/��8���=��N�N�#J�#*�$+�,�-1�H�*��
 �/�/����'��N�N�#P�#*�$+�,�-1�H�*��#�@�@��AR�AR�S���{�#�a�'��.2�H�*�?
2�B�}�}��*�*�A�B��'�'����$:�R�$?�@�A��#�#�D�J�J�4�#�8��#�#�D�J�J�/�k5	0r-c�J�|�tjd�ytd�y)a�Merge of kCCFailedLinks and kCCFailedLinks from bridgeheads.

        The KCC on a writable DC attempts to merge the link and connection
        failure information from bridgehead DCs in its own site to help it
        identify failed bridgehead DCs.

        Based on MS-ADTS 6.2.2.3.2 "Merge of kCCFailedLinks and kCCFailedLinks
        from Bridgeheads"

        :param ping: An oracle of current bridgehead availability
        :return: None
        Nz'merge_failed_links() is NOT IMPLEMENTEDz}skipping merge_failed_links() because it requires real network connections
and we weren't asked to --attempt-live-connections)r"�	DEBUG_REDr )rKr�s  r+�merge_failed_linkszKCC.merge_failed_linksVs&��$���O�O�E�F��J�
Kr-c
�j�|jjdzdk7}t|jj�}t||j||j|�}|js|j��g}|jD]e}tj|jd�D]@\}}|j|jj |jj f��B�gd}	d|j"z}
t%|
|d|j&|	t(|j|j��|S)a�Set up an intersite graph

        An intersite graph has a Vertex for each site object, a
        MultiEdge for each SiteLink object, and a MutliEdgeSet for
        each siteLinkBridge object (or implied siteLinkBridge). It
        reflects the intersite topology in a slightly more abstract
        graph form.

        Roughly corresponds to MS-ADTS 6.2.2.3.4.3

        :param part: a Partition object
        :returns: an InterSiteGraph object
        irr�r/z
site_edges_%sF��directed�label�
propertiesr"rIrJ)rD�site_optionsrZr6r|rr5r7rIrJ�edgesr��combinations�verticesr�r{�
site_dnstrr�rrAr)rKr��bridges_requiredr�g�	dot_edges�edger�r��verify_propertiesr]s           r+rzKCC.setup_graphos��& �<�<�4�4�z�A�Q�F���T�.�.�3�3�4����d�o�o�~��+�+�-=�
?���;�;�$�+�+�7��I����
M��%�2�2�4�=�=�!�D�M�D�A�q��$�$�a�f�f�&7�&7����9J�9J�%K�L�M�
M�!#��"�T�\�\�1�D��4��U�!%�!2�!2�&7�u�"&�+�+�(,�(9�(9�	
;��r-c���|j|||||�}|s#tjd|jz�ytjd|j�d|dj
���|dS)a�Get a bridghead DC for a site.

        Part of MS-ADTS 6.2.2.3.4.4

        :param site: site object representing for which a bridgehead
            DC is desired.
        :param part: crossRef for NC to replicate.
        :param transport: interSiteTransport object for replication
            traffic.
        :param partial_ok: True if a DC containing a partial
            replica or a full replica will suffice, False if only
            a full replica will suffice.
        :param detect_failed: True to detect failed DCs and route
            replication traffic around them, False to assume no DC
            has failed.
        :return: dsa object for the bridgehead DC or None
        z"get_bridgehead FAILED:
sitedn = %sNzget_bridgehead:
	sitedn = z	
	bhdn = r)�get_all_bridgeheadsr"�
DEBUG_MAGENTArN�DEBUG_GREENr�)rKr{r�re�
partial_ok�
detect_failed�bhss       r+�get_bridgeheadzKCC.get_bridgehead�sr��&�&�&�t�T�9�'1�=�B������ E� $���!0�
1��
����?�?�C��F�,<�,<�>�	?��1�v�
r-c��g}|jdk7rtd|j����t|j�|jj	�D�]R}|j�}t
|j�dk7r||jvr�;|jj|�r8|j|�\}	}
}|	r|r|s�r|j|j�}n0|j|j�}|�|j�r|s��|jj�r3|�1|j!�r!|j#t$j&�s��|j)||�r
t+d���*td|j,z�|j/|���U|j1�r |j3t5t6���nt9j:|�t=j>|�|S)a�Get all bridghead DCs on a site satisfying the given criteria

        Part of MS-ADTS 6.2.2.3.4.4

        :param site: site object representing the site for which
            bridgehead DCs are desired.
        :param part: partition for NC to replicate.
        :param transport: interSiteTransport object for
            replication traffic.
        :param partial_ok: True if a DC containing a partial
            replica or a full replica will suffice, False if
            only a full replica will suffice.
        :param detect_failed: True to detect failed DCs and route
            replication traffic around them, FALSE to assume
            no DC has failed.
        :return: list of dsa object for available bridgehead DCs
        rRz5get_all_bridgeheads has run into a non-IP transport! rzbridgehead is failedzfound a bridgehead: %s��key) r]rr r�ry�get_parent_dnstrr��bridgehead_listrDr!�should_be_presentr&r'r)rBr��
is_default�is_minimum_behaviorr�DS_DOMAIN_FUNCTION_2008r�rr�r��is_random_bridgehead_disabled�sortrr,�random�shuffler"�DEBUG_YELLOW)
rKr{r�rerXrYrZr��pdnstrr�r��partial�reps
             r+rUzKCC.get_all_bridgeheads�s���&���>�>�T�!��'�n�n�/�0�
0�	��"�"�#��$�$�+�+�-�/	�C��)�)�+�F�
�Y�.�.�/�1�4��y�8�8�8���|�|�%�%�c�*�&*�&<�&<�S�&A�#���G��'�*���-�-�d�m�m�<���-�-�d�m�m�<���;�3�>�>�#3�J���{�{� � �"�s��3�>�>�;K��.�.�t�/K�/K�L���(�(��m�<��,�-���-��
�
�=�>��J�J�s�O�_/	�n�-�-�/��H�H��$;�<�H�=��N�N�3��
���3���
r-c�^�|sy|jjdzry|j|�S)adDetermine whether a given DC is known to be in a failed state

        :param dsa: the bridgehead to test
        :param detect_failed: True to really check, False to assume no failure
        :return: True if and only if the DC should be considered failed

        Here we DEPART from the pseudo code spec which appears to be
        wrong. It says, in full:

    /***** BridgeheadDCFailed *****/
    /* Determine whether a given DC is known to be in a failed state.
     * IN: objectGUID - objectGUID of the DC's nTDSDSA object.
     * IN: detectFailedDCs - TRUE if and only failed DC detection is
     *     enabled.
     * RETURNS: TRUE if and only if the DC should be considered to be in a
     *          failed state.
     */
    BridgeheadDCFailed(IN GUID objectGUID, IN bool detectFailedDCs) : bool
    {
        IF bit NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED is set in
        the options attribute of the site settings object for the local
        DC's site
            RETURN FALSE
        ELSEIF a tuple z exists in the kCCFailedLinks or
        kCCFailedConnections variables such that z.UUIDDsa =
        objectGUID, z.FailureCount > 1, and the current time -
        z.TimeFirstFailure > 2 hours
            RETURN TRUE
        ELSE
            RETURN detectFailedDCs
        ENDIF
    }

        where you will see detectFailedDCs is not behaving as
        advertised -- it is acting as a default return code in the
        event that a failure is not detected, not a switch turning
        detection on or off. Elsewhere the documentation seems to
        concur with the comment rather than the code.
        F�)rDrJr�)rKr�rYs   r+r�zKCC.is_bridgehead_faileds3��P��
�<�<�$�$�z�1���,�,�S�1�1r-c	��|j||||	d�}td�|D��}tjdt	|��d|D�
cgc]}
|
j
��c}
���|j||||	d�}|j
�r|j|�tjdt	|��d|D�
cgc]}
|
j
��c}
���|D�]w}|jj�D�]V}|j|j�}|��"tjd|j
z�|j�s�U|j�r�f|j|j k(s��|j#�s)|j%|�s||_|j)d�|j+�rm|j-�r]|t.j0zd	k(r�|xj2t.j4t.j6zzc_|j)d�n[|t.j0zd	k7rE|xj2t.j4t.j6zzc_|j)d�|j9�rL|t.j:zd	k(r�|xj2t.j<zc_|j)d�nJ|t.j:zd	k7r4|xj2t.j<zc_|j)d�|j?�rL|t.j@zd	k(r�|xj2t.jBzc_|j)d�nJ|t.j@zd	k7r4|xj2t.jBzc_|j)d�|jDs|j
�rC|jFrtIjJd
|z�|jM|jNd����<|jM|jN���Y��zd	}|D]�}|jj�D]�}|j|j�}|��!tjd|j
z�|j�r|j|j k(s�m|j�r�~|jQ||
�s|jQ||
�s|d
z
}|jRjU|�����tjVd|z�tYd|jR���|d	k(�r�t.jZ}|t.j0zd	k7r$|t.j4t.j6zz}|t.j:zd	k7r|t.j<z}|t.j@zd	k7r|t.jBz}t]d|j^j
z�t.j`t.jbz}|je||||j
|�}|jDs|j
�rB|jfrtIjJd|z�|jM|jNd��n|jM|jN�|jRjU|�yycc}
wcc}
w)a�Create an nTDSConnection object as specified if it doesn't exist.

        Part of MS-ADTS 6.2.2.3.4.5

        :param part: crossRef object for the NC to replicate.
        :param rbh: nTDSDSA object for DC to act as the
            IDL_DRSGetNCChanges server (which is in a site other
            than the local DC's site).
        :param rsite: site of the rbh
        :param transport: interSiteTransport object for the transport
            to use for replication traffic.
        :param lbh: nTDSDSA object for DC to act as the
            IDL_DRSGetNCChanges client (which is in the local DC's site).
        :param lsite: site of the lbh
        :param link_opt: Replication parameters (aggregated siteLink options,
                                                 etc.)
        :param link_sched: Schedule specifying the times at which
            to begin replicating.
        :partial_ok: True if bridgehead DCs containing partial
            replicas of the NC are acceptable.
        :param detect_failed: True to detect failed DCs and route
            replication traffic around them, FALSE to assume no DC
            has failed.
        Fc3�8K�|]}|j|f���y�wro�r�rqs  r+rtz(KCC.create_connection.<locals>.<genexpr>^s����<�a�!�+�+�q�)�<�s�z
rbhs_all: � z
lbhs_all: Nz
rdsa is %sTrr�r�zround 2: rdsa is %sr&zvalid connections %dzkept_connections:
znew connection, KCC dsa: %sr�)4rU�dictr"�
DEBUG_GREYr�r�r�r�r�ryr:r�r�r�r�rr|�is_user_owned_schedule�is_equivalent_scheduler�set_modified�is_override_notify_default�
is_use_notifyr�NTDSSITELINK_OPT_USE_NOTIFYrr
r�is_twoway_sync�NTDSSITELINK_OPT_TWOWAY_SYNCr�!is_intersite_compression_disabled�$NTDSSITELINK_OPT_DISABLE_COMPRESSIONrrHr�r!r�r�rEr�r@r�rCr�NTDSCONN_OPT_IS_GENERATEDr rB�SYSTEM_FLAG_CONFIG_ALLOW_RENAME�SYSTEM_FLAG_CONFIG_ALLOW_MOVE�new_connectionr�)rKr��rbh�rsitere�lbh�lsite�link_opt�
link_schedrXrY�rbhs_all�	rbh_tablers�lbhs_all�ldsar��rdsa�valid_connections�opt�system_flagss                     r+�create_connectionzKCC.create_connectionAs���6�+�+�E�4��,6��?���<�8�<�<�	�
���c�(�m�DL�.M�q�q�{�{�.M�O�	P��+�+�E�4��,6��?���9�9�;��O�O�C� �
���c�(�m�DL�.M�q�q�{�{�.M�O�	P��o	<�D��(�(�/�/�1�n
<�� �}�}�R�]�]�3���<���'�'��t�~�~�(E�F��_�_�&��,�,�.��&�&�)�.�.�8� �6�6�8��6�6�z�B�&0�������-��4�4�6��'�'�)�%�t�'G�'G�G�A�M��J�J�"&�"K�"K�"&�">�">�#?�!@�@�J��O�O�D�1�%�t�'G�'G�G�A�M��J�J�!%�!J�!J�!%�!=�!=�">�?�J��O�O�D�1��(�(�*�%�t�'H�'H�H�Q�N��J�J�4�+H�+H�*H�H�J��O�O�D�1�%�t�'H�'H�H�Q�N��J�J�$�*G�*G�G�J��O�O�D�1��;�;�=�&�!�F�F�G�KL�M��J�J�!%�!P�!P� P�Q�J��O�O�D�1�&�!�F�F�G�KL�M��J�J� $� O� O�P�J��O�O�D�1��}�}��
�
���,�,�"�K�K�(=��(B�C��/�/��
�
�t�/�D��/�/��
�
�;�]n
<�o	<�d���	2�D��(�(�/�/�1�
2�� �}�}�R�]�]�3���<���'�'�(=����(N�O�
�/�/�+��'�'�9�>�>�9��,�,�.�"�6�6�t�]�K�!�6�6�t�]�K�)�Q�.�)��)�)�-�-�b�1�9
2�	2�@	���.�1B�B�C�
��)>�)>�@�A���!��0�0�C�
�4�;�;�;��A���A�A��4�4�5�6��
�4�<�<�<��B��t�4�4�4��
��:�:�;�?@�A��t�F�F�F��
�2�T�[�[�5J�5J�J�K� �@�@� �>�>�?�L��#�#�C��y�$'�M�M�:�?�B��}�}��	�	���>�>��K�K� 2�R� 7�8��&�&�t�z�z�d�&�;��&�&�t�z�z�2�
�!�!�%�%�b�)�["��[/N��/Ns�\�:\	c�P�g|_g|_d}||jvr�t|jj
�}|j
|j|j|j|j�|�}|�9|jj�r|jj|�n9d}n6|jj|�|jj|�|jjd�|jjd�|S)a~Build a Vertex's transport lists

        Each vertex has accept_red_red and accept_black lists that
        list what transports they accept under various conditions. The
        only transport that is ever accepted is IP, and a dummy extra
        transport called "EDGE_TYPE_ALL".

        Part of MS-ADTS 6.2.2.3.4.3 -- ColorVertices

        :param vertex: the remote vertex we are thinking about
        :param local_vertex: the vertex relating to the local site.
        :param graph: the intersite graph
        :param detect_failed: whether to detect failed links
        :return: True if some bridgeheads were not found
        FT�
EDGE_TYPE_ALL)�accept_red_red�accept_black�connected_verticesrZr6r|r[r{r��is_black�is_rodc_siter�)rK�vertex�local_vertex�graphrY�found_failed�t_guid�bhs        r+�add_transportszKCC.add_transports=s���2!#��� ������U�-�-�-���*�*�/�/�0�F��$�$�V�[�[�&�+�+�%)�%6�%6�%+�_�_�%6�
�G�B��z��;�;�+�+�-��)�)�0�0��8�#'�L��%�%�,�,�V�4��#�#�*�*�6�2�	���$�$�_�5����"�"�?�3��r-c
��d}d}td|j�d|���t|j|�}|j	�|j
D])}|j	�|j
||||�s�(d}�+|j�r||fSt||j|j��\}}	td|j|	fz�|	dkDrd}|j�}
|j}td|z�|D�]�}|jr&|j
d	j|jur�6|j
d	j|jur|j
dj}
n|j
d	j}
|
|jurtd
���|j|
|||
|�}|���|j j#�r|j}|j }n!|j}|j||||
|�}|�t%j&d�y
td|�d|
���td|j
���t%j(d|�d|�dd���|j*}|�d	}d}n|j,}|j.}|j1|||
||||||
|�
���||fS)a1Create intersite NTDSConnections as needed by a partition

        Construct an NC replica graph for the NC identified by
        the given crossRef, then create any additional nTDSConnection
        objects required.

        :param graph: site graph.
        :param part: crossRef object for NC.
        :param detect_failed:  True to detect failed DCs and route
            replication traffic around them, False to assume no DC
            has failed.

        Modifies self.kept_connections by adding any connections
        deemed to be "in use".

        :return: (all_connected, found_failed_dc)
        (all_connected) True if the resulting NC replica graph
            connects all sites that need to be connected.
        (found_failed_dc) True if one or more failed DCs were
            detected.
        TFz$create_connections(): enter
	partdn=z
	detect_failed=)rHz%s Number of components: %dr&zedge_list %srzrsite is my_siteNzDISASTER! lbh is None)FTzlsite: z
rsite: z	vertices zbridgeheads
�
zF----------------------------------------------------------------------)r r'rrD�color_vertexrMr��is_whiterr�r�r6rrGr{r[rBr�r"rC�
DEBUG_BLUE�	site_linkrrr�)rKr�r�rYrr��	my_vertex�v�	edge_list�n_componentsrXrer�r�r�r�r�rjr�r�s                    r+�create_connectionszKCC.create_connectionsos���,�
�����-�-��0�	1��4�<�<��.�	���� ����	$�A�
�N�N���"�"�1�i��
�F�#��	$����� �,�.�.�"9�%�:>�,�,�@D���#N��	�<�	�.��-�-��.�/�	0��!��!�M��'�'�)�
��%�%�	�
�n�y�(�)��6	>�A��z�z�a�j�j��m�0�0�D�L�L�@���z�z�!�}�!�!�T�\�\�1��
�
�1�
�*�*���
�
�1�
�*�*������$��(�)���%�%�e�T�9�&0�-�A�C��{���{�{� � �"������k�k�������)�)�%��y�*4�m�E���{���� 7�8�"��u�e�<�=��a�j�j�2�3����#�s�H�M�N��{�{�H�����!�
�#�+�+��%�.�.�
��"�"�4��e�Y�#&��x��#-�}�
>�i6	>�p�l�*�*r-c�T�d}t�|_|jj�D]y}|j	�s�|j�r�%|j
|�}d}|j||d�\}}td|�d|���|r�bd}|s�g|j||d��{|S)a�Create NTDSConnections as necessary for all partitions.

        Computes an NC replica graph for each NC replica that "should be
        present" on the local DC or "is present" on any DC in the same site
        as the local DC. For each edge directed to an NC replica on such a
        DC from an NC replica on a DC in another site, the KCC creates an
        nTDSConnection object to imply that edge if one does not already
        exist.

        Modifies self.kept_connections - A set of nTDSConnection
        objects for edges that are directed
        to the local DC's site in one or more NC replica graphs.

        :return: True if spanning trees were created for all NC replica
                 graphs, otherwise False.
        TFzwith detect_failed: connected z Found failed )	r>r@r4ryr�
is_foreignrr�r)rKrr�r�r��	connecteds      r+�create_intersite_connectionsz KCC.create_intersite_connections�s���"�
� #�����O�O�*�*�,�	@�D��?�?�$����� ���$�$�T�*�E�!�L�&*�&=�&=�e�>B�D�'J�#�I�|�
��l�,�
-�� %�
���+�+�E�4��?�3	@�6�r-c��|j}|j}d}td�|jr|j	|j
|d��n|j	|j
|d��|j
�rtd|z�|S|j�std|z�|S|j|�|j�}td|z�|S)amGenerate the inter-site KCC replica graph and nTDSConnections

        As per MS-ADTS 6.2.2.3.

        If self.readonly is False, the connections are added to self.samdb.

        Produces self.kept_connections which is a set of NTDS
        Connections that should be kept during subsequent pruning
        process.

        After this has run, all sites should be connected in a minimum
        spanning tree.

        :param ping: An oracle function of remote site availability
        :return (True or False):  (True) if the produced NC replica
            graph connects all sites that need to be connected
        Tzintersite(): enterr�Fz+intersite(): exit disabled all_connected=%dz+intersite(): exit not istg all_connected=%dz"intersite(): exit all_connected=%d)
rBrDr rH�select_istgrE�is_intersite_topology_disabledrrDr�)rKr�r��mysiters     r+�	intersitez
KCC.intersite%s���(���������
��%�&��=�=����t�z�z�5�T��:����t�z�z�5�U��;��0�0�2��B�"�#�
$� � ��}�}���B�"�#�
$� � �����%��9�9�;�
��5�
�E�F��r-c��|jj�sy|jjj�}|D�cgc]}|j	�s�|��}}|D�cgc]}||vr|��
}}|r`|r]|D]0}|d}|j
|_|j|_d|_�2|jj|j|��yyycc}wcc}w)zoUpdates the RODC NTFRS connection object.

        If the local DSA is not an RODC, this does nothing.
        NrTr�)
rBr�r�ryr�r�rr�r�rE)rKr��all_connectionsrs�ro_connections�rw_connections�conr�s        r+�update_rodc_connectionzKCC.update_rodc_connection`s���
�{�{� � �"���+�+�3�3�:�:�<��%4�M���8J�8J�8L�!�M��M�%4�6���n�4��6��6��n�%�
*��$�Q�'��!$�����"�|�|���%)��"�	
*�
�K�K�*�*�4�:�:�"�*�=�-�>��N��6s�C�C�$
Cc�X�d}	|d||zzd|zzdzkrn|dz}�|dz}|dkr|Sy)amFind the maximum number of edges directed to an intrasite node

        The KCC does not create more than 50 edges directed to a
        single DC. To optimize replication, we compute that each node
        should have n+2 total edges directed to it such that (n) is
        the smallest non-negative integer satisfying
        (node_count <= 2*(n*n) + 6*n + 7)

        (If the number of edges is m (i.e. n + 2), that is the same as
        2 * m*m - 2 * m + 3). We think in terms of n because that is
        the number of extra connections over the double directed ring
        that exists by default.

        edges  n   nodecount
          2    0    7
          3    1   15
          4    2   27
          5    3   43
                  ...
         50   48 4903

        :param node_count: total number of nodes in the replica graph

        The intention is that there should be no more than 3 hops
        between any two DSAs at a site. With up to 7 nodes the 2 edges
        of the ring are enough; any configuration of extra edges with
        8 nodes will be enough. It is less clear that the 3 hop
        guarantee holds at e.g. 15 nodes in degenerate cases, but
        those are quite unlikely given the extra edges are randomly
        arranged.

        :param node_count: the number of nodes in the site
        "return: The desired maximum number of connections
        rr���r&�2r/)rK�
node_count�ns   r+�intrasite_max_node_edgeszKCC.intrasite_max_node_edges�sV��F
����a�1�q�5�k�Q��U�3�a�7�8���A��A��
��E���r�6��H�r-c�D��|j|�\}}}tjdd|zzd|zzd|zzd|zzd|zzd|zz�|s#tjd|jz�y	t||j�}	|	j
�j�||	_||	_	|j|	�g}
�jjj�D]�}|j|jvr�|j|j}|j�r�F|j!�s�W|j�s||ur�l|r|j#�s�|r?|s=|j$t&j(k(r |j+t,j.�s��|r�j1|�r��|
j3|���|rʉjjj�D]�}|j|jvr�|j|j}
|
j5�s�F|
j!�s�W|j�s||ur�l|r|j#�s�|r�j1|�r��|
j3|
���|
j3|	�|
j7d
���t9|
�}�j;|�}g}|
D])}t=|j>|�}|j3|��+d}||d
z
kr�|
|j5�r|
|d
zj5�r$||d
zjA|
|j>�|
|d
zj5�r|
|j5�r$||jA|
|d
zj>�|d
z}||d
z
kr��|
|d
z
j5�r|
dj5�r$|djA|
|d
z
j>�|
dj5�r|
|d
z
j5�r$||d
z
jA|
dj>�tCdt9|
�z�tCdjEd�|
D����jFd	uxr�j}�jHs|�rUg}tK�}|D]\}|jM|jN�|jPD]0}|j3||jNf�|jM|��2�^d}tSd|||jT�dtV|j$�d|j��|tB�jH�jFd��	tK�fd�|D��}|D��cgc]\}}||vr||vr||f��}}}d}tSd|||jT�dtV|j$�d|j��|tB�jH�jFd��	|D]z}�jj|jN} | jXj�D]8}!|!jZ}"|"�jjvs�(|jA|"��:�|tCddjEd�|
D��z�tCddjEd�|D��z�|D�]�}#|dk\�r;|#j]��s*|D�$cgc] }$|$|#ur|$jN|#jPvr|$��"}%}$tj^d|#jN|t9|�t9|%�fz�tCd |%D�$cgc]}$|$jN��c}$z�|%r�|#j]�s�tajb|%�}&tCd!|&jNz�|#jA|&jN�s"tjd"|&jNz�|%je|&�|%rP|#j]�s��n>tgd#|#jN�d$|�d%t9|#jP��d&|#jh���tgd'|#z�|#jN|jNk(s���|#jk|�jl�����jHs|�rVg}tK�}|D]\}|jM|jN�|jPD]0}|j3||jNf�|jM|��2�^d}tSd(|||jT�dtV|j$�d|j��|tB�jH�jFd��	tK�fd)�|D��}|D��cgc]\}}||vr||vr||f��}}}d}tSd*|||jT�dtV|j$�d|j��|tB�jH�jFd��	y	y	cc}}wcc}$wcc}$wcc}}w)+aTCreate an intrasite graph using given parameters

        This might be called a number of times per site with different
        parameters.

        Based on [MS-ADTS] 6.2.2.2

        :param site_local: site for which we are working
        :param dc_local: local DC that potentially needs a replica
        :param nc_x:  naming context (x) that we are testing if it
                    "should be present" on the local DC
        :param gc_only: Boolean - only consider global catalog servers
        :param detect_stale: Boolean - check whether links seems down
        :return: None
        z"construct_intrasite_graph(): enterz
	gc_only=%dz
	detect_stale=%dz
	needed=%sz
	ro=%sz
	partial=%sz
%szH%s lacks 'should be present' status, aborting construct_intrasite_graph!Nc�,�t|j�Sro)r�rep_dsa_guid)rls r+�<lambda>z/KCC.construct_intrasite_graph.<locals>.<lambda>�s��H�S�-=�-=�$>�r-r]rr&zr_list is length %sr�c3�^K�|]%}t|j|jf����'y�wro)rZr��
rep_dsa_dnstrrqs  r+rtz0KCC.construct_intrasite_graph.<locals>.<genexpr>�s*����)���Q�^�^�Q�_�_�=�>�)�s�+-�r��intrasite_pre_ntdscon�__T)rHrIr"rIrJrGc3�`�K�|]%}�j|�j�s|���'y�wro�r<r��rrrsrKs  �r+rtz0KCC.construct_intrasite_graph.<locals>.<genexpr>��.�����"B��)-���a��)>�)>�)@�#$�"B���+.)r��directed_double_ring_or_small�intrasite_rw_pre_ntdsconz
reps are:  %sz   c3�4K�|]}|j���y�wro)r�rqs  r+rtz0KCC.construct_intrasite_graph.<locals>.<genexpr>�s����*K�q�1�?�?�*K���z
dsas are:  %sc3�4K�|]}|j���y�wrorqrqs  r+rtz0KCC.construct_intrasite_graph.<locals>.<genexpr>�s����*K�1�1�;�;�*K�r��zDlooking for random link for %s. r_len %d, graph len %d candidates %dz
candidates %sztrying to add candidate %szcould not add %sznot adding links to z: nodes z, links is �/z%s�intrasite_post_ntdsconc3�`�K�|]%}�j|�j�s|���'y�wror�r�s  �r+rtz0KCC.construct_intrasite_graph.<locals>.<genexpr>'	r�r��intrasite_rw_post_ntdscon)7rar"rirCr'r�identify_by_basednrE�rep_partial�rep_ro�add_needed_replicarDrxryr9r�r(r'�nc_typer�domainrcrrdr�r�r)rfr�r�rr��
add_edge_fromr�joinrJrIr>r�r��	edge_fromrrNrr�r��has_sufficient_edgesr�rg�choice�remover �	max_edges�add_connections_from_edgesr6)'rK�
site_local�dc_local�nc_x�gc_only�detect_staler�r�rk�l_of_x�r_list�dc_s�f_of_x�p_of_x�r_len�max_node_edges�
graph_listrl�node�i�do_dot_filesrQ�dot_vertices�v1�v2rS�rw_dot_verticesr�r��rw_dot_edges�rw_verify_propertiesr�r�r��remote�tnoders�
candidates�others'`                                      r+�construct_intrasite_graphzKCC.construct_intrasite_graph�s�	���F#�4�4�X�>����G�
���?�+�g�5�6�0�<�?�@�+�V�3�4�'��+�	,�
,�g�5�6�"�D�=�
)�	*���O�O�B� �M�M�*�
+�
��8�T�]�]�3���!�!�$�*�*�-�$�����
�	�#�#�F�+�0���L�L�*�*�1�1�3�>	"�D��}�}�D�$:�$:�:���+�+�D�M�M�:�F��|�|�~��
�$�$�&��
�z�z�|�t�x�/��
�t�z�z�|��(�'�d�l�l�f�m�m�&C��/�/��0L�0L�M��
�� =� =�d� C��
�M�M�&�!�}>	"�X����.�.�5�5�7�*
&��
�=�=��(>�(>�>���/�/��
�
�>���(�(�*��
�(�(�*��
�:�:�<�4�8�#3��
�4�:�:�<��
 �D�$A�$A�$�$G���
�
�f�%�U*
&�\	�
�
�f�����>��?��F����6�6�u�=���
��	$�C��S�.�.��?�D����d�#�	$�

���5�1�9�o��!�9�'�'�)�V�A�q�D�\�-D�-D�-F��1�q�5�!�/�/��q�	�0G�0G�H��!�a�%�=�+�+�-����1E�1E�1G��1�
�+�+�F�1�q�5�M�,G�,G�H��A��A��5�1�9�o��e�a�i� �+�+�-����1E�1E�1G��q�M�'�'��u�q�y�(9�(G�(G�H��a�y�#�#�%���q��)9�)D�)D�)F��u�q�y�!�/�/��q�	�0G�0G�H�
�#�c�&�k�1�2�
�d�i�i�)�!'�)�)�	*��(�(��4�C������;�;�,��I��5�L� �
)��� � ����.��,�,�)�B��$�$�b�"�,�,�%7�8� �$�$�R�(�)�
)�!/���2�I�|�1;�1F�1F�1;�D�L�L�1I�15���"@�'8�u�"&�+�+�(,�(9�(9�$(�
*�"�"B�\�"B�B�O�/8�K�t�q�!���0�Q�/�5I���F�K�L�K�$E� ��5�|�*�1;�1F�1F�1;�D�L�L�1I�15���"@�';�%�"&�+�+�(,�(9�(9�$(�
*�!�	1�F��,�,�(�(��)9�)9�:�C��,�,�3�3�5�
1�� �+�+���T�\�\�3�3�3��(�(��0�
1�	1�	�o��
�
�*K�F�*K� K�K�L�
�o��
�
�*K�
�*K� K�K�L��,	N�E���z�%�"<�"<�">�)3�D�A� ��~� �{�{�%�/�/�A� �D�
�D�� � �">�$)�O�O�U�C�
�O�$'�
�O�$5�"5�6�
�o�j�(I�����(I�I�J� ��)C�)C�)E�"�M�M�*�5�E��6����H�I� �.�.�u���?����(:�U�_�_�(L�M��%�%�e�,�!��)C�)C�)E���/�/�5�#�e�o�o�2F��/�/�+�,�

�T�E�\�"�
���(�"4�"4�4��0�0��4�;L�;L�M�Y,	N�\�;�;�,��I��5�L� �
)��� � ����.��,�,�)�B��$�$�b�"�,�,�%7�8� �$�$�R�(�)�
)�!/���3�Y��1;�1F�1F�1;�D�L�L�1I�15���"@�'8�u�"&�+�+�(,�(9�(9�$(�
*�"�"B�\�"B�B�O�/8�K�t�q�!���0�Q�/�5I���F�K�L�K�$E� ��6��*�1;�1F�1F�1;�D�L�L�1I�15���"@�';�%�"&�+�+�(,�(9�(9�$(�
*�3'��UK��VD��)J��VKs�h�:%h�#h�hc�T�|j}td�|j}|j�ry|j	�}|j
j
�D]'}|js�tjd|z��)|jj�D]^\}}|j|||d|�|j
j
�D]'}|js�tjd|z��)�`|j
j
�D]'}|js�tjd|z��)|jj�D]+\}}|j�s�|j|||d|��-|j
j
�D]'}|js�tjd|z��)|jj�D]\}}|j|||dd��|j
j
�D]'}|js�tj d|z��)|jj�D]+\}}|j�s�|j|||dd��-|j#|�y)a�Generate the intrasite KCC connections

        As per MS-ADTS 6.2.2.2.

        If self.readonly is False, the connections are added to self.samdb.

        After this call, all DCs in each site with more than 3 DCs
        should be connected in a bidirectional ring. If a site has 2
        DCs, they will bidirectionally connected. Sites with many DCs
        may have arbitrary extra connections.

        :return: None
        zintrasite(): enterNr�FT)rBr rD�is_intrasite_topology_disabled�is_detect_stale_disabledr�ryr�r"�
DEBUG_CYANr4�itemsrr�ri�	is_configrCr�)rKr�r�r�r��partdnr�s       r+�	intrasitez
KCC.intrasite7	s��������%�&������0�0�2��"�;�;�=�=���*�*�1�1�3�	?�G��"�"�� � �!3�g�!=�>�	?�
!�O�O�1�1�3�	C�L�F�D��*�*�6�5�$��+7�
9� �.�.�5�5�7�
C���&�&��$�$�%7�'�%A�B�
C�	C��*�*�1�1�3�	A�G��"�"��"�"�#5��#?�@�	A�
!�O�O�1�1�3�	=�L�F�D��~�~���.�.�v�u�d�D�/;�=�	=��*�*�1�1�3�	?�G��"�"�� � �!3�g�!=�>�	?�
!�O�O�1�1�3�	2�L�F�D��*�*�6�5�$��+0�
2�	2��*�*�1�1�3�	>�G��"�"���� 2�W� <�=�	>�!�O�O�1�1�3�	6�L�F�D��~�~���.�.�v�u�d�D�/4�6�	6�
	
���U�#r-c��|j�|j�|j�|j�|j	�|j�g}|jj�D]T}|j|jj�D�cgc]}|jjddd���!c}��V|Scc}w)aCompile a comprehensive list of DSA DNs

        These are all the DSAs on all the sites that KCC would be
        dealing with.

        This method is not idempotent and may not work correctly in
        sequence with KCC.run().

        :return: a list of DSA DN strings.
        zCN=NTDS Settings,r�r&)r�r�r�r�rfrkr5ry�extendrxr��replace)rK�dsasr{r�s    r+�	list_dsasz
KCC.list_dsas�	s���	
������������� � �"���� ����!����O�O�*�*�,�	>�D��K�K�$(�N�N�$9�$9�$;�=� ����.�.�/B�B��J�=�
>�	>����=s�'$C
c���|s|j�	t|t�||��|_yy#tj$r%}|j
\}}t
d|�d|����d}~wwxYw)aSLoad the database using an url, loadparm, and credentials

        If force is False, the samdb won't be reloaded if it already
        exists.

        :param dburl: a database url.
        :param lp: a loadparm object.
        :param creds: a Credentials object.
        :param force: a boolean indicating whether to overwrite.

        N)�url�session_info�credentials�lpzUnable to open sam database z : )rEr
r	rrXrYr)rK�dburlr�creds�force�e1�numrcs        r+�
load_samdbzKCC.load_samdb�	sm���D�J�J�&�
-�"�u�0>�0@�/4��=��
�'��
�<�<�
-��W�W�
��c�� %�s� ,�-�-��
-�s�.�A&� A!�!A&c
�z�|xr|j}|s
|j�yg}g}g}g}|jj�D]�}|j	|j
�|j
�r|j	d�n|j	d�|jj�D]\}	|	j�r|j	d�n|j	d�|j	|	j|j
f��^��t||||j|t||jd||��y)z�Helper function to plot and verify NTDSConnections

        :param basename: an identifying string to use in filenames and logs.
        :param verify_properties: properties to verify (default empty)
        Nz#cc0000z#0000cc�red�blueT)	rMrHrIr"rIrJrG�edge_colors�
vertex_colors)
rIrJr8ryr�r�r�r�r�r�rrAr)
rK�basenamerSrIrQr��edge_colours�vertex_coloursr�r�s
          r+�plot_all_connectionszKCC.plot_all_connections�	s"��#�2�t�{�{���$�+�+�3���	��������$�$�+�+�-�	B�C�����
�
�.��y�y�{��%�%�i�0��%�%�i�0��(�(�/�/�1�
B���'�'�)� �'�'��.� �'�'��/�� � �#�.�.�#�-�-�!@�A�
B�
	B�	�x��\�!�.�.�"3�5�$�4�3D�3D� $�,�%3�	5r-c�z��"��j�#td|����j|||d��|r�jjd|z�	�j	��j��j
��j��j��j��js
�j���i}�jj�D]2�"|jd��"jj!�D���4�j#d�g}	�j$j'�\}
}|
j!�D]:\}}
t)d|
z�|	j+�j$j,|f��<t/d	|	d
�j0dt(�j�j��g}	�jj�D]��"�"jj�D]�}|j'�\}
}|
j!�D][\}}|j2D]G}t)d
|z�t5|j6�}||}|	j+|j,|f��I�]����t/d|	d
�j0dt(�j�j��g}	g}�j8j�D]�}ddlm}|j>jAd�}d||�jC�ddz}tEjF|jHd�D]/\}}|	j+|d|df�|j+|��1��d}t/d|	d�j0|t(�j�j|��	|rk�jJjj�D]3}tM�fd�|jNj!�D��|_'�5�j#d�|r��jj�D]S�"�"jj�D]4}tM��"fd�|jNj!�D��|_'�6�U�j#d�|rd�}nd}�jQ|��jS��jU|�}�jW|��jY��j[��j]��js
�j���j#dd�t_j`dtc�z�g}	g}�j$j,}�j$j'�\}
}|j!�D]k\}} | j2D]W}t5|j6�}!|	j+|||!f�|j+dt5| jd�ddz��Y�mt/d |	d
�j0dt(�j�j|��	g}	�jj�D]��"�"jj�D]r}|j'�\}
}|j�D]J} | j2D]9}t5|j6�}||}|	j+|j,|f��;�L�t��t/d!|	d
�j0dt(�j�j��y#�xYw)"a�Perform a KCC run, possibly updating repsFrom topology

        :param dburl: url of the database to work with.
        :param lp: a loadparm object.
        :param creds: a Credentials object.
        :param forced_local_dsa: pretend to be on the DSA with this dn_str
        :param forget_local_links: calculate as if no connections existed
               (boolean, default False)
        :param forget_intersite_links: calculate with only intrasite connection
               (boolean, default False)
        :param attempt_live_connections: attempt to connect to remote DSAs to
               determine link availability (boolean, default False)
        :return: 1 on error, 0 otherwise
        Nz"samdb is None; let's load it from F)rzCN=NTDS Settings,%sc3�PK�|]\}}t|j�|f��� y�wrorp)rrrdr�s   r+rtzKCC.run.<locals>.<genexpr>�	s,����)D�-7�U�C�+.�c�l�l�*;�U�)C�)D�s�$&�dsa_initialzc_rep %s�dsa_repsFrom_initialTr/rFzrep %s�dsa_repsFrom_initial_allr)�md5r��#r�r�r&r��dsa_sitelink_initial)rGrHrIr"rIrJrc3��K�|]=\}}|j�s"|j�jjvr||f���?y�wro)r�r�rDrx)rr�kr�rKs   �r+rtzKCC.run.<locals>.<genexpr>2
sH�����-G���1�01�0B�0B�0D�./�l�l�.2�l�l�.D�.D�/E�/0��V�-G�s�AA�dsa_forgotten_localc3�h�K�|])\}}��jur|j�r||f���+y�wro)rDr�)rrr,r�rKr{s   ��r+rtzKCC.run.<locals>.<genexpr><
s:�����1G�D�A�q�48�D�L�L�4H�12�1C�1C�1E�34�Q��1G�s�/2�dsa_forgotten_allc��	tj||j|j�y#tj$rYywxYw)NFT)r�drsuapi_connectrr�drsException)rK�dnsnames  r+r�zKCC.run.<locals>.pingF
s@��%�!�1�1�'�4�7�7�D�J�J�O� ��%�1�1�%�$�%�s�+.�A�A�	dsa_finalzthere are %d dsa guids�dsa_repsFrom_final�dsa_repsFrom_final_all)3rEr r�set_ntds_settings_dnr�r�r�r�rfrkrIrJr5ryrwrxrr"rBr�rr�r�rrAr�rZr�r7�hashlibr(rd�encode�	hexdigestr�rL�	site_listrDrsr�r�r	r�rrAr�r�r"rVr��nc_guid)#rKrrr�forced_local_dsa�forget_local_links�forget_intersite_links�attempt_live_connections�
guid_to_dnstrrQ�current_reps�needed_repsrdr<r�rzrlr�r(�dsa_dn�dot_colours�linkr(�tmp_str�colourr�r�rIr�rr�my_dnstrr�guid_strr{s#`                                 @r+�runzKCC.run�	s����"�:�:���u�F�G��O�O�E�2�u�E�O�:���J�J�+�+�,A�,<�-=�
>�]	������������!��$�$�&��"�"�$��#�#�%��{�{�d�/�/�;� "�
� �O�O�2�2�4�D�D�!�(�(�)D�,0�N�N�,@�,@�,B�)D�D�D�
�)�)�-�8��	�,0�K�K�,F�,F�,H�)��k�$0�$6�$6�$8�E�L�E�5��*�u�,�-��$�$�d�k�k�&;�&;�U�%C�D�E��5�y�(,�D�4E�4E�*,�E�$�+�+�,0�,=�,=�?�
�	� �O�O�2�2�4�J�D�#�~�~�4�4�6�J��47�4F�4F�4H�1��k�+7�+=�+=�+?�J�K�F�C�-0�-=�-=�J�	� %�h��n� 5�+.�y�/L�/L�+M��)6�x�)@�� )� 0� 0�#�-�-��1H� I�	J�J�J�J��9�9�(,�D�4E�4E�*,�E�$�+�+�,0�,=�,=�?�
�	� �� �/�/�6�6�8�3�D�+�"�j�j�/�/��7�G� �3�w�<�#9�#9�#;�B�Q�#?�?�F� )� 6� 6�t�~�~�q� I�3���1�!�(�(�!�A�$��!���6�#�*�*�6�2�3�	3�,�
��5�y�(-�%)�%6�%6�:�%*�4�;�;�,0�,=�,=�+6�8�"��<�<�1�1�8�8�:�G�C�(,�-G�-0�->�->�-D�-D�-F�-G�)G�C�%�G��)�)�*?�@�%� �O�O�2�2�4�G�D�#�~�~�4�4�6�G��,0�1G�14�1B�1B�1H�1H�1J�1G�-G��)�G�G��)�)�*=�>�'� ���

�1�1�$�7�
�N�N��!�N�N�4�0�M�
�)�)�-�8�
�#�#�%�
�9�9�;�
�'�'�)��{�{�d�/�/�;��)�)�+�*8�:��#�#�$<�$'�
�$6�%7�8��	� ���;�;�0�0��,0�K�K�,F�,F�,H�)��k�$/�$5�$5�$7�I�L�E�5�%*�%7�%7�I�	�#&�y�'D�'D�#E��!�(�(�(�M�(�4K�)L�M�#�*�*�3��U�]�]�1C�B�Q�1G�+G�H�I�I��3�Y��%)�%6�%6�*,�E�$�+�+�,0�,=�,=�+6�	8��	� �O�O�2�2�4�J�D�#�~�~�4�4�6�J��47�4F�4F�4H�1��k�%0�%7�%7�%9�J�E�-2�-?�-?�J�	�+.�y�/L�/L�+M��)6�x�)@�� )� 0� 0�#�-�-��1H� I�J�J�J�J��7��(,�D�4E�4E�*,�E�$�+�+�,0�,=�,=�?���	��s
�[#\7�7\:c��	tj||||�|_y#tj$r}t	j
|�Yd}~yd}~wwxYw)aIImport relevant objects and attributes from an LDIF file.

        The point of this function is to allow a programmer/debugger to
        import an LDIF file with non-security relevant information that
        was previously extracted from a DC database.  The LDIF file is used
        to create a temporary abbreviated database.  The KCC algorithm can
        then run against this abbreviated database for debug or test
        verification that the topology generated is computationally the
        same between different OSes and algorithms.

        :param dburl: path to the temporary abbreviated db to create
        :param lp: a loadparm object.
        :param ldif_file: path to the ldif file to import
        :param forced_local_dsa: perform KCC from this DSA's point of view
        :return: zero on success, 1 on error
        Nr&r)r�
ldif_to_samdbrE�	LdifErrorr!�critical)rKrr�	ldif_filer=r�s      r+�import_ldifzKCC.import_ldif�
sO��"	�+�9�9�%��Y�:J�L�D�J�
��"�+�+�	��O�O�A����	�s� �A�A
�
Ac��	tj|j||||�y#tj$r}t	j
|�Yd}~yd}~wwxYw)a-Save KCC relevant details to an ldif file

        The point of this function is to allow a programmer/debugger to
        extract an LDIF file with non-security relevant information from
        a DC database.  The LDIF file can then be used to "import" via
        the import_ldif() function this file into a temporary abbreviated
        database.  The KCC algorithm can then run against this abbreviated
        database for debug or test verification that the topology generated
        is computationally the same between different OSes and algorithms.

        :param dburl: LDAP database URL to extract info from
        :param lp: a loadparm object.
        :param cred: a Credentials object.
        :param ldif_file: output LDIF file name to create
        :return: zero on success, 1 on error
        Nr&r)r�samdb_to_ldif_filerErNr!rO)rKrrrrPr�s      r+�export_ldifzKCC.export_ldif�
sP��"	��1�1�$�*�*�e�R��2;�
=�
��"�+�+�	��O�O�A����	�s�#&�A�A�A)FFFNro)T)F)r/)NFFF),�__name__�
__module__�__qualname__�__doc__rLrfrkrur�r�r�r�r�r�r�r�r�r�r�r�rr$r*rArDrr[rUr�r�r�r�r�r�r�r�rr	rrr"rKrQrTr/r-r+r2r2Ns���FK�"�()�T!G�F2�<%�.	:�$�&8F�t,�<2K�h�B
�8�$
-�2-�h74�r/�"&�$M;�^%�Nz0�~K�2&�P�<W�r12�fz*�x0�dz+�x8�t7�v">�H+�ZD*�LN$�`�0-�,!5�F6:�=B�%*�x�t�2r-r2)4rgr��	functoolsrr��sambarrrrr�
samba.authr	�samba.samdbr
�samba.dcerpcrr�samba.kcc.kcc_utilsr
rrrrrrrrrr�samba.kcc.graphr�	samba.ndrr�samba.kcc.graph_utilsr�	samba.kccrrrr�samba.kcc.debugrr r!r"�samba.commonr#r,r0�objectr2r/r-r+�<module>rfsn��,�� ��*�&�&�%��&�D�D�H�H�E�E�9��0�(�@�"�3�3���A�"�t)�&�t)r-

Zerion Mini Shell 1.0