repl_meta_data: Bring replmd_check_upgrade_links() into get_parsed_dns_trusted()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 13 Feb 2017 22:59:13 +0000 (11:59 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 14 Feb 2017 01:20:07 +0000 (02:20 +0100)
This eliminates a lot of duplicate code and allows us to know that we will
have a set of FL2003 style links in the parsed DNs to operate on

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

index 6e041c76e20a527a2f415eee0615b4e1e181489c..8f80ce6b58a289e47ea460382c53692df9fb63b0 100644 (file)
@@ -101,8 +101,18 @@ struct replmd_replicated_request {
        bool isDeleted;
 };
 
+struct parsed_dn {
+       struct dsdb_dn *dsdb_dn;
+       struct GUID guid;
+       struct ldb_val *v;
+};
+
 static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar);
 static int replmd_delete_internals(struct ldb_module *module, struct ldb_request *req, bool re_delete);
+static int replmd_check_upgrade_links(struct ldb_context *ldb,
+                                     struct parsed_dn *dns, uint32_t count,
+                                     struct ldb_message_element *el,
+                                     const char *ldap_oid);
 
 enum urgent_situation {
        REPL_URGENT_ON_CREATE = 1,
@@ -862,12 +872,6 @@ static int replmd_build_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct ds
                               const struct GUID *invocation_id, uint64_t seq_num,
                               uint64_t local_usn, NTTIME nttime, uint32_t version, bool deleted);
 
-struct parsed_dn {
-       struct dsdb_dn *dsdb_dn;
-       struct GUID guid;
-       struct ldb_val *v;
-};
-
 static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
                          struct ldb_message_element *el, struct parsed_dn **pdn,
                          const char *ldap_oid, struct ldb_request *parent);
@@ -2073,6 +2077,9 @@ static int get_parsed_dns(struct ldb_module *module, TALLOC_CTX *mem_ctx,
  * GUID, even though the GUIDs might not be known. That works because we trust
  * the database to give us the elements like that if the
  * replmd_private->sorted_links flag is set.
+ *
+ * We also ensure that the links are in the Functional Level 2003
+ * linked attributes format.
  */
 static int get_parsed_dns_trusted(struct ldb_module *module,
                                  struct replmd_private *replmd_private,
@@ -2083,7 +2090,7 @@ static int get_parsed_dns_trusted(struct ldb_module *module,
                                  struct ldb_request *parent)
 {
        unsigned int i;
-
+       int ret;
        if (el == NULL) {
                *pdn = NULL;
                return LDB_SUCCESS;
@@ -2093,19 +2100,31 @@ static int get_parsed_dns_trusted(struct ldb_module *module,
                /* We need to sort the list. This is the slow old path we want
                   to avoid.
                 */
-               return get_parsed_dns(module, mem_ctx, el, pdn, ldap_oid,
+               ret = get_parsed_dns(module, mem_ctx, el, pdn, ldap_oid,
                                      parent);
-       }
-       /* Here we get a list of 'struct parsed_dns' without the parsing */
-       *pdn = talloc_zero_array(mem_ctx, struct parsed_dn,
-                                el->num_values);
-       if (!*pdn) {
-               ldb_module_oom(module);
-               return LDB_ERR_OPERATIONS_ERROR;
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       } else {
+               /* Here we get a list of 'struct parsed_dns' without the parsing */
+               *pdn = talloc_zero_array(mem_ctx, struct parsed_dn,
+                                        el->num_values);
+               if (!*pdn) {
+                       ldb_module_oom(module);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+
+               for (i = 0; i < el->num_values; i++) {
+                       (*pdn)[i].v = &el->values[i];
+               }
        }
 
-       for (i = 0; i < el->num_values; i++) {
-               (*pdn)[i].v = &el->values[i];
+       ret = replmd_check_upgrade_links(ldb_module_get_ctx(module),
+                                        *pdn, el->num_values,
+                                        el,
+                                        ldap_oid);
+       if (ret != LDB_SUCCESS) {
+               return ret;
        }
 
        return LDB_SUCCESS;
@@ -2208,10 +2227,10 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
 static int replmd_check_upgrade_links(struct ldb_context *ldb,
                                      struct parsed_dn *dns, uint32_t count,
                                      struct ldb_message_element *el,
-                                     const struct GUID *invocation_id,
                                      const char *ldap_oid)
 {
        uint32_t i;
+       const struct GUID *invocation_id = NULL;
        for (i=0; i<count; i++) {
                NTSTATUS status;
                uint32_t version;
@@ -2243,6 +2262,14 @@ static int replmd_check_upgrade_links(struct ldb_context *ldb,
                        continue;
                }
 
+               if (invocation_id == NULL) {
+                       invocation_id = samdb_ntds_invocation_id(ldb);
+                       if (invocation_id == NULL) {
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+               }
+
+
                /* it's an old one that needs upgrading */
                ret = replmd_update_la_val(el->values, dns[i].v,
                                           dns[i].dsdb_dn, dns[i].dsdb_dn,
@@ -2381,9 +2408,14 @@ static int replmd_modify_la_add(struct ldb_module *module,
        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
@@ -2407,20 +2439,6 @@ static int replmd_modify_la_add(struct ldb_module *module,
                return ret;
        }
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               talloc_free(tmp_ctx);
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = replmd_check_upgrade_links(ldb, old_dns, old_num_values,
-                                        old_el, invocation_id,
-                                        schema_attr->syntax->ldap_oid);
-       if (ret != LDB_SUCCESS) {
-               talloc_free(tmp_ctx);
-               return ret;
-       }
-
        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. "
@@ -2597,16 +2615,21 @@ static int replmd_modify_la_delete(struct ldb_module *module,
        struct parsed_dn *dns, *old_dns;
        TALLOC_CTX *tmp_ctx = NULL;
        int ret;
-       const struct GUID *invocation_id;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        struct ldb_control *vanish_links_ctrl = NULL;
        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) {
@@ -2637,20 +2660,6 @@ static int replmd_modify_la_delete(struct ldb_module *module,
                return ret;
        }
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               talloc_free(tmp_ctx);
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = replmd_check_upgrade_links(ldb, old_dns, old_el->num_values,
-                                        old_el, invocation_id,
-                                        schema_attr->syntax->ldap_oid);
-       if (ret != LDB_SUCCESS) {
-               talloc_free(tmp_ctx);
-               return ret;
-       }
-
        if (parent) {
                vanish_links_ctrl = ldb_request_get_control(parent, DSDB_CONTROL_REPLMD_VANISH_LINKS);
                if (vanish_links_ctrl) {
@@ -2863,6 +2872,11 @@ 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
@@ -2908,13 +2922,8 @@ static int replmd_modify_la_replace(struct ldb_module *module,
                return ret;
        }
 
-       invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!invocation_id) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        ret = replmd_check_upgrade_links(ldb, old_dns, old_num_values,
-                                        old_el, invocation_id, ldap_oid);
+                                        old_el, ldap_oid);
        if (ret != LDB_SUCCESS) {
                talloc_free(tmp_ctx);
                return ret;
@@ -6556,7 +6565,6 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
        struct GUID guid = GUID_zero();
        NTSTATUS ntstatus;
        bool active = (la->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)?true:false;
-       const struct GUID *our_invocation_id;
 
        enum deletion_state deletion_state = OBJECT_NOT_DELETED;
        enum deletion_state target_deletion_state = OBJECT_NOT_DELETED;
@@ -6672,22 +6680,6 @@ linked_attributes[0]:
                return ret;
        }
 
-       /* get our invocationId */
-       our_invocation_id = samdb_ntds_invocation_id(ldb);
-       if (!our_invocation_id) {
-               ldb_debug_set(ldb, LDB_DEBUG_ERROR, __location__ ": unable to find invocationId\n");
-               talloc_free(tmp_ctx);
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = replmd_check_upgrade_links(ldb, pdn_list, old_el->num_values,
-                                        old_el, our_invocation_id,
-                                        attr->syntax->ldap_oid);
-       if (ret != LDB_SUCCESS) {
-               talloc_free(tmp_ctx);
-               return ret;
-       }
-
        status = dsdb_dn_la_from_blob(ldb, attr, schema, tmp_ctx, la->value.blob, &dsdb_dn);
        if (!W_ERROR_IS_OK(status)) {
                ldb_asprintf_errstring(ldb, "Failed to parsed linked attribute blob for %s on %s - %s\n",