From: Andrew Bartlett Date: Tue, 31 Oct 2017 19:22:22 +0000 (+1300) Subject: repl_meta_data: Allow delete of an object with dangling backlinks X-Git-Tag: talloc-2.1.11~364 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6cf7abbcfdad84fee57852862ebe44aa6115ca25;p=thirdparty%2Fsamba.git repl_meta_data: Allow delete of an object with dangling backlinks This should not happen, but stopping all replication because of it is a pain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13095 Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Fri Nov 24 19:53:50 CET 2017 on sn-devel-144 --- diff --git a/selftest/knownfail.d/runtime-links b/selftest/knownfail.d/runtime-links deleted file mode 100644 index 70de8be3d55..00000000000 --- a/selftest/knownfail.d/runtime-links +++ /dev/null @@ -1,2 +0,0 @@ -^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_backlink_memberof_deleted_group -^samba4\.blackbox\.runtime-links\.release-4-5-0-pre1\.delete_dangling_backlink_memberof_group \ No newline at end of file diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 597e49c50f1..198ac84c730 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3172,9 +3172,22 @@ static int replmd_modify_handle_linked_attribs(struct ldb_module *module, continue; } if ((schema_attr->linkID & 1) == 1) { - if (parent && ldb_request_get_control(parent, DSDB_CONTROL_DBCHECK)) { - continue; + if (parent) { + struct ldb_control *ctrl; + + ctrl = ldb_request_get_control(parent, + DSDB_CONTROL_REPLMD_VANISH_LINKS); + if (ctrl != NULL) { + ctrl->critical = false; + continue; + } + ctrl = ldb_request_get_control(parent, + DSDB_CONTROL_DBCHECK); + if (ctrl != NULL) { + continue; + } } + /* Odd is for the target. Illegal to modify */ ldb_asprintf_errstring(ldb, "attribute %s must not be modified directly, it is a linked attribute", el->name); @@ -4275,6 +4288,7 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request /* don't remove the rDN */ continue; } + if (sa->linkID & 1) { /* we have a backlink in this object @@ -4288,7 +4302,16 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request replmd_private, old_dn, &guid, el, sa, req); - if (ret != LDB_SUCCESS) { + if (ret == LDB_SUCCESS) { + /* + * now we continue, which means we + * won't remove this backlink + * directly + */ + continue; + } + + if (ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { const char *old_dn_str = ldb_dn_get_linearized(old_dn); ldb_asprintf_errstring(ldb, @@ -4301,11 +4324,16 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } - /* now we continue, which means we - won't remove this backlink - directly - */ - continue; + + /* + * Otherwise vanish the link, we are + * out of sync and the controlling + * object does not have the source + * link any more + */ + + dsdb_flags |= DSDB_REPLMD_VANISH_LINKS; + } else if (sa->linkID == 0) { if (ldb_attr_in_list(preserved_attrs, el->name)) { continue;