repl_meta_data: Allow delete of an object with dangling backlinks
authorAndrew Bartlett <abartlet@samba.org>
Tue, 31 Oct 2017 19:22:22 +0000 (08:22 +1300)
committerStefan Metzmacher <metze@samba.org>
Thu, 23 Nov 2017 14:30:26 +0000 (15:30 +0100)
This should not happen, but stopping all replication because of it is a pain.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail.d/runtime-links [deleted file]
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

diff --git a/selftest/knownfail.d/runtime-links b/selftest/knownfail.d/runtime-links
deleted file mode 100644 (file)
index 70de8be..0000000
+++ /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
index 597e49c50f1a723b300aa5a0ffe3f968ddae0894..091517c591e21ec4f4a5531bd45159532afce641 100644 (file)
@@ -3172,9 +3172,20 @@ 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
+                                       = ldb_request_get_control(parent,
+                                                                 DSDB_CONTROL_REPLMD_VANISH_LINKS);
+                               if (ctrl) {
+                                       ctrl->critical = false;
+                                       continue;
+                               }
+                               if (ldb_request_get_control(parent,
+                                                           DSDB_CONTROL_DBCHECK)) {
+                                       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 +4286,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 +4300,15 @@ 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 +4321,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;