[SCM] Samba Shared Repository - branch master updated

Garming Sam garming at samba.org
Tue Jul 26 03:12:02 UTC 2016


The branch, master has been updated
       via  8dabd57 kcc: Clean up repsTo attribute for old DCs
       via  9427a24 kcc: Add a TODO for msDS[-RO]-Replica-Locations
       via  f95bbc7 kcc: Add corresponding methods for repsTo
      from  3cb659e WHATSNEW: CTDB updates

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


- Log -----------------------------------------------------------------
commit 8dabd57d1c2908a18c1b9eb70f54215653f73ee6
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon Jul 25 12:51:13 2016 +1200

    kcc: Clean up repsTo attribute for old DCs
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Garming Sam <garming at samba.org>
    Autobuild-Date(master): Tue Jul 26 05:11:57 CEST 2016 on sn-devel-144

commit 9427a2424ae4bb3250b35e3a38f3afda14a7bd0f
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Jul 22 16:33:12 2016 +1200

    kcc: Add a TODO for msDS[-RO]-Replica-Locations
    
    When you modify the replica locations to exclude a DSA, it should be respected.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f95bbc7933c71474b2b9796463e72bdde2442c77
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Jul 22 14:14:20 2016 +1200

    kcc: Add corresponding methods for repsTo
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 python/samba/kcc/__init__.py  | 71 +++++++++++++++++++++++++++++++
 python/samba/kcc/kcc_utils.py | 98 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+)


Changeset truncated at 500 lines:

diff --git a/python/samba/kcc/__init__.py b/python/samba/kcc/__init__.py
index 7b5b90d..9b29ef0 100644
--- a/python/samba/kcc/__init__.py
+++ b/python/samba/kcc/__init__.py
@@ -922,10 +922,13 @@ class KCC(object):
                  len(needed_rep_table), len(delete_reps)))
 
         if delete_reps:
+            # TODO Must delete repsFrom/repsTo for these replicas
             DEBUG('deleting these reps: %s' % delete_reps)
             for dnstr in delete_reps:
                 del current_rep_table[dnstr]
 
+        # HANDLE REPS-FROM
+        #
         # Now perform the scan of replicas we'll need
         # and compare any current repsFrom against the
         # connections
@@ -1038,6 +1041,74 @@ class KCC(object):
                 # Commit any modified repsFrom to the NC replica
                 n_rep.commit_repsFrom(self.samdb)
 
+        # HANDLE REPS-TO:
+        #
+        # Now perform the scan of replicas we'll need
+        # and compare any current repsTo against the
+        # connections
+
+        # RODC should never push to anybody (should we check this?)
+        if ro:
+            return
+
+        for n_rep in needed_rep_table.values():
+
+            # load any repsTo and fsmo roles as we'll
+            # need them during connection translation
+            n_rep.load_repsTo(self.samdb)
+
+            # Loop thru the existing repsTo tuples (if any)
+            # XXX This is a list and could contain duplicates
+            #     (multiple load_repsTo calls)
+            for t_repsTo in n_rep.rep_repsTo:
+
+                # for each tuple t in n!repsTo, let s be the nTDSDSA
+                # object such that s!objectGUID = t.uuidDsa
+                guidstr = str(t_repsTo.source_dsa_obj_guid)
+                s_dsa = self.get_dsa_by_guidstr(guidstr)
+
+                # Source dsa is gone from config (strange)
+                # so cleanup stale repsTo for unlisted DSA
+                if s_dsa is None:
+                    logger.warning("repsTo source DSA guid (%s) not found" %
+                                   guidstr)
+                    t_repsTo.to_be_deleted = True
+                    continue
+
+                # Find the connection that this repsTo would use. If
+                # there isn't a good one (i.e. non-RODC_TOPOLOGY,
+                # meaning non-FRS), we delete the repsTo.
+                s_dnstr = s_dsa.dsa_dnstr
+                if '\\0ADEL' in s_dnstr:
+                    logger.warning("repsTo source DSA guid (%s) appears deleted" %
+                                   guidstr)
+                    t_repsTo.to_be_deleted = True
+                    continue
+
+                connections = s_dsa.get_connection_by_from_dnstr(self.my_dsa_dnstr)
+                if len(connections) > 0:
+                    # Then this repsTo is tentatively valid
+                    continue
+                else:
+                    # There is no plausible connection for this repsTo
+                    t_repsTo.to_be_deleted = True
+
+            if self.readonly:
+                # Display any to be deleted or modified repsTo
+                text = n_rep.dumpstr_reps_to()
+                if text:
+                    logger.info("REMOVING REPS-TO:\n%s" % text)
+
+                # Peform deletion from our tables but perform
+                # no database modification
+                n_rep.commit_repsTo(self.samdb, ro=True)
+            else:
+                # Commit any modified repsTo to the NC replica
+                n_rep.commit_repsTo(self.samdb)
+
+        # TODO Remove any duplicate repsTo values. This should never happen in
+        # any normal situations.
+
     def merge_failed_links(self, ping=None):
         """Merge of kCCFailedLinks and kCCFailedLinks from bridgeheads.
 
diff --git a/python/samba/kcc/kcc_utils.py b/python/samba/kcc/kcc_utils.py
index e624519..190b93f 100644
--- a/python/samba/kcc/kcc_utils.py
+++ b/python/samba/kcc/kcc_utils.py
@@ -196,6 +196,9 @@ class NCReplica(NamingContext):
         # RepsFromTo tuples
         self.rep_repsFrom = []
 
+        # RepsFromTo tuples
+        self.rep_repsTo = []
+
         # The (is present) test is a combination of being
         # enumerated in (hasMasterNCs or msDS-hasFullReplicaNCs or
         # hasPartialReplicaNCs) as well as its replica flags found
@@ -220,6 +223,9 @@ class NCReplica(NamingContext):
         for rep in self.rep_repsFrom:
             text = text + "\n%s" % rep
 
+        for rep in self.rep_repsTo:
+            text = text + "\n%s" % rep
+
         return "%s\n%s" % (NamingContext.__str__(self), text)
 
     def set_instantiated_flags(self, flags=None):
@@ -427,6 +433,9 @@ class NCReplica(NamingContext):
     def dumpstr_to_be_modified(self):
         return '\n'.join(str(x) for x in self.rep_repsFrom if x.is_modified())
 
+    def dumpstr_reps_to(self):
+        return '\n'.join(str(x) for x in self.rep_repsTo if x.to_be_deleted)
+
     def load_fsmo_roles(self, samdb):
         """Given an NC replica which has been discovered thru the nTDSDSA
         database object, load the fSMORoleOwner attribute.
@@ -451,6 +460,95 @@ class NCReplica(NamingContext):
             return True
         return False
 
+    def load_repsTo(self, samdb):
+        """Given an NC replica which has been discovered thru the nTDSDSA
+        database object, load the repsTo attribute for the local replica.
+        held by my dsa.  The repsTo attribute is not replicated so this
+        attribute is relative only to the local DSA that the samdb exists on
+
+        This is responsible for push replication, not scheduled pull
+        replication. Not to be confused for repsFrom.
+        """
+        try:
+            res = samdb.search(base=self.nc_dnstr, scope=ldb.SCOPE_BASE,
+                               attrs=["repsTo"])
+
+        except ldb.LdbError, (enum, estr):
+            raise KCCError("Unable to find NC for (%s) - (%s)" %
+                           (self.nc_dnstr, estr))
+
+        msg = res[0]
+
+        # Possibly no repsTo if this is a singleton DC
+        if "repsTo" in msg:
+            for value in msg["repsTo"]:
+                rep = RepsFromTo(self.nc_dnstr,
+                                 ndr_unpack(drsblobs.repsFromToBlob, value))
+                self.rep_repsTo.append(rep)
+
+    def commit_repsTo(self, samdb, ro=False):
+        """Commit repsTo to the database"""
+
+        # XXX - This is not truly correct according to the MS-TECH
+        #       docs.  To commit a repsTo we should be using RPCs
+        #       IDL_DRSReplicaAdd, IDL_DRSReplicaModify, and
+        #       IDL_DRSReplicaDel to affect a repsTo change.
+        #
+        #       Those RPCs are missing in samba, so I'll have to
+        #       implement them to get this to more accurately
+        #       reflect the reference docs.  As of right now this
+        #       commit to the database will work as its what the
+        #       older KCC also did
+        modify = False
+        newreps = []
+        delreps = []
+
+        for repsTo in self.rep_repsTo:
+
+            # Leave out any to be deleted from
+            # replacement list.  Build a list
+            # of to be deleted reps which we will
+            # remove from rep_repsTo list below
+            if repsTo.to_be_deleted:
+                delreps.append(repsTo)
+                modify = True
+                continue
+
+            if repsTo.is_modified():
+                repsTo.set_unmodified()
+                modify = True
+
+            # current (unmodified) elements also get
+            # appended here but no changes will occur
+            # unless something is "to be modified" or
+            # "to be deleted"
+            newreps.append(ndr_pack(repsTo.ndr_blob))
+
+        # Now delete these from our list of rep_repsTo
+        for repsTo in delreps:
+            self.rep_repsTo.remove(repsTo)
+        delreps = []
+
+        # Nothing to do if no reps have been modified or
+        # need to be deleted or input option has informed
+        # us to be "readonly" (ro).  Leave database
+        # record "as is"
+        if not modify or ro:
+            return
+
+        m = ldb.Message()
+        m.dn = ldb.Dn(samdb, self.nc_dnstr)
+
+        m["repsTo"] = \
+            ldb.MessageElement(newreps, ldb.FLAG_MOD_REPLACE, "repsTo")
+
+        try:
+            samdb.modify(m)
+
+        except ldb.LdbError, estr:
+            raise KCCError("Could not set repsTo for (%s) - (%s)" %
+                           (self.nc_dnstr, estr))
+
 
 class DirectoryServiceAgent(object):
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list