[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Oct 29 07:12:04 UTC 2015


The branch, master has been updated
       via  4346fe6 KCC: allow --test-all-reps-from to work with --import-ldif
       via  8bdfb25 KCC: samba_kcc --tmpdb X won't run if X already exists
       via  e29fba6 KCC: with --import-ldif, don't default to standard DB url
       via  46ac3a5 KCC: kcc.import_ldif doesn't need creds
       via  6f93ffa KCC: remove NTDSConnection API methods that are never used
       via  b93205e KCC: whitespace for pep8
       via  1d5bb59 KCC: fix pep8 line length in load_ip_transport()
       via  ab63f1a KCC: Correct capitalisation of KCCError
       via  e9f0799 KCC: raise KCCError, not Exception, in multiple places
       via  2638419 KCC: NTDSConnection.load_connection() requires objectGUID
       via  8f59362 KCC: remove debug print statements from intrasite and intersite
       via  8fe9992 KCC: load samdb before calling kcc.run()
       via  47b3334 KCC: load the object GUID with --import-ldif
       via  30330b4 KCC: avoid logging alarming things about exected events
       via  ad009be KCC: shift --test-all-reps-from call to after kcc loading
       via  a9ddca0 KCC: Simplify RNG seeding logic, dropping the default value
       via  e442726 KCC: more debug info when --import-ldif goes badly
       via  acd7728 KCC: default to not loading new samdb when we already have one
       via  76f195a KCC: fix typo in error path
       via  6f78ad2 KCC: better explain our confusion in colour_vertices comment
       via  310aa2f KCC: clarify debugging messages in bridgehead finding code
       via  5f60c4b KCC: keep track of IP transport for dsa.new_connection()
       via  059e283 KCC: set system flags for new intrasite connections
       via  704fd83 KCC: correctly use dsa.new_connection() system_flags argument
       via  4bf95b6 KCC: Use detect_failed in create_connections
       via  0f8f99f KCC: remove useless comments and simplify get_dsa_for_implied_replica()
       via  24ae662 KCC: stop --forget-intersite-links forgetting local links
       via  eec0d11 KCC: simplify get_dsa_for_implied_replica(), using IP invariant
       via  5bbcbe3 KCC: Share commit wrapper between forget_ntdsconn and intrasite
       via  03e3522 KCC: pull apart remove_unneeded_ntdsconn(), fixing intersite
       via  472735f KCC: shift common is_generated() check out of branches
      from  6e3cb6b s4:torture: fix a comment typo.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4346fe6a0259e326bd5254a9d192f0807b27331e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: allow --test-all-reps-from to work with --import-ldif
    
    The ldif files lack information that a normal database has, which means
    the ldif import function has to use some trickery to set the local DSA.
    Once the local DSA is thus set, the fake database is a bit useless from
    the point of view of other DSAs. We get around this by re-importing it
    each time.
    
    This is doing something slightly different than the normal samdb
    --test-all-reps-from, in that the changes are not preserved between each
    DSA's run. With the samdb database (unless using --readonly), the later
    DSA's will see changes the early ones made. The ordering is arbitrary.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Oct 29 08:11:54 CET 2015 on sn-devel-104

commit 8bdfb256d6c4fdeaaa118fc6da841daebc1c377d
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: samba_kcc --tmpdb X won't run if X already exists
    
    Part of an ongoing safety campaign, making it harder to overwrite
    your valuable things while keeping it easy enough to test crazy schemes.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e29fba640b7d543f1e7177aa9357c82f590b6b07
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: with --import-ldif, don't default to standard DB url
    
    Before samba_kcc would always assume `-H /usr/local/whatever`, and this
    interacted badly with the likes of `--test-all-reps-from` and
    `--forget-intersite-links`.  When I say badly, I mean it crashed because
    the file is absent on my dev machine.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 46ac3a5308dfc5d03173bbae03734ba327f0e570
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: kcc.import_ldif doesn't need creds
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6f93ffaf0c446cd72478317636c0dcd7e0f4f4b8
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: remove NTDSConnection API methods that are never used
    
    These are not used, and using them would not be considered Pythonic. The
    flags they alter are always changed directly.
    
    The similar set_modified() method IS used.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b93205ebe4cb54175642ee60e18354f7bfb4c0fd
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: whitespace for pep8
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1d5bb5996e7df31aac746375a5cc24a91ee52d7e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Jun 23 16:38:29 2015 +1200

    KCC: fix pep8 line length in load_ip_transport()
    
    You are right to sigh about this one.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ab63f1a9839c286cf7f345cc62207d9b95a5af62
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: Correct capitalisation of KCCError
    
    previously we had "raise KccError", which of course would raise a
    NameError.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e9f0799a18955e9fec1478a6019a333f588b26cc
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: raise KCCError, not Exception, in multiple places
    
    "except Exception" lines will still catch them, but more fine-grained
    control is possible.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 26384192d56d765a8ea4667fac7c9b7ad2e3d415
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: NTDSConnection.load_connection() requires objectGUID
    
    If there is no GUID, that is an error, so we raise an exception instead
    of stepping around it.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8f5936261f221f6a83fc294e308160d9fb9562e3
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: remove debug print statements from intrasite and intersite
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8fe9992cffed82e9e26ebe8185f372c8a1dfb3a9
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: load samdb before calling kcc.run()
    
    kcc.run() is a mega-function that does nearly everything, including
    loading the database. The --list-valid-dsas and --test-all-reps-from
    tasks also want to load the database, but not do all that other run()
    stuff, so it makes sense to pull it out. When the samdb has not been
    loaded, run() will still load it -- this avoids having to change all
    the tests.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 47b3334f48f21118ba1f61e841eb95920f384ee4
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: load the object GUID with --import-ldif
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 30330b4df8e1542a2c9fd2ca256cb58029b6cbf4
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Mon Jun 22 16:38:29 2015 +1200

    KCC: avoid logging alarming things about exected events
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ad009be3297ec9343fd07ea86a197dc11ab8890f
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 16:38:29 2015 +1200

    KCC: shift --test-all-reps-from call to after kcc loading
    
    This is in an effort to allow --test-all-reps-from to work with
    --import-ldif (though so far it doesn't for other reasons). Rather than
    replicate all the ldif loading logic within test_all_reps_from, we just
    wait delay the test_all_reps_from() call.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a9ddca042c51de5c95327f41e3a31c178f5ab85b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 16:38:29 2015 +1200

    KCC: Simplify RNG seeding logic, dropping the default value
    
    There is no particular justification for the previous default, other
    than being deterministic makes testing more reliable. The algorithms
    using randomness do not assume determinism.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e442726c3d59bf861058ac81735653d9f91610a2
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 16:38:29 2015 +1200

    KCC: more debug info when --import-ldif goes badly
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit acd77283ccf3253bb7d5d048465bbf8e77a89982
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 16:38:29 2015 +1200

    KCC: default to not loading new samdb when we already have one
    
    This should make things simpler in the --import-ldif case.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 76f195a2792d0c4cd86a337881d1ce01194113af
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 16:38:29 2015 +1200

    KCC: fix typo in error path
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6f78ad24506928f48f5a26bf87f3d4de460f0cde
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 10 16:38:29 2015 +1200

    KCC: better explain our confusion in colour_vertices comment
    
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 310aa2f3408800498876768091f3533e3332b75b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 10 16:38:29 2015 +1200

    KCC: clarify debugging messages in bridgehead finding code
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5f60c4bf33cd94c84cad0ba5768474435a515af0
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 10 16:38:29 2015 +1200

    KCC: keep track of IP transport for dsa.new_connection()
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 059e2838c8a61ffbb0865e665694c02bb531758b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 10 16:38:29 2015 +1200

    KCC: set system flags for new intrasite connections
    
    These flags are mandatory for intrasite connections.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 704fd83bcf5bba3bf5e67ea8060aff148aacea32
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 10 16:38:29 2015 +1200

    KCC: correctly use dsa.new_connection() system_flags argument
    
    The dsa.system_flags attribute is important and gets saved in the
    database, but was never getting altered because we were setting dsa.flags
    instead.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4bf95b6b32dfc8ecc0aac92971e173b826e2d4ac
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Jun 26 16:38:29 2015 +1200

    KCC: Use detect_failed in create_connections
    
    Without this, dead DCs were treated as live, and could be used in the
    tree. If they're in the tree they can split the network.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0f8f99f6af2785d6774ca9436b6eef2078a246df
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 25 16:38:29 2015 +1200

    KCC: remove useless comments and simplify get_dsa_for_implied_replica()
    
    These comments are a close reflection (or possibly copy/paste) of the
    spec, but our code here no longer resembles the spec. We end up just
    glazing over when we see comments and losing track of the flow of code.
    
    If you want the spec just look at the spec.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 24ae662eaee03a0e5d1046acf6882bc6842f518a
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 25 16:38:29 2015 +1200

    KCC: stop --forget-intersite-links forgetting local links
    
    It will still forget intrasite links on other sites, but that in theory
    should not matter.
    
    It will still break your network, and is only useful for debugging.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit eec0d119ac755b72f8e881728608a849ad12b66b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 25 16:38:29 2015 +1200

    KCC: simplify get_dsa_for_implied_replica(), using IP invariant
    
    We only do IP transports. Therfore the long list of alternatives...
    
                       (not n_rep.is_domain() or
                        n_rep.is_partial() or
                        cn_conn.transport_dnstr is None or
                        cn_conn.transport_dnstr.find("CN=IP") == 0)
    
    that ends with the equivalant of "is this IP?" always evaluates to True.
    
    If we leave it there it will confuse people for ever.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5bbcbe380b8b5cb7a9f479e585f46040f2d99ad5
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 25 16:38:29 2015 +1200

    KCC: Share commit wrapper between forget_ntdsconn and intrasite
    
    The wrapper is only to create DEBUG output in read-only mode --
    normally it amounts to `dsa.commit_connections(self.samdb)`.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 03e352268a80a4671b50855a977a655b095ddf18
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Jun 25 16:38:29 2015 +1200

    KCC: pull apart remove_unneeded_ntdsconn(), fixing intersite
    
    The confusing big mess was hiding bugs. Firstly, intersite links on
    non-intersite-topology-generators were not getting looked at. Secondly,
    the logic around superseding intersite links was missing.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 472735f26c3bc67d4a04d08038d1f63c1b275986
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Jun 17 15:11:20 2015 +1200

    KCC: shift common is_generated() check out of branches
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/kcc/__init__.py                 | 372 ++++++++++++---------------
 python/samba/kcc/kcc_utils.py                | 105 ++++----
 python/samba/kcc/ldif_import_export.py       |   2 +-
 python/samba/tests/kcc/ldif_import_export.py |   6 +-
 source4/scripting/bin/samba_kcc              |  74 ++++--
 5 files changed, 274 insertions(+), 285 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/kcc/__init__.py b/python/samba/kcc/__init__.py
index 46a25ce..c3e92b7 100644
--- a/python/samba/kcc/__init__.py
+++ b/python/samba/kcc/__init__.py
@@ -165,11 +165,12 @@ class KCC(object):
             if transport.name == 'IP':
                 self.ip_transport = transport
             elif transport.name == 'SMTP':
-                logger.info("Samba KCC is ignoring the obsolete SMTP transport.")
+                logger.debug("Samba KCC is ignoring the obsolete "
+                             "SMTP transport.")
 
             else:
-                logger.warning("Samba KCC does not support the transport called %r."
-                               % (transport.name,))
+                logger.warning("Samba KCC does not support the transport "
+                               "called %r." % (transport.name,))
 
         if self.ip_transport is None:
             raise KCCError("there doesn't seem to be an IP transport")
@@ -261,14 +262,15 @@ class KCC(object):
         :return: None
         :raise: KCCError if DSA can't be found
         """
-        dn = ldb.Dn(self.samdb, "<GUID=%s>" % self.samdb.get_ntds_GUID())
+        dn_query = "<GUID=%s>" % self.samdb.get_ntds_GUID()
+        dn = ldb.Dn(self.samdb, dn_query)
         try:
             res = self.samdb.search(base=dn, scope=ldb.SCOPE_BASE,
                                     attrs=["objectGUID"])
         except ldb.LdbError, (enum, estr):
-            logger.warning("Search for %s failed: %s.  This typically happens"
-                           " in --importldif mode due to lack of module"
-                           " support.", dn, estr)
+            DEBUG_FN("Search for dn '%s' [from %s] failed: %s. "
+                     "This typically happens in --importldif mode due "
+                     "to lack of module support." % (dn, dn_query, estr))
             try:
                 # We work around the failure above by looking at the
                 # dsServiceName that was put in the fake rootdse by
@@ -305,7 +307,7 @@ class KCC(object):
                                     " it must be RODC.\n"
                                     "Let's add it, because my_dsa is special!"
                                     "\n(likewise for self.dsa_by_guid)" %
-                                    self.my_dsas_dnstr)
+                                    self.my_dsa_dnstr)
 
             self.dsa_by_dnstr[self.my_dsa_dnstr] = self.my_dsa
             self.dsa_by_guid[str(self.my_dsa.dsa_guid)] = self.my_dsa
@@ -432,19 +434,17 @@ class KCC(object):
         # that became active during this run.
         pass
 
-    def remove_unneeded_ntdsconn(self, all_connected):
-        """Remove unneeded NTDS Connections once topology is calculated
+    def _ensure_connections_are_loaded(self, connections):
+        """Load or fake-load NTDSConnections lacking GUIDs
 
-        Based on MS-ADTS 6.2.2.4 Removing Unnecessary Connections
+        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 all_connected: indicates whether all sites are connected
+        :param connections: an iterable of NTDSConnection objects.
         :return: None
         """
-        mydsa = self.my_dsa
-
-        # New connections won't have GUIDs which are needed for
-        # sorting. Add them.
-        for cn_conn in mydsa.connect_table.values():
+        for cn_conn in connections:
             if cn_conn.guid is None:
                 if self.readonly:
                     cn_conn.guid = misc.GUID(str(uuid.uuid4()))
@@ -452,135 +452,139 @@ class KCC(object):
                 else:
                     cn_conn.load_connection(self.samdb)
 
-        for cn_conn in mydsa.connect_table.values():
+    def _mark_broken_ntdsconn(self):
+        """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
+        """
+        for cn_conn in self.my_dsa.connect_table.values():
             s_dnstr = cn_conn.get_from_dnstr()
             if s_dnstr is None:
+                DEBUG_FN("%s has phantom connection %s" % (self.my_dsa,
+                                                           cn_conn))
                 cn_conn.to_be_deleted = True
-                continue
 
-            #XXX should an RODC be regarded as same site
-            same_site = s_dnstr in self.my_site.dsa_table
-
-            # Given an nTDSConnection object cn, if the DC with the
-            # nTDSDSA object dc that is the parent object of cn and
-            # the DC with the nTDSDA object referenced by cn!fromServer
-            # are in the same site, the KCC on dc deletes cn if all of
-            # the following are true:
-            #
-            # Bit NTDSCONN_OPT_IS_GENERATED is clear in cn!options.
-            #
-            # No site settings object s exists for the local DC's site, or
-            # bit NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED is clear in
-            # s!options.
-            #
-            # Another nTDSConnection object cn2 exists such that cn and
-            # cn2 have the same parent object, cn!fromServer = cn2!fromServer,
-            # and either
-            #
-            #     cn!whenCreated < cn2!whenCreated
-            #
-            #     cn!whenCreated = cn2!whenCreated and
-            #     cn!objectGUID < cn2!objectGUID
-            #
-            # Bit NTDSCONN_OPT_RODC_TOPOLOGY is clear in cn!options
-            if same_site:
-                if not cn_conn.is_generated():
-                    continue
-
-                if self.my_site.is_cleanup_ntdsconn_disabled():
-                    continue
-
-                # Loop thru connections looking for a duplicate that
-                # fulfills the previous criteria
-                lesser = False
-                packed_guid = ndr_pack(cn_conn.guid)
-                for cn2_conn in mydsa.connect_table.values():
-                    if cn2_conn is cn_conn:
-                        continue
+    def _mark_unneeded_local_ntdsconn(self):
+        """Find unneeded intrasite NTDS Connections for removal
 
-                    s2_dnstr = cn2_conn.get_from_dnstr()
+        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.
 
-                    # If the NTDS Connections has a different
-                    # fromServer field then no match
-                    if s2_dnstr != s_dnstr:
-                        continue
+        :return: None
+        """
+        # XXX should an RODC be regarded as same site? It isn't part
+        # of the intrasite ring.
 
-                    lesser = (cn_conn.whenCreated < cn2_conn.whenCreated or
-                              (cn_conn.whenCreated == cn2_conn.whenCreated and
-                               packed_guid < ndr_pack(cn2_conn.guid)))
+        if self.my_site.is_cleanup_ntdsconn_disabled():
+            DEBUG_FN("not doing ntdsconn cleanup for site %s, "
+                     "because it is disabled" % self.my_site)
+            return
 
-                    if lesser:
-                        break
+        mydsa = self.my_dsa
 
-                if lesser and not cn_conn.is_rodc_topology():
-                    cn_conn.to_be_deleted = True
+        self._ensure_connections_are_loaded(mydsa.connect_table.values())
 
-            # Given an nTDSConnection object cn, if the DC with the nTDSDSA
-            # object dc that is the parent object of cn and the DC with
-            # the nTDSDSA object referenced by cn!fromServer are in
-            # different sites, a KCC acting as an ISTG in dc's site
-            # deletes cn if all of the following are true:
-            #
-            #     Bit NTDSCONN_OPT_IS_GENERATED is clear in cn!options.
-            #
-            #     cn!fromServer references an nTDSDSA object for a DC
-            #     in a site other than the local DC's site.
-            #
-            #     The keepConnections sequence returned by
-            #     CreateIntersiteConnections() does not contain
-            #     cn!objectGUID, or cn is "superseded by" (see below)
-            #     another nTDSConnection cn2 and keepConnections
-            #     contains cn2!objectGUID.
-            #
-            #     The return value of CreateIntersiteConnections()
-            #     was true.
-            #
-            #     Bit NTDSCONN_OPT_RODC_TOPOLOGY is clear in
-            #     cn!options
-            #
-            else:  # different site
+        local_connections = []
 
-                if not mydsa.is_istg():
-                    continue
+        for cn_conn in mydsa.connect_table.values():
+            s_dnstr = cn_conn.get_from_dnstr()
+            if s_dnstr in self.my_site.dsa_table:
+                removable = not (cn_conn.is_generated() or
+                                 cn_conn.is_rodc_topology())
+                packed_guid = ndr_pack(cn_conn.guid)
+                local_connections.append((cn_conn, s_dnstr,
+                                          packed_guid, removable))
+
+        for a, b in itertools.permutations(local_connections, 2):
+            cn_conn, s_dnstr, packed_guid, removable = a
+            cn_conn2, s_dnstr2, packed_guid2, removable2 = b
+            if (removable and
+                s_dnstr == s_dnstr2 and
+                cn_conn.whenCreated < cn_conn2.whenCreated or
+                (cn_conn.whenCreated == cn_conn2.whenCreated and
+                 packed_guid < packed_guid2)):
+                cn_conn.to_be_deleted = True
 
-                if not cn_conn.is_generated():
-                    continue
+    def _mark_unneeded_intersite_ntdsconn(self):
+        """find unneeded intersite NTDS Connections for removal
 
-                # TODO
-                # We are directly using this connection in intersite or
-                # we are using a connection which can supersede this one.
-                #
-                # MS-ADTS 6.2.2.4 - Removing Unnecessary Connections does not
-                # appear to be correct.
-                #
-                # 1. cn!fromServer and cn!parent appear inconsistent with
-                #    no cn2
-                # 2. The repsFrom do not imply each other
-                #
-                if cn_conn in self.kept_connections:  # and not_superceded:
-                    continue
+        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.
 
-                # This is the result of create_intersite_connections
-                if not all_connected:
-                    continue
+        :return: None
+        """
+        # Find the intersite connections
+        local_dsas = self.my_site.dsa_table
+        connections_and_dsas = []
+        for dsa in local_dsas.values():
+            for cn in dsa.connect_table.values():
+                s_dnstr = cn.get_from_dnstr()
+                if s_dnstr not in local_dsas:
+                    from_dsa = self.get_dsa(s_dnstr)
+                    connections_and_dsas.append((cn, dsa, from_dsa))
+
+        self._ensure_connections_are_loaded(x[0] for x in connections_and_dsas)
+        for cn, to_dsa, from_dsa in connections_and_dsas:
+            if not cn.is_generated() or cn.is_rodc_topology():
+                continue
 
-                if not cn_conn.is_rodc_topology():
-                    cn_conn.to_be_deleted = True
+            # If the connection is in the kept_connections list, we
+            # only remove it if an endpoint seems down.
+            if (cn in self.kept_connections and
+                not (self.is_bridgehead_failed(to_dsa, True) or
+                     self.is_bridgehead_failed(from_dsa, True))):
+                continue
 
-        if mydsa.is_ro() or self.readonly:
-            for connect in mydsa.connect_table.values():
+            # this one is broken and might be superseded by another.
+            # But which other? Let's just say another link to the same
+            # site can supersede.
+            from_dnstr = from_dsa.dsa_dnstr
+            for site in self.site_table.values():
+                if from_dnstr in site.rw_dsa_table:
+                    for cn2, to_dsa2, from_dsa2 in connections_and_dsas:
+                        if (cn is not cn2 and
+                            from_dsa2 in site.rw_dsa_table):
+                            cn.to_be_deleted = True
+
+    def _commit_changes(self, dsa):
+        if dsa.is_ro() or self.readonly:
+            for connect in dsa.connect_table.values():
                 if connect.to_be_deleted:
-                    DEBUG_FN("TO BE DELETED:\n%s" % connect)
+                    logger.info("TO BE DELETED:\n%s" % connect)
                 if connect.to_be_added:
-                    DEBUG_FN("TO BE ADDED:\n%s" % connect)
+                    logger.info("TO BE ADDED:\n%s" % connect)
+                if connect.to_be_modified:
+                    logger.info("TO BE MODIFIED:\n%s" % connect)
 
             # Peform deletion from our tables but perform
             # no database modification
-            mydsa.commit_connections(self.samdb, ro=True)
+            dsa.commit_connections(self.samdb, ro=True)
         else:
             # Commit any modified connections
-            mydsa.commit_connections(self.samdb)
+            dsa.commit_connections(self.samdb)
+
+    def remove_unneeded_ntdsconn(self, all_connected):
+        """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
+        """
+        self._mark_broken_ntdsconn()
+        self._mark_unneeded_local_ntdsconn()
+        # if we are not the istg, we're done!
+        # if we are the istg, but all_connected is False, we also do nothing.
+        if self.my_dsa.is_istg() and all_connected:
+            self._mark_unneeded_intersite_ntdsconn()
+
+        for dsa in self.my_site.dsa_table.values():
+            self._commit_changes(dsa)
 
     def modify_repsFrom(self, n_rep, t_repsFrom, s_rep, s_dsa, cn_conn):
         """Update an repsFrom object if required.
@@ -797,14 +801,12 @@ class KCC(object):
         :param cn_conn: NTDS Connection
         :return: source DSA or None
         """
-        #XXX different conditions for "implies" than MS-ADTS 6.2.2
+        # XXX different conditions for "implies" than MS-ADTS 6.2.2
+        # preamble.
 
-        # NTDS Connection must satisfy all the following criteria
-        # to imply a repsFrom tuple is needed:
-        #
-        #    cn!enabledConnection = true.
-        #    cn!options does not contain NTDSCONN_OPT_RODC_TOPOLOGY.
-        #    cn!fromServer references an nTDSDSA object.
+        # It boils down to: we want an enabled, non-FRS connections to
+        # a valid remote DSA with a non-RO replica corresponding to
+        # n_rep.
 
         if not cn_conn.is_enabled() or cn_conn.is_rodc_topology():
             return None
@@ -816,39 +818,11 @@ class KCC(object):
         if s_dsa is None:
             return None
 
-        # To imply a repsFrom tuple is needed, each of these
-        # must be True:
-        #
-        #     An NC replica of the NC "is present" on the DC to
-        #     which the nTDSDSA object referenced by cn!fromServer
-        #     corresponds.
-        #
-        #     An NC replica of the NC "should be present" on
-        #     the local DC
         s_rep = s_dsa.get_current_replica(n_rep.nc_dnstr)
 
-        if s_rep is None or not s_rep.is_present():
-            return None
-
-        # To imply a repsFrom tuple is needed, each of these
-        # must be True:
-        #
-        #     The NC replica on the DC referenced by cn!fromServer is
-        #     a writable replica or the NC replica that "should be
-        #     present" on the local DC is a partial replica.
-        #
-        #     The NC is not a domain NC, the NC replica that
-        #     "should be present" on the local DC is a partial
-        #     replica, cn!transportType has no value, or
-        #     cn!transportType has an RDN of CN=IP.
-        #
-        implied = (not s_rep.is_ro() or n_rep.is_partial()) and \
-                  (not n_rep.is_domain() or
-                   n_rep.is_partial() or
-                   cn_conn.transport_dnstr is None or
-                   cn_conn.transport_dnstr.find("CN=IP") == 0)
-
-        if implied:
+        if (s_rep is not None and
+            s_rep.is_present() and
+            (not s_rep.is_ro() or n_rep.is_partial())):
             return s_dsa
         return None
 
@@ -1106,14 +1080,14 @@ class KCC(object):
 
         bhs = self.get_all_bridgeheads(site, part, transport,
                                        partial_ok, detect_failed)
-        if len(bhs) == 0:
-            debug.DEBUG_MAGENTA("get_bridgehead:\n\tsitedn=%s\n\tbhdn=None" %
+        if not bhs:
+            debug.DEBUG_MAGENTA("get_bridgehead FAILED:\nsitedn = %s" %
                                 site.site_dnstr)
             return None
-        else:
-            debug.DEBUG_GREEN("get_bridgehead:\n\tsitedn=%s\n\tbhdn=%s" %
-                              (site.site_dnstr, bhs[0].dsa_dnstr))
-            return bhs[0]
+
+        debug.DEBUG_GREEN("get_bridgehead:\n\tsitedn = %s\n\tbhdn = %s" %
+                          (site.site_dnstr, bhs[0].dsa_dnstr))
+        return bhs[0]
 
     def get_all_bridgeheads(self, site, part, transport,
                             partial_ok, detect_failed):
@@ -1141,7 +1115,6 @@ class KCC(object):
                            "non-IP transport! %r"
                            % (transport.name,))
 
-        DEBUG_FN("get_all_bridgeheads")
         DEBUG_FN(site.rw_dsa_table)
         for dsa in site.rw_dsa_table.values():
 
@@ -1189,7 +1162,7 @@ class KCC(object):
                 DEBUG("bridgehead is failed")
                 continue
 
-            DEBUG_FN("get_all_bridgeheads: dsadn=%s" % dsa.dsa_dnstr)
+            DEBUG_FN("found a bridgehead: %s" % dsa.dsa_dnstr)
             bhs.append(dsa)
 
         # IF bit NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED is set in
@@ -1490,7 +1463,10 @@ class KCC(object):
             # cn!options = opt, cn!transportType is a reference to t,
             # cn!fromServer is a reference to rbh, and cn!schedule = sch
             DEBUG_FN("new connection, KCC dsa: %s" % self.my_dsa.dsa_dnstr)
-            cn = lbh.new_connection(opt, 0, transport,
+            system_flags = (dsdb.SYSTEM_FLAG_CONFIG_ALLOW_RENAME |
+                            dsdb.SYSTEM_FLAG_CONFIG_ALLOW_MOVE)
+
+            cn = lbh.new_connection(opt, system_flags, transport,
                                     rbh.dsa_dnstr, link_sched)
 
             # Display any added connection
@@ -1525,7 +1501,7 @@ class KCC(object):
         # here, but using vertex seems to make more sense. That is,
         # the docs want this:
         #
-        #bh = self.get_bridgehead(vertex.site, vertex.part, transport,
+        #bh = self.get_bridgehead(local_vertex.site, vertex.part, transport,
         #                         local_vertex.is_black(), detect_failed)
         #
         # TODO WHY?????
@@ -1596,7 +1572,7 @@ class KCC(object):
 
         for v in graph.vertices:
             v.color_vertex()
-            if self.add_transports(v, my_vertex, graph, False):
+            if self.add_transports(v, my_vertex, graph, detect_failed):
                 found_failed = True
 
         # No NC replicas for this NC in the site of the local DC,
@@ -2159,7 +2135,6 @@ class KCC(object):
                                   if not self.get_dsa(x).is_ro())
             rw_dot_edges = [(a, b) for a, b in dot_edges if
                             a in rw_dot_vertices and b in rw_dot_vertices]
-            print rw_dot_edges, rw_dot_vertices
             rw_verify_properties = ('connected',
                                     'directed_double_ring_or_small')
             verify_and_dot('intrasite_rw_pre_ntdscon', rw_dot_edges,
@@ -2230,7 +2205,7 @@ class KCC(object):
             # points to us that satisfies the KCC criteria
 
             if tnode.dsa_dnstr == dc_local.dsa_dnstr:
-                tnode.add_connections_from_edges(dc_local)
+                tnode.add_connections_from_edges(dc_local, self.ip_transport)
 
         if self.verify or do_dot_files:
             dot_edges = []
@@ -2255,7 +2230,6 @@ class KCC(object):
                                   if not self.get_dsa(x).is_ro())
             rw_dot_edges = [(a, b) for a, b in dot_edges if
                             a in rw_dot_vertices and b in rw_dot_vertices]
-            print rw_dot_edges, rw_dot_vertices
             rw_verify_properties = ('connected',
                                     'directed_double_ring_or_small')
             verify_and_dot('intrasite_rw_post_ntdscon', rw_dot_edges,
@@ -2346,20 +2320,7 @@ class KCC(object):
                 self.construct_intrasite_graph(mysite, mydsa, part, True,
                                                False)  # don't detect stale
 
-        if self.readonly:
-            # Display any to be added or modified repsFrom
-            for connect in mydsa.connect_table.values():
-                if connect.to_be_deleted:
-                    logger.info("TO BE DELETED:\n%s" % connect)
-                if connect.to_be_modified:
-                    logger.info("TO BE MODIFIED:\n%s" % connect)
-                if connect.to_be_added:
-                    debug.DEBUG_GREEN("TO BE ADDED:\n%s" % connect)
-
-            mydsa.commit_connections(self.samdb, ro=True)
-        else:
-            # Commit any newly created connections to the samdb
-            mydsa.commit_connections(self.samdb)
+        self._commit_changes(mydsa)
 
     def list_dsas(self):
         """Compile a comprehensive list of DSA DNs
@@ -2385,16 +2346,26 @@ class KCC(object):


-- 
Samba Shared Repository



More information about the samba-cvs mailing list