From bdc93190fe075af35d52560401bb4cd0c29bf31d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 Sep 2011 17:30:40 +1000 Subject: s4-dsdb: implement DSDB_REPL_FLAG_PRIORITISE_INCOMING With this set, we accept changes even if they have the same tuple as the local copy. This can be used by a FULL_SYNC replication to recover a replica that is corrupt --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 26 +++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 32b8ab25c9..89f8e23b66 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3681,8 +3681,18 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) continue; } - cmp = replmd_replPropertyMetaData1_is_newer(&nmd.ctr.ctr1.array[j], - &rmd->ctr.ctr1.array[i]); + if (ar->objs->dsdb_repl_flags & DSDB_REPL_FLAG_PRIORITISE_INCOMING) { + /* if we compare equal then do an + update. This is used when a client + asks for a FULL_SYNC, and can be + used to recover a corrupt + replica */ + cmp = !replmd_replPropertyMetaData1_is_newer(&rmd->ctr.ctr1.array[i], + &nmd.ctr.ctr1.array[j]); + } else { + cmp = replmd_replPropertyMetaData1_is_newer(&nmd.ctr.ctr1.array[j], + &rmd->ctr.ctr1.array[i]); + } if (cmp) { /* replace the entry */ nmd.ctr.ctr1.array[j] = rmd->ctr.ctr1.array[i]; @@ -4324,6 +4334,7 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct uint32_t i; struct replmd_private *replmd_private = talloc_get_type(ldb_module_get_private(module), struct replmd_private); + struct dsdb_control_replicated_update *rep_update; ldb = ldb_module_get_ctx(module); @@ -4364,8 +4375,15 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct if (!req->controls) return replmd_replicated_request_werror(ar, WERR_NOMEM); } - /* This allows layers further down to know if a change came in over replication */ - ret = ldb_request_add_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID, false, NULL); + /* This allows layers further down to know if a change came in + over replication and what the replication flags were */ + rep_update = talloc_zero(ar, struct dsdb_control_replicated_update); + if (rep_update == NULL) { + return ldb_module_oom(module); + } + rep_update->dsdb_repl_flags = objs->dsdb_repl_flags; + + ret = ldb_request_add_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID, false, rep_update); if (ret != LDB_SUCCESS) { return ret; } -- cgit