replmd: Mark link conflicts as inactive correctly
authorTim Beale <timbeale@catalyst.net.nz>
Wed, 27 Sep 2017 03:37:59 +0000 (16:37 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 20 Oct 2017 02:05:21 +0000 (04:05 +0200)
The previous patch to handle link conflicts was simply overriding the
received information and marking the link as deleted. We should be doing
this as a separate operation to make it clear what has happened, and so
that the new (i.e. inactive) link details get replicated out.

This patch changes it so that when a conflict occurs, we immediately
overwrite the received information to mark it as deleted, and to update
the version/USN/timestamp/originating_invocation_id to make it clear
that this is a new change.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13055

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index d37137bf0cd172854615836c0f30945a243df7b8..4f347938e17fdc9f7b8c733b74019aeae4f63804 100644 (file)
@@ -7302,6 +7302,7 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
        enum deletion_state deletion_state = OBJECT_NOT_DELETED;
        struct dsdb_dn *old_dsdb_dn = NULL;
        struct ldb_val *val_to_update = NULL;
+       bool add_as_inactive = false;
 
        /*
         * get the attribute being modified, the search result for the source object,
@@ -7438,8 +7439,11 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
                                    ldb_dn_get_linearized(conflict_pdn->dsdb_dn->dn),
                                    ldb_dn_get_linearized(dsdb_dn->dn));
 
-                       /* don't add the link as active */
-                       active = false;
+                       /*
+                        * we want to keep our existing active link and add the
+                        * received link as inactive
+                        */
+                       add_as_inactive = true;
                }
        }
 
@@ -7516,8 +7520,22 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
                return ret;
        }
 
-       /* if the new link is active, then add the new backlink */
-       if (active) {
+       if (add_as_inactive) {
+
+               /* Set the new link as inactive/deleted to avoid conflicts */
+               ret = replmd_delete_link_value(module, replmd_private, old_el,
+                                              msg->dn, schema, attr, seq_num,
+                                              false, &guid, dsdb_dn,
+                                              val_to_update);
+
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(tmp_ctx);
+                       return ret;
+               }
+
+       } else if (active) {
+
+               /* if the new link is active, then add the new backlink */
                ret = replmd_add_backlink(module, replmd_private,
                                          schema,
                                          msg->dn,