The branch, master has been updated
       via  c3aa880 repl_meta_data: Initialise parent_dn to NULL
       via  cdb42ea repl_meta_data: Explain that we do not truncate the DN at 
present
       via  68de8c6 repl_meta_data: Use replmd_make_prefix_child_dn() in 
replmd_conflict_dn()
       via  5364f8d repl_meta_data: Split replmd_make_deleted_child_dn() into a 
helper function
       via  5eff04e repl_meta_data: Move creation of deleted DN into helper: 
replmd_make_deleted_child_dn()
       via  b838c14 repl_meta_data: Avoid printf() and use binary direct RDN 
creation for deleted objects
      from  3e0cc6e s3-auth: remove leftover prototype from auth_domain.

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


- Log -----------------------------------------------------------------
commit c3aa8809e19bd97c0891d7c7ed4499f8a6babfb1
Author: Andrew Bartlett <[email protected]>
Date:   Tue Oct 17 12:00:27 2017 +1300

    repl_meta_data: Initialise parent_dn to NULL
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    
    Autobuild-User(master): Garming Sam <[email protected]>
    Autobuild-Date(master): Mon Oct 30 04:16:42 CET 2017 on sn-devel-144

commit cdb42eae898011121415f36cff27aeb8b16c9feb
Author: Andrew Bartlett <[email protected]>
Date:   Tue Oct 17 11:36:03 2017 +1300

    repl_meta_data: Explain that we do not truncate the DN at present
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit 68de8c66c741457563b5cd6aa4eb75c10fd006ef
Author: Andrew Bartlett <[email protected]>
Date:   Tue Oct 17 11:28:45 2017 +1300

    repl_meta_data: Use replmd_make_prefix_child_dn() in replmd_conflict_dn()
    
    Now both routines avoid the escape/unescape implicit in 
ldb_dn_add_child_fmt()
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit 5364f8d3d5a9a9fde6ca0ed88c9943dbfb02f699
Author: Andrew Bartlett <[email protected]>
Date:   Tue Oct 17 11:27:49 2017 +1300

    repl_meta_data: Split replmd_make_deleted_child_dn() into a helper function
    
    This will allow it to be used in common with replmd_conflict_dn()
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit 5eff04e9b8b6fc1c8b6eed25f916f83ed8b1d97a
Author: Andrew Bartlett <[email protected]>
Date:   Mon Oct 16 17:27:59 2017 +1300

    repl_meta_data: Move creation of deleted DN into helper: 
replmd_make_deleted_child_dn()
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit b838c14b1bf1117ab4ce6bdd44ccb6b8effd13bd
Author: Andrew Bartlett <[email protected]>
Date:   Mon Oct 16 16:02:57 2017 +1300

    repl_meta_data: Avoid printf() and use binary direct RDN creation for 
deleted objects
    
    This makes it clearer that we are just replacing the RDN and ensures we do 
not
    somehow create multiple components inside ldb_dn_add_child_fmt().
    
    We also avoid an escape/un-escape round-trip.
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 174 ++++++++++++++++++++----
 1 file changed, 147 insertions(+), 27 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 
b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index c443102..9a24349 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -127,6 +127,13 @@ static int replmd_set_la_val(TALLOC_CTX *mem_ctx, struct 
ldb_val *v, struct dsdb
                             uint64_t usn, uint64_t local_usn, NTTIME nttime,
                             uint32_t version, bool deleted);
 
+static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
+                                       struct ldb_context *ldb,
+                                       struct ldb_dn *dn,
+                                       const char *rdn_name,
+                                       const struct ldb_val *rdn_value,
+                                       struct GUID guid);
+
 enum urgent_situation {
        REPL_URGENT_ON_CREATE = 1,
        REPL_URGENT_ON_UPDATE = 2,
@@ -3844,7 +3851,7 @@ static int replmd_delete_internals(struct ldb_module 
*module, struct ldb_request
 {
        int ret = LDB_ERR_OTHER;
        bool retb, disallow_move_on_delete;
-       struct ldb_dn *old_dn, *new_dn;
+       struct ldb_dn *old_dn = NULL, *new_dn = NULL;
        const char *rdn_name;
        const struct ldb_val *rdn_value, *new_rdn_value;
        struct GUID guid;
@@ -4056,17 +4063,16 @@ static int replmd_delete_internals(struct ldb_module 
*module, struct ldb_request
        guid = samdb_result_guid(old_msg, "objectGUID");
 
        if (deletion_state == OBJECT_NOT_DELETED) {
-               /* Add a formatted child */
-               retb = ldb_dn_add_child_fmt(new_dn, "%s=%s\\0ADEL:%s",
-                                           rdn_name,
-                                           ldb_dn_escape_value(tmp_ctx, 
*rdn_value),
-                                           GUID_string(tmp_ctx, &guid));
-               if (!retb) {
-                       ldb_asprintf_errstring(ldb, __location__
-                                              ": Unable to add a formatted 
child to dn: %s",
-                                              ldb_dn_get_linearized(new_dn));
+
+               ret = replmd_make_deleted_child_dn(tmp_ctx,
+                                                  ldb,
+                                                  new_dn,
+                                                  rdn_name, rdn_value,
+                                                  guid);
+
+               if (ret != LDB_SUCCESS) {
                        talloc_free(tmp_ctx);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ret;
                }
 
                ret = ldb_msg_add_string(msg, "isDeleted", "TRUE");
@@ -4501,13 +4507,103 @@ static bool 
replmd_replPropertyMetaData1_new_should_be_taken(uint32_t dsdb_repl_
 
 
 /*
+  form a DN for a deleted (DEL:) or conflict (CNF:) DN
+ */
+static int replmd_make_prefix_child_dn(TALLOC_CTX *tmp_ctx,
+                                      struct ldb_context *ldb,
+                                      struct ldb_dn *dn,
+                                      const char *four_char_prefix,
+                                      const char *rdn_name,
+                                      const struct ldb_val *rdn_value,
+                                      struct GUID guid)
+{
+       struct ldb_val deleted_child_rdn_val;
+       struct GUID_txt_buf guid_str;
+       bool retb;
+
+       GUID_buf_string(&guid, &guid_str);
+
+       retb = ldb_dn_add_child_fmt(dn, "X=Y");
+       if (!retb) {
+               ldb_asprintf_errstring(ldb, __location__
+                                      ": Unable to add a formatted child to 
dn: %s",
+                                      ldb_dn_get_linearized(dn));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       /*
+        * TODO: Per MS-ADTS 3.1.1.5.5 Delete Operation
+        * we should truncate this value to ensure the RDN is not more than 255 
chars.
+        *
+        * However we MS-ADTS 3.1.1.5.1.2 Naming Constraints indicates that:
+        *
+        * "Naming constraints are not enforced for replicated
+        * updates." so this is safe and we don't have to work out not
+        * splitting a UTF8 char right now.
+        */
+       deleted_child_rdn_val = ldb_val_dup(tmp_ctx, rdn_value);
+
+       /*
+        * sizeof(guid_str.buf) will always be longer than
+        * strlen(guid_str.buf) but we allocate using this and
+        * waste the trailing bytes to avoid scaring folks
+        * with memcpy() using strlen() below
+        */
+
+       deleted_child_rdn_val.data
+               = talloc_realloc(tmp_ctx, deleted_child_rdn_val.data,
+                                uint8_t,
+                                rdn_value->length + 5
+                                + sizeof(guid_str.buf));
+       if (!deleted_child_rdn_val.data) {
+               ldb_asprintf_errstring(ldb, __location__
+                                      ": Unable to add a formatted child to 
dn: %s",
+                                      ldb_dn_get_linearized(dn));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       deleted_child_rdn_val.length =
+               rdn_value->length + 5
+               + strlen(guid_str.buf);
+
+       SMB_ASSERT(deleted_child_rdn_val.length <
+                  talloc_get_size(deleted_child_rdn_val.data));
+
+       /*
+        * talloc won't allocate more than 256MB so we can't
+        * overflow but just to be sure
+        */
+       if (deleted_child_rdn_val.length < rdn_value->length) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       deleted_child_rdn_val.data[rdn_value->length] = 0x0a;
+       memcpy(&deleted_child_rdn_val.data[rdn_value->length + 1],
+              four_char_prefix, 4);
+       memcpy(&deleted_child_rdn_val.data[rdn_value->length + 5],
+              guid_str.buf,
+              sizeof(guid_str.buf));
+
+       /* Now set the value into the RDN, without parsing it */
+       ldb_dn_set_component(dn, 0, rdn_name,
+                            deleted_child_rdn_val);
+
+       return LDB_SUCCESS;
+}
+
+
+/*
   form a conflict DN
  */
-static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx, struct ldb_dn 
*dn, struct GUID *guid)
+static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX *mem_ctx,
+                                        struct ldb_context *ldb,
+                                        struct ldb_dn *dn,
+                                        struct GUID *guid)
 {
        const struct ldb_val *rdn_val;
        const char *rdn_name;
        struct ldb_dn *new_dn;
+       int ret;
 
        rdn_val = ldb_dn_get_rdn_val(dn);
        rdn_name = ldb_dn_get_rdn_name(dn);
@@ -4515,25 +4611,41 @@ static struct ldb_dn *replmd_conflict_dn(TALLOC_CTX 
*mem_ctx, struct ldb_dn *dn,
                return NULL;
        }
 
-       new_dn = ldb_dn_copy(mem_ctx, dn);
+       new_dn = ldb_dn_get_parent(mem_ctx, dn);
        if (!new_dn) {
                return NULL;
        }
 
-       if (!ldb_dn_remove_child_components(new_dn, 1)) {
-               return NULL;
-       }
-
-       if (!ldb_dn_add_child_fmt(new_dn, "%s=%s\\0ACNF:%s",
-                                 rdn_name,
-                                 ldb_dn_escape_value(new_dn, *rdn_val),
-                                 GUID_string(new_dn, guid))) {
+       ret = replmd_make_prefix_child_dn(mem_ctx,
+                                         ldb, new_dn,
+                                         "CNF:",
+                                         rdn_name,
+                                         rdn_val,
+                                         *guid);
+       if (ret != LDB_SUCCESS) {
                return NULL;
        }
-
        return new_dn;
 }
 
+/*
+  form a deleted DN
+ */
+static int replmd_make_deleted_child_dn(TALLOC_CTX *tmp_ctx,
+                                       struct ldb_context *ldb,
+                                       struct ldb_dn *dn,
+                                       const char *rdn_name,
+                                       const struct ldb_val *rdn_value,
+                                       struct GUID guid)
+{
+       return replmd_make_prefix_child_dn(tmp_ctx,
+                                          ldb, dn,
+                                          "DEL:",
+                                          rdn_name,
+                                          rdn_value,
+                                          guid);
+}
+
 
 /*
   perform a modify operation which sets the rDN and name attributes to
@@ -4816,7 +4928,9 @@ static int replmd_op_possible_conflict_callback(struct 
ldb_request *req, struct
                                 ldb_dn_get_linearized(conflict_dn)));
                        goto failed;
                }
-               new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+               new_dn = replmd_conflict_dn(req,
+                                           ldb_module_get_ctx(ar->module),
+                                           conflict_dn, &guid);
                if (new_dn == NULL) {
                        DEBUG(0,(__location__ ": Failed to form conflict DN for 
%s\n",
                                 ldb_dn_get_linearized(conflict_dn)));
@@ -4841,7 +4955,9 @@ static int replmd_op_possible_conflict_callback(struct 
ldb_request *req, struct
                        goto failed;
                }
 
-               new_dn = replmd_conflict_dn(req, conflict_dn, &guid);
+               new_dn = replmd_conflict_dn(req,
+                                           ldb_module_get_ctx(ar->module),
+                                           conflict_dn, &guid);
                if (new_dn == NULL) {
                        DEBUG(0,(__location__ ": Failed to form conflict DN for 
%s\n",
                                 ldb_dn_get_linearized(conflict_dn)));
@@ -5140,7 +5256,7 @@ static int 
replmd_replicated_apply_search_for_parent_callback(struct ldb_request
        {
                struct ldb_message *parent_msg = ares->message;
                struct ldb_message *msg = 
ar->objs->objects[ar->index_current].msg;
-               struct ldb_dn *parent_dn;
+               struct ldb_dn *parent_dn = NULL;
                int comp_num;
 
                if (!ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")
@@ -5443,7 +5559,9 @@ static int replmd_replicated_handle_rename(struct 
replmd_replicated_request *ar,
 
        if (rename_incoming_record) {
 
-               new_dn = replmd_conflict_dn(msg, msg->dn,
+               new_dn = replmd_conflict_dn(msg,
+                                           ldb_module_get_ctx(ar->module),
+                                           msg->dn,
                                            
&ar->objs->objects[ar->index_current].object_guid);
                if (new_dn == NULL) {
                        ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
@@ -5479,7 +5597,9 @@ static int replmd_replicated_handle_rename(struct 
replmd_replicated_request *ar,
                goto failed;
        }
 
-       new_dn = replmd_conflict_dn(tmp_ctx, conflict_dn, &guid);
+       new_dn = replmd_conflict_dn(tmp_ctx,
+                                   ldb_module_get_ctx(ar->module),
+                                   conflict_dn, &guid);
        if (new_dn == NULL) {
                DEBUG(0,(__location__ ": Failed to form conflict DN for %s\n",
                         ldb_dn_get_linearized(conflict_dn)));


-- 
Samba Shared Repository

Reply via email to