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 <garm...@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 <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Garming Sam <garm...@samba.org> Autobuild-Date(master): Tue Jul 26 05:11:57 CEST 2016 on sn-devel-144 commit 9427a2424ae4bb3250b35e3a38f3afda14a7bd0f Author: Garming Sam <garm...@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 <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit f95bbc7933c71474b2b9796463e72bdde2442c77 Author: Garming Sam <garm...@catalyst.net.nz> Date: Fri Jul 22 14:14:20 2016 +1200 kcc: Add corresponding methods for repsTo Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@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