The branch, master has been updated
       via  852e1db dsdb: Add comments explaining the limitations of our 
current backlink behaviour
       via  7a36cb3 s4:samldb: internally use extended dns while changing the 
primaryGroupID field
       via  0386307 s4:repl_meta_data: add support for 
DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID
       via  1ef145d s4:repl_meta_data: pass down struct 
replmd_replicated_request to replmd_modify_la_replace()
       via  738b52e s4:repl_meta_data: pass down struct 
replmd_replicated_request to replmd_modify_la_delete()
       via  70a306d s4:repl_meta_data: add missing 
 to a DEBUG message in replmd_modify_la_add()
       via  42e69a8 s4:repl_meta_data: pass down struct 
replmd_replicated_request to replmd_modify_la_add()
       via  966c7fe s4:repl_meta_data: pass down struct 
replmd_replicated_request to replmd_modify_handle_linked_attribs()
       via  f81771c blackbox/dbcheck-links: Test broken links with missing 
<SID=...> on linked attributes
       via  a801799 dbchecker: Fix missing <SID=...> on linked attributes
       via  c5c99b5 dbchecker: improve verbose output of do_modify()
       via  bb9c9e4 s4:dsdb: add DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID oid
       via  364ed53 testprogs/blackbox: add samba4.blackbox.test_primary_group 
test
       via  60131b4 s4:dsdb: fix comment on 
DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME
       via  0189f23 schema_samba4.ldif: add allocation of 
DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME
      from  500a729 tdb: Make record deletion circular-chain safe

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 852e1db12b0afa04a738c03bb2609c084fe96a7f
Author: Andrew Bartlett <abart...@samba.org>
Date:   Tue Oct 30 15:56:43 2018 +1300

    dsdb: Add comments explaining the limitations of our current backlink 
behaviour
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Tim Beale <timbe...@catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abart...@samba.org>
    Autobuild-Date(master): Tue Oct 30 10:32:51 CET 2018 on sn-devel-144

commit 7a36cb30b716d56b84e894851c1a18e9eb3a0964
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 24 15:33:49 2018 +0200

    s4:samldb: internally use extended dns while changing the primaryGroupID 
field
    
    This is important, otherwise we'll loose the <SID=> component of the
    linked attribute.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 0386307e34097f5d9233c970983c7306d1705a87
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 15:56:18 2018 +0200

    s4:repl_meta_data: add support for DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID
    
    This will be used by dbcheck in the next commits.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 1ef145d9d72d847055f6aba8a0070b3e1cfdabbc
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 18:43:25 2018 +0200

    s4:repl_meta_data: pass down struct replmd_replicated_request to 
replmd_modify_la_replace()
    
    This will simplify further changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 738b52eb0856c8fcdbb8589e8061bcc14700c23a
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 18:43:25 2018 +0200

    s4:repl_meta_data: pass down struct replmd_replicated_request to 
replmd_modify_la_delete()
    
    This will simplify further changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 70a306d0bd6806d1fd00d45e3d8cc70c73d09f79
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 19:34:08 2018 +0200

    s4:repl_meta_data: add missing \n to a DEBUG message in 
replmd_modify_la_add()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 42e69a86ca583e3cb20c63b9c6930b4b3425485d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 18:43:25 2018 +0200

    s4:repl_meta_data: pass down struct replmd_replicated_request to 
replmd_modify_la_add()
    
    This will simplify further changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 966c7febaf0245516481bde924ea6cd738eeb78b
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 18:43:25 2018 +0200

    s4:repl_meta_data: pass down struct replmd_replicated_request to 
replmd_modify_handle_linked_attribs()
    
    This will simplify further changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit f81771c8593327e058b9cb4330d7e77083df3ea9
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 15:56:18 2018 +0200

    blackbox/dbcheck-links: Test broken links with missing <SID=...> on linked 
attributes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit a801799ebe26780653f4ed3fa3fc633e31871f7d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Oct 12 15:56:18 2018 +0200

    dbchecker: Fix missing <SID=...> on linked attributes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit c5c99b569569ce36cac94e967ca53e3182abd6f7
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Oct 8 17:14:28 2018 +0200

    dbchecker: improve verbose output of do_modify()
    
    This makes it easier to debug dbcheck problems.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit bb9c9e49a5e82f19626cb1b12ec9189fff5114e8
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Oct 8 17:13:52 2018 +0200

    s4:dsdb: add DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID oid
    
    This will be used to fix missing <SID=> components in future.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 364ed537e0bcb3a97cae0f2d1ff72de9423ce0e6
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Oct 16 15:16:18 2018 +0200

    testprogs/blackbox: add samba4.blackbox.test_primary_group test
    
    This demonstrates the bug, that happens when the primaryGroupID
    of a user is changed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13418
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 60131b4452d43b3792e7f27a4190c88e7aabb1b4
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Oct 8 17:13:13 2018 +0200

    s4:dsdb: fix comment on DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 0189f23f5bda263c7462366ee16b2fe4bcda0119
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Oct 8 15:35:52 2018 +0200

    schema_samba4.ldif: add allocation of DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME
    
    This was already allocated in source4/dsdb/samdb/samdb.h with
    commit 22208f52e6096fbe9413b8ff339d9446851e0874.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/dbchecker.py                          |  45 +++-
 source4/dsdb/pydsdb.c                              |   1 +
 source4/dsdb/samdb/ldb_modules/extended_dn_store.c |   7 +
 source4/dsdb/samdb/ldb_modules/linked_attributes.c |  18 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    | 269 +++++++++++++++------
 source4/dsdb/samdb/ldb_modules/samldb.c            |  41 +++-
 source4/dsdb/samdb/samdb.h                         |   5 +-
 ...eck-link-output-missing-link-sid-corruption.txt |   8 +
 source4/selftest/tests.py                          |   2 +
 source4/setup/schema_samba4.ldif                   |   2 +
 testprogs/blackbox/dbcheck-links.sh                | 110 +++++++++
 testprogs/blackbox/test_primary_group.sh           |  90 +++++++
 12 files changed, 515 insertions(+), 83 deletions(-)
 create mode 100644 
source4/selftest/provisions/release-4-5-0-pre1/expected-dbcheck-link-output-missing-link-sid-corruption.txt
 create mode 100755 testprogs/blackbox/test_primary_group.sh


Changeset truncated at 500 lines:

diff --git a/python/samba/dbchecker.py b/python/samba/dbchecker.py
index dcdbb893..c70ca7b 100644
--- a/python/samba/dbchecker.py
+++ b/python/samba/dbchecker.py
@@ -79,6 +79,7 @@ class dbcheck(object):
         self.fix_all_string_dn_component_mismatch = False
         self.fix_all_GUID_dn_component_mismatch = False
         self.fix_all_SID_dn_component_mismatch = False
+        self.fix_all_SID_dn_component_missing = False
         self.fix_all_old_dn_string_component_mismatch = False
         self.fix_all_metadata = False
         self.fix_time_metadata = False
@@ -402,10 +403,11 @@ systemFlags: -1946157056%s""" % (dn, guid_suffix),
 
     def do_modify(self, m, controls, msg, validate=True):
         '''perform a modify with optional verbose output'''
+        controls = controls + ["local_oid:%s:0" % dsdb.DSDB_CONTROL_DBCHECK]
         if self.verbose:
             self.report(self.samdb.write_ldif(m, ldb.CHANGETYPE_MODIFY))
+            self.report("controls: %r" % controls)
         try:
-            controls = controls + ["local_oid:%s:0" % 
dsdb.DSDB_CONTROL_DBCHECK]
             self.samdb.modify(m, controls=controls, validate=validate)
         except Exception as err:
             if self.in_transaction:
@@ -697,6 +699,38 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), 
str(to_base)))
                           "Failed to fix incorrect DN %s on attribute %s" % 
(mismatch_type, attrname)):
             self.report("Fixed incorrect DN %s on attribute %s" % 
(mismatch_type, attrname))
 
+    def err_dn_component_missing_target_sid(self, dn, attrname, val, dsdb_dn, 
target_sid_blob):
+        """handle a DN string being incorrect"""
+        self.report("ERROR: missing DN SID component for %s in object %s - %s" 
% (attrname, dn, val))
+
+        if len(dsdb_dn.prefix) != 0:
+            self.report("Not fixing missing DN SID on DN+BINARY or DN+STRING")
+            return
+
+        correct_dn = ldb.Dn(self.samdb, dsdb_dn.dn.extended_str())
+        correct_dn.set_extended_component("SID", target_sid_blob)
+
+        if not self.confirm_all('Change DN to %s?' % correct_dn.extended_str(),
+                                'fix_all_SID_dn_component_missing'):
+            self.report("Not fixing missing DN SID component")
+            return
+
+        target_guid_blob = correct_dn.get_extended_component("GUID")
+        guid_sid_dn = ldb.Dn(self.samdb, "")
+        guid_sid_dn.set_extended_component("GUID", target_guid_blob)
+        guid_sid_dn.set_extended_component("SID", target_sid_blob)
+
+        m = ldb.Message()
+        m.dn = dn
+        m['new_value'] = ldb.MessageElement(guid_sid_dn.extended_str(), 
ldb.FLAG_MOD_ADD, attrname)
+        controls = [
+            "show_recycled:1",
+            "local_oid:%s:1" % dsdb.DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID
+        ]
+        if self.do_modify(m, controls,
+                          "Failed to ADD missing DN SID on attribute %s" % 
(attrname)):
+            self.report("Fixed missing DN SID on attribute %s" % (attrname))
+
     def err_unknown_attribute(self, obj, attrname):
         '''handle an unknown attribute error'''
         self.report("ERROR: unknown attribute '%s' in %s" % (attrname, obj.dn))
@@ -1322,7 +1356,14 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), 
str(to_base)))
                                                       res[0].dn, "GUID")
                 continue
 
-            if res[0].dn.get_extended_component("SID") != 
dsdb_dn.dn.get_extended_component("SID"):
+            target_sid = res[0].dn.get_extended_component("SID")
+            link_sid = dsdb_dn.dn.get_extended_component("SID")
+            if link_sid is None and target_sid is not None:
+                error_count += 1
+                self.err_dn_component_missing_target_sid(obj.dn, attrname, val,
+                                                         dsdb_dn, target_sid)
+                continue
+            if link_sid != target_sid:
                 error_count += 1
                 self.err_dn_component_target_mismatch(obj.dn, attrname, val, 
dsdb_dn,
                                                       res[0].dn, "SID")
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 19fb75d..36cc80d 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -1659,6 +1659,7 @@ MODULE_INIT_FUNC(dsdb)
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA);
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS);
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_LINK_DN_NAME);
+       ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID);
        ADD_DSDB_STRING(DSDB_CONTROL_REPLMD_VANISH_LINKS);
        ADD_DSDB_STRING(DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
        ADD_DSDB_STRING(DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID);
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c 
b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
index a37b55c..6bfced3 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
@@ -722,6 +722,7 @@ static int extended_dn_modify(struct ldb_module *module, 
struct ldb_request *req
        unsigned int i, j;
        struct extended_dn_context *ac;
        struct ldb_control *fix_links_control = NULL;
+       struct ldb_control *fix_link_sid_ctrl = NULL;
        int ret;
 
        if (ldb_dn_is_special(req->op.mod.message->dn)) {
@@ -746,6 +747,12 @@ static int extended_dn_modify(struct ldb_module *module, 
struct ldb_request *req
                return ldb_next_request(module, req);
        }
 
+       fix_link_sid_ctrl = ldb_request_get_control(ac->req,
+                                       DSDB_CONTROL_DBCHECK_FIX_LINK_DN_SID);
+       if (fix_link_sid_ctrl != NULL) {
+               return ldb_next_request(module, req);
+       }
+
        for (i=0; i < req->op.mod.message->num_elements; i++) {
                const struct ldb_message_element *el = 
&req->op.mod.message->elements[i];
                const struct dsdb_attribute *schema_attr
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c 
b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index 57d2507..2568d4d 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -25,7 +25,23 @@
  *
  *  Component: ldb linked_attributes module
  *
- *  Description: Module to ensure linked attribute pairs remain in sync
+ *  Description: Module to ensure linked attribute pairs (i.e. forward-links
+ *  and backlinks) remain in sync.
+ *
+ *  Backlinks are 'plain' links (without extra metadata). When the link target
+ *  object is modified (e.g. renamed), we use the backlinks to keep the link
+ *  source object updated. Note there are some cases where we can't do this:
+ *    - one-way links, which don't have a corresponding backlink
+ *    - two-way deactivated links, i.e. when a user is removed from a group,
+ *      the forward 'member' link still exists (but is inactive), however, the
+ *      'memberOf' backlink is deleted.
+ *  In these cases, we can end up with a dangling forward link which is
+ *  incorrect (i.e. the target has been renamed or deleted). We have dbcheck
+ *  rules to detect and fix this, and cope otherwise by filtering at runtime
+ *  (i.e. in the extended_dn module).
+ *
+ *  See also repl_meta_data.c, which handles updating links for deleted
+ *  objects, as well as link changes received from another DC.
  *
  *  Author: Andrew Bartlett
  */
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 
b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 584fd21..b1f1523 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -112,6 +112,8 @@ struct replmd_replicated_request {
        bool is_urgent;
 
        bool isDeleted;
+
+       bool fix_link_sid;
 };
 
 static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar);
@@ -2402,12 +2404,11 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, 
struct ldb_val *v, struct d
  */
 static int replmd_modify_la_add(struct ldb_module *module,
                                struct replmd_private *replmd_private,
-                               const struct dsdb_schema *schema,
+                               struct replmd_replicated_request *ac,
                                struct ldb_message *msg,
                                struct ldb_message_element *el,
                                struct ldb_message_element *old_el,
                                const struct dsdb_attribute *schema_attr,
-                               uint64_t seq_num,
                                time_t t,
                                struct ldb_dn *msg_dn,
                                struct ldb_request *parent)
@@ -2420,17 +2421,10 @@ static int replmd_modify_la_add(struct ldb_module 
*module,
        unsigned old_num_values = old_el ? old_el->num_values : 0;
        unsigned num_values = 0;
        unsigned max_num_values;
-       const struct GUID *invocation_id;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        NTTIME now;
        unix_to_nt_time(&now, t);
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               talloc_free(tmp_ctx);
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        /* get the DNs to be added, fully parsed.
         *
         * We need full parsing because they came off the wire and we don't
@@ -2457,7 +2451,7 @@ static int replmd_modify_la_add(struct ldb_module *module,
        max_num_values = old_num_values + el->num_values;
        if (max_num_values < old_num_values) {
                DEBUG(0, ("we seem to have overflow in replmd_modify_la_add. "
-                         "old values: %u, new values: %u, sum: %u",
+                         "old values: %u, new values: %u, sum: %u\n",
                          old_num_values, el->num_values, max_num_values));
                talloc_free(tmp_ctx);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -2493,6 +2487,109 @@ static int replmd_modify_la_add(struct ldb_module 
*module,
                        return err;
                }
 
+               if (ac->fix_link_sid) {
+                       char *fixed_dnstring = NULL;
+                       struct dom_sid tmp_sid = { 0, };
+                       DATA_BLOB sid_blob = data_blob_null;
+                       enum ndr_err_code ndr_err;
+                       NTSTATUS status;
+                       int num;
+
+                       if (exact == NULL) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       if (dns[i].dsdb_dn->dn_format != DSDB_NORMAL_DN) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       /*
+                        * Only "<GUID=...><SID=...>" is allowed.
+                        *
+                        * We get the GUID to just to find the old
+                        * value and the SID in order to add it
+                        * to the found value.
+                        */
+
+                       num = ldb_dn_get_comp_num(dns[i].dsdb_dn->dn);
+                       if (num != 0) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       num = ldb_dn_get_extended_comp_num(dns[i].dsdb_dn->dn);
+                       if (num != 2) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       status = dsdb_get_extended_dn_sid(exact->dsdb_dn->dn,
+                                                         &tmp_sid, "SID");
+                       if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                               /* this is what we expect */
+                       } else if (NT_STATUS_IS_OK(status)) {
+                               struct GUID_txt_buf guid_str;
+                               ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+                                                      "i[%u] SID NOT 
MISSING... Attribute %s already "
+                                                      "exists for target GUID 
%s, SID %s, DN: %s",
+                                                      i, el->name,
+                                                      
GUID_buf_string(&exact->guid,
+                                                                      
&guid_str),
+                                                      dom_sid_string(tmp_ctx, 
&tmp_sid),
+                                                      
dsdb_dn_get_extended_linearized(tmp_ctx,
+                                                              exact->dsdb_dn, 
1));
+                               talloc_free(tmp_ctx);
+                               return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+                       } else {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       status = dsdb_get_extended_dn_sid(dns[i].dsdb_dn->dn,
+                                                         &tmp_sid, "SID");
+                       if (!NT_STATUS_IS_OK(status)) {
+                               struct GUID_txt_buf guid_str;
+                               ldb_asprintf_errstring(ldb,
+                                                      "NO SID PROVIDED... 
Attribute %s already "
+                                                      "exists for target GUID 
%s",
+                                                      el->name,
+                                                      
GUID_buf_string(&exact->guid,
+                                                                      
&guid_str));
+                               talloc_free(tmp_ctx);
+                               return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+                       }
+
+                       ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, 
&tmp_sid,
+                                                      
(ndr_push_flags_fn_t)ndr_push_dom_sid);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       ret = ldb_dn_set_extended_component(exact->dsdb_dn->dn, 
"SID", &sid_blob);
+                       data_blob_free(&sid_blob);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(tmp_ctx);
+                               return ret;
+                       }
+
+                       fixed_dnstring = dsdb_dn_get_extended_linearized(
+                                       new_values, exact->dsdb_dn, 1);
+                       if (fixed_dnstring == NULL) {
+                               talloc_free(tmp_ctx);
+                               return ldb_operr(ldb);
+                       }
+
+                       /*
+                        * We just replace the existing value...
+                        */
+                       *exact->v = data_blob_string_const(fixed_dnstring);
+
+                       continue;
+               }
+
                if (exact != NULL) {
                        /*
                         * We are trying to add one that exists, which is only
@@ -2526,15 +2623,16 @@ static int replmd_modify_la_add(struct ldb_module 
*module,
                        ret = replmd_update_la_val(new_values, exact->v,
                                                   dns[i].dsdb_dn,
                                                   exact->dsdb_dn,
-                                                  invocation_id, seq_num,
-                                                  seq_num, now, false);
+                                                  &ac->our_invocation_id,
+                                                  ac->seq_num, ac->seq_num,
+                                                  now, false);
                        if (ret != LDB_SUCCESS) {
                                talloc_free(tmp_ctx);
                                return ret;
                        }
 
                        ret = replmd_add_backlink(module, replmd_private,
-                                                 schema,
+                                                 ac->schema,
                                                  msg_dn,
                                                  &dns[i].guid, 
                                                  true,
@@ -2576,14 +2674,14 @@ static int replmd_modify_la_add(struct ldb_module 
*module,
                }
 
                ret = replmd_add_backlink(module, replmd_private,
-                                         schema, msg_dn,
+                                         ac->schema, msg_dn,
                                          &dns[i].guid,
                                          true, schema_attr,
                                          parent);
                /* Make the new linked attribute ldb_val. */
                ret = replmd_build_la_val(new_values, &new_values[num_values],
-                                         dns[i].dsdb_dn, invocation_id,
-                                         seq_num, now);
+                                         dns[i].dsdb_dn, 
&ac->our_invocation_id,
+                                         ac->seq_num, now);
                if (ret != LDB_SUCCESS) {
                        talloc_free(tmp_ctx);
                        return ret;
@@ -2622,12 +2720,11 @@ static int replmd_modify_la_add(struct ldb_module 
*module,
  */
 static int replmd_modify_la_delete(struct ldb_module *module,
                                   struct replmd_private *replmd_private,
-                                  const struct dsdb_schema *schema,
+                                  struct replmd_replicated_request *ac,
                                   struct ldb_message *msg,
                                   struct ldb_message_element *el,
                                   struct ldb_message_element *old_el,
                                   const struct dsdb_attribute *schema_attr,
-                                  uint64_t seq_num,
                                   time_t t,
                                   struct ldb_dn *msg_dn,
                                   struct ldb_request *parent)
@@ -2641,16 +2738,10 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
        bool vanish_links = false;
        unsigned int num_to_delete = el->num_values;
        uint32_t rmd_flags;
-       const struct GUID *invocation_id;
        NTTIME now;
 
        unix_to_nt_time(&now, t);
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        if (old_el == NULL || old_el->num_values == 0) {
                /* there is nothing to delete... */
                if (num_to_delete == 0) {
@@ -2714,7 +2805,7 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
                                }
                        }
                        ret = replmd_add_backlink(module, replmd_private,
-                                                 schema, msg_dn, &p->guid,
+                                                 ac->schema, msg_dn, &p->guid,
                                                  false, schema_attr,
                                                  parent);
                        if (ret != LDB_SUCCESS) {
@@ -2732,8 +2823,9 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
 
                        ret = replmd_update_la_val(old_el->values, p->v,
                                                   p->dsdb_dn, p->dsdb_dn,
-                                                  invocation_id, seq_num,
-                                                  seq_num, now, true);
+                                                  &ac->our_invocation_id,
+                                                  ac->seq_num, ac->seq_num,
+                                                  now, true);
                        if (ret != LDB_SUCCESS) {
                                talloc_free(tmp_ctx);
                                return ret;
@@ -2795,7 +2887,7 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
                        /* remove the backlink */
                        ret = replmd_add_backlink(module,
                                                  replmd_private,
-                                                 schema, 
+                                                 ac->schema,
                                                  msg_dn,
                                                  &p->guid,
                                                  false, schema_attr,
@@ -2829,14 +2921,15 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
 
                ret = replmd_update_la_val(old_el->values, exact->v,
                                           exact->dsdb_dn, exact->dsdb_dn,
-                                          invocation_id, seq_num, seq_num,
+                                          &ac->our_invocation_id,
+                                          ac->seq_num, ac->seq_num,
                                           now, true);
                if (ret != LDB_SUCCESS) {
                        talloc_free(tmp_ctx);
                        return ret;
                }
                ret = replmd_add_backlink(module, replmd_private,
-                                         schema, msg_dn,
+                                         ac->schema, msg_dn,
                                          &p->guid,
                                          false, schema_attr,
                                          parent);
@@ -2886,12 +2979,11 @@ static int replmd_modify_la_delete(struct ldb_module 
*module,
  */
 static int replmd_modify_la_replace(struct ldb_module *module,
                                    struct replmd_private *replmd_private,
-                                   const struct dsdb_schema *schema,
+                                   struct replmd_replicated_request *ac,
                                    struct ldb_message *msg,
                                    struct ldb_message_element *el,
                                    struct ldb_message_element *old_el,
                                    const struct dsdb_attribute *schema_attr,
-                                   uint64_t seq_num,
                                    time_t t,
                                    struct ldb_dn *msg_dn,
                                    struct ldb_request *parent)
@@ -2900,7 +2992,6 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
        struct parsed_dn *dns, *old_dns;
        TALLOC_CTX *tmp_ctx = talloc_new(msg);
        int ret;
-       const struct GUID *invocation_id;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        struct ldb_val *new_values = NULL;
        const char *ldap_oid = schema_attr->syntax->ldap_oid;
@@ -2911,11 +3002,6 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
 
        unix_to_nt_time(&now, t);
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        /*
         * The replace operation is unlike the replace and delete cases in that
         * we need to look at every existing link to see whether it is being
@@ -3015,8 +3101,8 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
                                ret = replmd_update_la_val(new_values, old_p->v,
                                                           old_p->dsdb_dn,
                                                           old_p->dsdb_dn,
-                                                          invocation_id,
-                                                          seq_num, seq_num,
+                                                          
&ac->our_invocation_id,
+                                                          ac->seq_num, 
ac->seq_num,
                                                           now, true);
                                if (ret != LDB_SUCCESS) {
                                        talloc_free(tmp_ctx);
@@ -3024,7 +3110,7 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
                                }
 
                                ret = replmd_add_backlink(module, 
replmd_private,
-                                                         schema, 
+                                                         ac->schema,
                                                          msg_dn,
                                                          &old_p->guid, false,
                                                          schema_attr,
@@ -3049,8 +3135,8 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
                        ret = replmd_update_la_val(new_values, old_p->v,
                                                   new_p->dsdb_dn,
                                                   old_p->dsdb_dn,
-                                                  invocation_id,
-                                                  seq_num, seq_num,
+                                                  &ac->our_invocation_id,
+                                                  ac->seq_num, ac->seq_num,
                                                   now, false);
                        if (ret != LDB_SUCCESS) {
                                talloc_free(tmp_ctx);
@@ -3060,7 +3146,7 @@ static int replmd_modify_la_replace(struct ldb_module 
*module,
                        rmd_flags = dsdb_dn_rmd_flags(old_p->dsdb_dn->dn);
                        if ((rmd_flags & DSDB_RMD_FLAG_DELETED) != 0) {
                                ret = replmd_add_backlink(module, 
replmd_private,
-                                                         schema, 
+                                                         ac->schema,
                                                          msg_dn,
                                                          &new_p->guid, true,


-- 
Samba Shared Repository

Reply via email to