summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/samba/join.py19
-rw-r--r--selftest/knownfail.d/replicate_against_deleted1
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c13
3 files changed, 31 insertions, 2 deletions
diff --git a/python/samba/join.py b/python/samba/join.py
index 70b3c9729b0..6c1ab3be7b4 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -50,6 +50,7 @@ import tempfile
from collections import OrderedDict
from samba.common import get_string
from samba.netcmd import CommandError
+from samba import dsdb
class DCJoinException(Exception):
@@ -937,6 +938,10 @@ class DCJoinContext(object):
"""Replicate the SAM."""
ctx.logger.info("Starting replication")
+
+ # A global transaction is started so that linked attributes
+ # are applied at the very end, once all partitions are
+ # replicated. This helps get all cross-partition links.
ctx.local_samdb.transaction_start()
try:
source_dsa_invocation_id = misc.GUID(ctx.samdb.get_invocation_id())
@@ -1057,7 +1062,21 @@ class DCJoinContext(object):
ctx.local_samdb.transaction_cancel()
raise
else:
+
+ # This is a special case, we have completed a full
+ # replication so if a link comes to us that points to a
+ # deleted object, and we asked for all objects already, we
+ # just have to ignore it, the chance to re-try the
+ # replication with GET_TGT has long gone. This can happen
+ # if the object is deleted and sent to us after the link
+ # was sent, as we are processing all links in the
+ # transaction_commit().
+ if not ctx.domain_replica_flags & drsuapi.DRSUAPI_DRS_CRITICAL_ONLY:
+ ctx.local_samdb.set_opaque_integer(dsdb.DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME,
+ 1)
ctx.local_samdb.transaction_commit()
+ ctx.local_samdb.set_opaque_integer(dsdb.DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME,
+ 0)
ctx.logger.info("Committed SAM database")
# A large replication may have caused our LDB connection to the
diff --git a/selftest/knownfail.d/replicate_against_deleted b/selftest/knownfail.d/replicate_against_deleted
deleted file mode 100644
index 9caa5346a45..00000000000
--- a/selftest/knownfail.d/replicate_against_deleted
+++ /dev/null
@@ -1 +0,0 @@
-samba4.drs.ridalloc_exop.python\(.*\).ridalloc_exop.DrsReplicaSyncTestCase.test_replicate_against_deleted_objects_transaction
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index c1ea5ad90f8..175a02d3ba7 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -7533,6 +7533,16 @@ static int replmd_allow_missing_target(struct ldb_module *module,
source_dn,
target_dn);
if (is_in_same_nc) {
+ /*
+ * We allow the join.py code to point out that all
+ * replication is completed, so failing now would just
+ * trigger errors, rather than trigger a GET_TGT
+ */
+ int *finished_full_join_ptr =
+ talloc_get_type(ldb_get_opaque(ldb,
+ DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME),
+ int);
+ bool finished_full_join = finished_full_join_ptr && *finished_full_join_ptr;
/*
* if the target is already be up-to-date there's no point in
@@ -7540,7 +7550,8 @@ static int replmd_allow_missing_target(struct ldb_module *module,
* on a one-way link was deleted. We ignore the link rather
* than failing the replication cycle completely
*/
- if (dsdb_repl_flags & DSDB_REPL_FLAG_TARGETS_UPTODATE) {
+ if (finished_full_join
+ || dsdb_repl_flags & DSDB_REPL_FLAG_TARGETS_UPTODATE) {
*ignore_link = true;
DBG_WARNING("%s is %s "
"but up to date. Ignoring link from %s\n",