The Samba-Bugzilla – Attachment 13605 Details for
Bug 12972
Failed to find account dn (serverReference) for DC=...
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch-set to fix the problem
4.7-bug-fix-v2.txt (text/plain), 24.83 KB, created by
Tim Beale
on 2017-09-18 21:02:47 UTC
(
hide
)
Description:
Patch-set to fix the problem
Filename:
MIME Type:
Creator:
Tim Beale
Created:
2017-09-18 21:02:47 UTC
Size:
24.83 KB
patch
obsolete
>From 5edc97d2fc2df1577da017266ae06f7a0f920fc1 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 13 Sep 2017 13:37:57 +1200 >Subject: [PATCH 1/5] getncchanges.py: Add a test for dropped cross-partition > links > >Samba would drop linked attributes that span partitions if it didn't >know about the target object. This patch adds a test that exposes >the problem. > >I've backported getncchanges.py from master and stripped out the >unnecessary tests/functionality. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > selftest/knownfail.d/getncchanges | 3 + > source4/selftest/tests.py | 5 + > source4/torture/drs/python/getncchanges.py | 149 +++++++++++++++++++++++++++++ > 3 files changed, 157 insertions(+) > create mode 100644 selftest/knownfail.d/getncchanges > create mode 100644 source4/torture/drs/python/getncchanges.py > >diff --git a/selftest/knownfail.d/getncchanges b/selftest/knownfail.d/getncchanges >new file mode 100644 >index 0000000..303400f >--- /dev/null >+++ b/selftest/knownfail.d/getncchanges >@@ -0,0 +1,3 @@ >+samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_cross_partition_links\(vampire_dc\) >+samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_cross_partition_links\(promoted_dc\) >+ >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 4bcbdc6..783676f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -845,6 +845,11 @@ for env in ['vampire_dc', 'promoted_dc']: > name="samba4.drs.linked_attributes_drs.python(%s)" % env, > environ={'DC1': "$DC_SERVER", 'DC2': '$%s_SERVER' % env.upper()}, > extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) >+ planoldpythontestsuite(env, "getncchanges", >+ extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], >+ name="samba4.drs.getncchanges.python(%s)" % env, >+ environ={'DC1': "$DC_SERVER", 'DC2': '$%s_SERVER' % env.upper()}, >+ extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) > > for env in ['vampire_dc', 'promoted_dc', 'vampire_2000_dc']: > planoldpythontestsuite(env, "repl_schema", >diff --git a/source4/torture/drs/python/getncchanges.py b/source4/torture/drs/python/getncchanges.py >new file mode 100644 >index 0000000..d735d9c >--- /dev/null >+++ b/source4/torture/drs/python/getncchanges.py >@@ -0,0 +1,149 @@ >+#!/usr/bin/env python >+# -*- coding: utf-8 -*- >+# >+# Tests various schema replication scenarios >+# >+# Copyright (C) Catalyst.Net Ltd. 2017 >+# >+# This program is free software; you can redistribute it and/or modify >+# it under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# This program is distributed in the hope that it will be useful, >+# but WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with this program. If not, see <http://www.gnu.org/licenses/>. >+# >+ >+# >+# Usage: >+# export DC1=dc1_dns_name >+# export DC2=dc2_dns_name >+# export SUBUNITRUN=$samba4srcdir/scripting/bin/subunitrun >+# PYTHONPATH="$PYTHONPATH:$samba4srcdir/torture/drs/python" $SUBUNITRUN getncchanges -U"$DOMAIN/$DC_USERNAME"%"$DC_PASSWORD" >+# >+ >+import drs_base >+import samba.tests >+import ldb >+from ldb import SCOPE_BASE >+import random >+ >+from samba.dcerpc import drsuapi >+ >+class DrsReplicaSyncIntegrityTestCase(drs_base.DrsBaseTestCase): >+ def setUp(self): >+ super(DrsReplicaSyncIntegrityTestCase, self).setUp() >+ >+ # for this test we modify DC2 and replicate to DC1 >+ self.test_ldb_dc = self.ldb_dc2 >+ >+ # add some randomness to the test OU. (Deletion of the last test's >+ # objects can be slow to replicate out. So the OU created by a previous >+ # testenv may still exist at this point). >+ rand = random.randint(1, 10000000) >+ self.base_dn = self.test_ldb_dc.get_default_basedn() >+ self.ou = "OU=getncchanges%d_test,%s" %(rand, self.base_dn) >+ self.test_ldb_dc.add({ >+ "dn": self.ou, >+ "objectclass": "organizationalUnit"}) >+ >+ def tearDown(self): >+ super(DrsReplicaSyncIntegrityTestCase, self).tearDown() >+ # tidyup groups and users >+ try: >+ self.ldb_dc2.delete(self.ou, ["tree_delete:1"]) >+ except ldb.LdbError as (enum, string): >+ if enum == ldb.ERR_NO_SUCH_OBJECT: >+ pass >+ >+ self._enable_all_repl(self.dnsname_dc2) >+ >+ def add_object(self, dn, objectclass="organizationalunit"): >+ """Adds an OU object""" >+ self.test_ldb_dc.add({"dn": dn, "objectclass": objectclass}) >+ res = self.test_ldb_dc.search(base=dn, scope=SCOPE_BASE, attrs=['objectGUID']) >+ self.assertEquals(len(res), 1) >+ return self._GUID_string(res[0]["objectGUID"][0]) >+ >+ def modify_object(self, dn, attr, value): >+ """Modifies an object's USN by adding an attribute value to it""" >+ m = ldb.Message() >+ m.dn = ldb.Dn(self.test_ldb_dc, dn) >+ m[attr] = ldb.MessageElement(value, ldb.FLAG_MOD_ADD, attr) >+ self.test_ldb_dc.modify(m) >+ >+ def delete_attribute(self, dn, attr, value): >+ """Deletes an attribute from an object""" >+ m = ldb.Message() >+ m.dn = ldb.Dn(self.test_ldb_dc, dn) >+ m[attr] = ldb.MessageElement(value, ldb.FLAG_MOD_DELETE, attr) >+ self.test_ldb_dc.modify(m) >+ >+ def sync_DCs(self, nc_dn=None): >+ # make sure DC1 has all the changes we've made to DC2 >+ self._net_drs_replicate(DC=self.dnsname_dc1, fromDC=self.dnsname_dc2, nc_dn=nc_dn) >+ >+ def test_repl_integrity_cross_partition_links(self): >+ """ >+ Checks that a cross-partition link to an unknown target object does >+ not result in missing links. >+ """ >+ >+ # make sure the peer DC is in sync >+ self.sync_DCs() >+ >+ # stop replication so the peer gets the following objects in one go >+ self._disable_all_repl(self.dnsname_dc2) >+ >+ # create a link source object in the main NC >+ la_source = "OU=cross_nc_src,%s" % self.ou >+ src_guid = self.add_object(la_source) >+ >+ # create the link target (a server object) in the config NC >+ rand = random.randint(1, 10000000) >+ la_target = "CN=getncchanges-%d,CN=Servers,CN=Default-First-Site-Name," \ >+ "CN=Sites,%s" %(rand, self.config_dn) >+ self.add_object(la_target, objectclass="server") >+ >+ # add a cross-partition link between the two >+ self.modify_object(la_source, "managedBy", la_target) >+ >+ # sync the NC containing the link source first, then the target/Config NC >+ self.sync_DCs() >+ self.sync_DCs(nc_dn=self.config_dn) >+ >+ res1 = self.ldb_dc1.search(base="<GUID=%s>" % src_guid, >+ scope=SCOPE_BASE, attrs=["managedBy"]) >+ res2 = self.ldb_dc2.search(base="<GUID=%s>" % src_guid, >+ scope=SCOPE_BASE, attrs=["managedBy"]) >+ >+ self.assertTrue("managedBy" in res1[0], "%s in DB is missing managedBy attribute" >+ % la_source) >+ self.assertTrue("managedBy" in res2[0], "%s in DB is missing managedBy attribute" >+ % la_source) >+ >+ # the cross-partition linked attribute has a missing backlink. Check >+ # that we can still delete it successfully >+ self.delete_attribute(la_source, "managedBy", la_target) >+ self.sync_DCs() >+ >+ res1 = self.ldb_dc1.search(base="<GUID=%s>" % src_guid, >+ scope=SCOPE_BASE, attrs=["managedBy"]) >+ res2 = self.ldb_dc2.search(base="<GUID=%s>" % src_guid, >+ scope=SCOPE_BASE, attrs=["managedBy"]) >+ >+ self.assertFalse("managedBy" in res1[0], "%s in DB still has managedBy attribute" >+ % la_source) >+ self.assertFalse("managedBy" in res2[0], "%s in DB still has managedBy attribute" >+ % la_source) >+ >+ # cleanup the server object we created in the Configuration partition >+ self.test_ldb_dc.delete(la_source) >+ >+ >+ >-- >2.7.4 > > >From 9b1d3122cb95533de469ddc3260f0e87931de924 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Mon, 19 Jun 2017 10:26:48 +1200 >Subject: [PATCH 2/5] libnet: Initialize req_level in become_dc tests > >The net.api.become.dc tests would always pass the request into >libnet_vampire_cb_store_chunk() with req_level=0, which meant that >storing the chunk didn't use the correct replica_flags/exop. > >I noticed this problem when working on client-side support for GET_TGT. >My changes relied on the critical-only request flag being passed down >into replmd, but because the request flags weren't passed correctly, my >changes caused the become_dc tests to fail. > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 475a3206461f5458059f8f530b45f0b1ae636739) >--- > source4/libnet/libnet_become_dc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c >index 43a3209..e9153a0 100644 >--- a/source4/libnet/libnet_become_dc.c >+++ b/source4/libnet/libnet_become_dc.c >@@ -2673,7 +2673,7 @@ static WERROR becomeDC_drsuapi_pull_partition_recv(struct libnet_BecomeDC_state > struct libnet_BecomeDC_Partition *partition, > struct drsuapi_DsGetNCChanges *r) > { >- uint32_t req_level = 0; >+ uint32_t req_level = r->in.level; > struct drsuapi_DsGetNCChangesRequest5 *req5 = NULL; > struct drsuapi_DsGetNCChangesRequest8 *req8 = NULL; > struct drsuapi_DsGetNCChangesRequest10 *req10 = NULL; >-- >2.7.4 > > >From 40adadd5614ddeb4e1d7211f2825b95dcf7d3d2d Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 13 Sep 2017 15:35:20 +1200 >Subject: [PATCH 3/5] drs: Refactor to distinguish missing link target cases > >This is mostly a cherry-pick of f69596cd21d8106afdf494f39d from master, >except I've omitted the actual change in functionality (i.e. dropping >the link). > >It adds the code that allows us to distinguish between the various cases >where the link target can be missing: >- We're replicating a CRITICAL_ONLY object and don't know about the > target yet. >- We've got a cross-partition link and we haven't replicated the > partition containing the target yet. >- Some other corner-case (in master, we'd retry with GET_TGT). > >There should be no change in functionality from this patch (apart from >tweaking the debug message). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > source4/dsdb/repl/drepl_out_helpers.c | 4 ++ > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 83 ++++++++++++++++++++++++- > source4/dsdb/samdb/samdb.h | 2 +- > source4/libnet/libnet_vampire.c | 1 + > 4 files changed, 86 insertions(+), 4 deletions(-) > >diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c >index 80762f0..3c0092e 100644 >--- a/source4/dsdb/repl/drepl_out_helpers.c >+++ b/source4/dsdb/repl/drepl_out_helpers.c >@@ -798,6 +798,10 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req > if (state->op->options & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) { > dsdb_repl_flags |= DSDB_REPL_FLAG_EXPECT_NO_SECRETS; > } >+ if (state->op->options & DRSUAPI_DRS_CRITICAL_ONLY || >+ state->op->extended_op != DRSUAPI_EXOP_NONE) { >+ dsdb_repl_flags |= DSDB_REPL_FLAG_OBJECT_SUBSET; >+ } > > if (state->op->extended_op != DRSUAPI_EXOP_NONE) { > ret = dsdb_find_nc_root(service->samdb, partition, >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index e4c3cda..b6c302e 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -77,6 +77,7 @@ struct replmd_private { > struct la_entry { > struct la_entry *next, *prev; > struct drsuapi_DsReplicaLinkedAttribute *la; >+ bool incomplete_replica; > }; > > struct replmd_replicated_request { >@@ -6564,6 +6565,7 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct > struct ldb_control **ctrls; > int ret; > uint32_t i; >+ bool incomplete_subset; > struct replmd_private *replmd_private = > talloc_get_type(ldb_module_get_private(module), struct replmd_private); > >@@ -6621,6 +6623,7 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct > > ar->controls = req->controls; > req->controls = ctrls; >+ incomplete_subset = (ar->objs->dsdb_repl_flags & DSDB_REPL_FLAG_OBJECT_SUBSET); > > DEBUG(4,("linked_attributes_count=%u\n", objs->linked_attributes_count)); > >@@ -6645,6 +6648,13 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct > } > *la_entry->la = ar->objs->linked_attributes[i]; > >+ /* >+ * we may not be able to resolve link targets properly when >+ * dealing with subsets of objects, e.g. the source is a >+ * critical object and the target isn't >+ */ >+ la_entry->incomplete_replica = incomplete_subset; >+ > /* we need to steal the non-scalars so they stay > around until the end of the transaction */ > talloc_steal(la_entry->la, la_entry->la->identifier); >@@ -6656,6 +6666,46 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct > return replmd_replicated_apply_next(ar); > } > >+/** >+ * Returns True if the source and target DNs both have the same naming context, >+ * i.e. they're both in the same partition. >+ */ >+static bool replmd_objects_have_same_nc(struct ldb_context *ldb, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *source_dn, >+ struct ldb_dn *target_dn) >+{ >+ TALLOC_CTX *tmp_ctx; >+ struct ldb_dn *source_nc; >+ struct ldb_dn *target_nc; >+ int ret; >+ bool same_nc = true; >+ >+ tmp_ctx = talloc_new(mem_ctx); >+ >+ ret = dsdb_find_nc_root(ldb, tmp_ctx, source_dn, &source_nc); >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("Failed to find base DN for source %s\n", >+ ldb_dn_get_linearized(source_dn)); >+ talloc_free(tmp_ctx); >+ return true; >+ } >+ >+ ret = dsdb_find_nc_root(ldb, tmp_ctx, target_dn, &target_nc); >+ if (ret != LDB_SUCCESS) { >+ DBG_ERR("Failed to find base DN for target %s\n", >+ ldb_dn_get_linearized(target_dn)); >+ talloc_free(tmp_ctx); >+ return true; >+ } >+ >+ same_nc = (ldb_dn_compare(source_nc, target_nc) == 0); >+ >+ talloc_free(tmp_ctx); >+ >+ return same_nc; >+} >+ > /* > process one linked attribute structure > */ >@@ -6863,9 +6913,36 @@ linked_attributes[0]: > } > > if (target_res->count == 0) { >- DEBUG(2,(__location__ ": WARNING: Failed to re-resolve GUID %s - using %s\n", >- GUID_string(tmp_ctx, &guid), >- ldb_dn_get_linearized(dsdb_dn->dn))); >+ bool same_partition; >+ >+ /* >+ * TODO: >+ * When we implement Trusted Domains we need to consider >+ * whether they get treated as an incomplete replica here or not >+ */ >+ if (la_entry->incomplete_replica) { >+ >+ /* >+ * If we're only replicating a subset of objects (e.g. >+ * critical-only, single-object), then an unknown target >+ * is probably not a critical problem. We don't increase >+ * the highwater-mark so subsequent replications should >+ * resolve any missing links >+ */ >+ DEBUG(2,(__location__ >+ ": Failed to find target %s linked from %s\n", >+ ldb_dn_get_linearized(dsdb_dn->dn), >+ ldb_dn_get_linearized(msg->dn))); >+ return LDB_SUCCESS; >+ } >+ >+ same_partition = replmd_objects_have_same_nc(ldb, tmp_ctx, msg->dn, dsdb_dn->dn); >+ >+ DEBUG(2,(__location__ ": WARNING: Failed to re-resolve %sGUID %s - using %s\n", >+ same_partition ? "" : "cross-partition ", >+ GUID_string(tmp_ctx, &guid), >+ ldb_dn_get_linearized(dsdb_dn->dn))); >+ > } else if (target_res->count != 1) { > ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching objectGUID %s\n", > GUID_string(tmp_ctx, &guid)); >diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h >index c8658dc..2abaf4a 100644 >--- a/source4/dsdb/samdb/samdb.h >+++ b/source4/dsdb/samdb/samdb.h >@@ -64,7 +64,7 @@ struct dsdb_control_current_partition { > #define DSDB_REPL_FLAG_PARTIAL_REPLICA 2 > #define DSDB_REPL_FLAG_ADD_NCNAME 4 > #define DSDB_REPL_FLAG_EXPECT_NO_SECRETS 8 >- >+#define DSDB_REPL_FLAG_OBJECT_SUBSET 16 > > #define DSDB_CONTROL_REPLICATED_UPDATE_OID "1.3.6.1.4.1.7165.4.3.3" > >diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c >index 25e261e..6b154dd 100644 >--- a/source4/libnet/libnet_vampire.c >+++ b/source4/libnet/libnet_vampire.c >@@ -663,6 +663,7 @@ WERROR libnet_vampire_cb_store_chunk(void *private_data, > */ > ZERO_STRUCT(s_dsa->highwatermark); > uptodateness_vector = NULL; >+ dsdb_repl_flags |= DSDB_REPL_FLAG_OBJECT_SUBSET; > } > > /* TODO: avoid hardcoded flags */ >-- >2.7.4 > > >From 13330ef37d674faa72a4a46b13c63b5b4b898140 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 13 Sep 2017 16:02:00 +1200 >Subject: [PATCH 4/5] replmd: Small refactor to make code flow more obvious > >When the 'Failed to re-resolve GUID' case was hit, target_msg would >still be assigned to NULL. Execution would fall through, bail out >early in replmd_deletion_state(), then return because the >target_deletion_state >= OBJECT_RECYCLED. > >This code path wasn't very clear. Change it so the 're-resolve GUID' >case just returns early. We can then move replmd_deletion_state() into >the only code block that cares about it. > >This patch should not alter functionality. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 28 +++++++++++++------------ > 1 file changed, 15 insertions(+), 13 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index b6c302e..318a3a0 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -6943,6 +6943,8 @@ linked_attributes[0]: > GUID_string(tmp_ctx, &guid), > ldb_dn_get_linearized(dsdb_dn->dn))); > >+ return LDB_SUCCESS; >+ > } else if (target_res->count != 1) { > ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching objectGUID %s\n", > GUID_string(tmp_ctx, &guid)); >@@ -6951,21 +6953,21 @@ linked_attributes[0]: > } else { > target_msg = target_res->msgs[0]; > dsdb_dn->dn = talloc_steal(dsdb_dn, target_msg->dn); >- } > >- /* >- * Check for deleted objects per MS-DRSR 4.1.10.6.13 >- * ProcessLinkValue, because link updates are not applied to >- * recycled and tombstone objects. We don't have to delete >- * any existing link, that should have happened when the >- * object deletion was replicated or initiated. >- */ >- replmd_deletion_state(module, target_msg, >- &target_deletion_state, NULL); >+ /* >+ * Check for deleted objects per MS-DRSR 4.1.10.6.13 >+ * ProcessLinkValue, because link updates are not applied to >+ * recycled and tombstone objects. We don't have to delete >+ * any existing link, that should have happened when the >+ * object deletion was replicated or initiated. >+ */ >+ replmd_deletion_state(module, target_msg, >+ &target_deletion_state, NULL); > >- if (target_deletion_state >= OBJECT_RECYCLED) { >- talloc_free(tmp_ctx); >- return LDB_SUCCESS; >+ if (target_deletion_state >= OBJECT_RECYCLED) { >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+ } > } > > /* see if this link already exists */ >-- >2.7.4 > > >From d9bb8357af936754cd2d3132a9baa8d83ca23416 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 13 Sep 2017 16:24:09 +1200 >Subject: [PATCH 5/5] replmd: Try to add forward-link for unknown > cross-partition links > >Previously Samba would just drop cross-partition links where the link >target object is unknown. Instead, what we want to do is try to add the >forward link for the GUID specified. We can't add the backlink because >we don't know the target, however, dbcheck should be able to fix any >missing backlinks. > >The new behaviour should now mean dbcheck will detect the problem and be >able to fix it. It's still not ideal, but it's better than dropping the >link completely. > >I've updated the log so that it has higher severity and tells the user >what they need to do to fix it. > >These changes now mean that the selftests now detect an error - instead >of completely dropping the serverReference, we now have a missing >backlink. I've updated the selftests to fix up any missing >serverReference backlinks before running dbcheck. > >(This is master commit fae5df891c11f642cbede9e backported to 4.7) > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > selftest/knownfail.d/getncchanges | 3 --- > source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 26 ++++++++++++++++++------- > testprogs/blackbox/dbcheck.sh | 8 ++++++++ > 3 files changed, 27 insertions(+), 10 deletions(-) > delete mode 100644 selftest/knownfail.d/getncchanges > >diff --git a/selftest/knownfail.d/getncchanges b/selftest/knownfail.d/getncchanges >deleted file mode 100644 >index 303400f..0000000 >--- a/selftest/knownfail.d/getncchanges >+++ /dev/null >@@ -1,3 +0,0 @@ >-samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_cross_partition_links\(vampire_dc\) >-samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_integrity_cross_partition_links\(promoted_dc\) >- >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index 318a3a0..3e0407f 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -375,8 +375,9 @@ static int replmd_process_backlink(struct ldb_module *module, struct la_backlink > ret = dsdb_module_dn_by_guid(module, frame, &bl->target_guid, &target_dn, parent); > if (ret != LDB_SUCCESS) { > struct GUID_txt_buf guid_str; >- DEBUG(2,(__location__ ": WARNING: Failed to find target DN for linked attribute with GUID %s\n", >- GUID_buf_string(&bl->target_guid, &guid_str))); >+ DBG_WARNING("Failed to find target DN for linked attribute with GUID %s\n", >+ GUID_buf_string(&bl->target_guid, &guid_str)); >+ DBG_WARNING("Please run 'samba-tool dbcheck' to resolve any missing backlinks.\n"); > talloc_free(frame); > return LDB_SUCCESS; > } >@@ -6938,12 +6939,23 @@ linked_attributes[0]: > > same_partition = replmd_objects_have_same_nc(ldb, tmp_ctx, msg->dn, dsdb_dn->dn); > >- DEBUG(2,(__location__ ": WARNING: Failed to re-resolve %sGUID %s - using %s\n", >- same_partition ? "" : "cross-partition ", >- GUID_string(tmp_ctx, &guid), >- ldb_dn_get_linearized(dsdb_dn->dn))); >+ if (same_partition) { >+ DEBUG(2,(__location__ ": WARNING: Failed to re-resolve GUID %s - using %s\n", >+ GUID_string(tmp_ctx, &guid), >+ ldb_dn_get_linearized(dsdb_dn->dn))); >+ return LDB_SUCCESS; >+ } else { > >- return LDB_SUCCESS; >+ /* >+ * The target of the cross-partition link is missing. >+ * Continue and try to at least add the forward-link. >+ * This isn't great, but if we can add a partial link >+ * then it's better than nothing. >+ */ >+ DBG_WARNING("Missing cross-partition target %s linked from %s\n", >+ ldb_dn_get_linearized(dsdb_dn->dn), >+ ldb_dn_get_linearized(msg->dn)); >+ } > > } else if (target_res->count != 1) { > ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching objectGUID %s\n", >diff --git a/testprogs/blackbox/dbcheck.sh b/testprogs/blackbox/dbcheck.sh >index 0f979ab..387ce70 100755 >--- a/testprogs/blackbox/dbcheck.sh >+++ b/testprogs/blackbox/dbcheck.sh >@@ -27,6 +27,13 @@ dbcheck_fix_stale_links() { > $BINDIR/samba-tool dbcheck --quiet --fix --yes remove_plausible_deleted_DN_links --attrs="member msDS-NC-Replica-Locations msDS-NC-RO-Replica-Locations" --cross-ncs $ARGS > } > >+# This list of attributes can be freely extended >+dbcheck_fix_crosspartition_backlinks() { >+ # we may not know the target yet when we receive a cross-partition link, >+ # which can result in a missing backlink >+ $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_missing_backlinks --attrs="serverReference" --cross-ncs $ARGS >+} >+ > # This test shows that this does not do anything to a current > # provision (that would be a bug) > dbcheck_reset_well_known_acls() { >@@ -47,6 +54,7 @@ force_modules() { > > dbcheck_fix_one_way_links > dbcheck_fix_stale_links >+dbcheck_fix_crosspartition_backlinks > testit "dbcheck" dbcheck > testit "reindex" reindex > testit "fixed_attrs" fixed_attrs >-- >2.7.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 12972
:
13480
|
13581
|
13595
| 13605