dsdb-repl: split out dsdb_repl_resolve_working_schema
authorStefan Metzmacher <metze@samba.org>
Fri, 17 May 2013 21:02:03 +0000 (23:02 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 23 May 2013 10:26:28 +0000 (20:26 +1000)
This can be reused later in other places.

Pair-Programmed-With: Matthieu Patou <mat@matws.net>

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/repl/replicated_objects.c

index 6c96b4111e18843df1d7c903e2533a1e34625ef3..82a46677f2878f23239fe1f5b9589cd346518e9b 100644 (file)
 #include "libcli/auth/libcli_auth.h"
 #include "param/param.h"
 
-/**
- * Multi-pass working schema creation
- * Function will:
- *  - shallow copy initial schema supplied
- *  - create a working schema in multiple passes
- *    until all objects are resolved
- * Working schema is a schema with Attributes, Classes
- * and indexes, but w/o subClassOf, possibleSupperiors etc.
- * It is to be used just us cache for converting attribute values.
- */
-WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
-                                    const struct dsdb_schema *initial_schema,
-                                    const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
-                                    uint32_t object_count,
-                                    const struct drsuapi_DsReplicaObjectListItemEx *first_object,
-                                    const DATA_BLOB *gensec_skey,
-                                    TALLOC_CTX *mem_ctx,
-                                    struct dsdb_schema **_schema_out)
+WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct dsdb_schema_prefixmap *pfm_remote,
+                                       struct dsdb_schema *initial_schema,
+                                       struct dsdb_schema *resulting_schema,
+                                       uint32_t object_count,
+                                       const struct drsuapi_DsReplicaObjectListItemEx *first_object)
 {
        struct schema_list {
                struct schema_list *next, *prev;
                const struct drsuapi_DsReplicaObjectListItemEx *obj;
        };
-
-       WERROR werr;
-       struct dsdb_schema_prefixmap *pfm_remote;
        struct schema_list *schema_list = NULL, *schema_list_item, *schema_list_next_item;
+       WERROR werr;
        struct dsdb_schema *working_schema;
        const struct drsuapi_DsReplicaObjectListItemEx *cur;
+       DATA_BLOB empty_key = data_blob_null;
        int ret, pass_no;
        uint32_t ignore_attids[] = {
                        DRSUAPI_ATTID_auxiliaryClass,
@@ -70,46 +58,37 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                        DRSUAPI_ATTID_INVALID
        };
 
-       /* make a copy of the iniatial_scheam so we don't mess with it */
-       working_schema = dsdb_schema_copy_shallow(mem_ctx, ldb, initial_schema);
-       if (!working_schema) {
-               DEBUG(0,(__location__ ": schema copy failed!\n"));
-               return WERR_NOMEM;
-       }
-
-       /* we are going to need remote prefixMap for decoding */
-       werr = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true,
-                                               mem_ctx, &pfm_remote, NULL);
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s",
-                        win_errstr(werr)));
-               return werr;
-       }
-
        /* create a list of objects yet to be converted */
        for (cur = first_object; cur; cur = cur->next_object) {
                schema_list_item = talloc(mem_ctx, struct schema_list);
+               if (schema_list_item == NULL) {
+                       return WERR_NOMEM;
+               }
+
                schema_list_item->obj = cur;
                DLIST_ADD_END(schema_list, schema_list_item, struct schema_list);
        }
 
        /* resolve objects until all are resolved and in local schema */
        pass_no = 1;
+       working_schema = initial_schema;
 
        while (schema_list) {
                uint32_t converted_obj_count = 0;
                uint32_t failed_obj_count = 0;
-               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
-               for (schema_list_item = schema_list; schema_list_item; schema_list_item=schema_list_next_item) {
+               for (schema_list_item = schema_list;
+                    schema_list_item;
+                    schema_list_item=schema_list_next_item) {
                        struct dsdb_extended_replicated_object object;
 
                        cur = schema_list_item->obj;
 
-                       /* Save the next item, now we have saved out
+                       /*
+                        * Save the next item, now we have saved out
                         * the current one, so we can DLIST_REMOVE it
-                        * safely */
+                        * safely
+                        */
                        schema_list_next_item = schema_list_item->next;
 
                        /*
@@ -117,14 +96,17 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                         * schema we have so far. It's ok if we fail to convert
                         * an object. We should convert more objects on next pass.
                         */
-                       werr = dsdb_convert_object_ex(ldb, working_schema, pfm_remote,
-                                                     cur, gensec_skey,
+                       werr = dsdb_convert_object_ex(ldb, working_schema,
+                                                     pfm_remote,
+                                                     cur, &empty_key,
                                                      ignore_attids,
                                                      0,
-                                                     tmp_ctx, &object);
+                                                     schema_list_item, &object);
                        if (!W_ERROR_IS_OK(werr)) {
-                               DEBUG(4,("debug: Failed to convert schema object %s into ldb msg, will try during next loop\n",
-                                         cur->object.identifier->dn));
+                               DEBUG(4,("debug: Failed to convert schema "
+                                        "object %s into ldb msg, "
+                                        "will try during next loop\n",
+                                        cur->object.identifier->dn));
 
                                failed_obj_count++;
                        } else {
@@ -134,22 +116,23 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                                 * the remote prefixMap
                                 */
                                werr = dsdb_schema_set_el_from_ldb_msg_dups(ldb,
-                                                               working_schema,
+                                                               resulting_schema,
                                                                object.msg,
                                                                true);
                                if (!W_ERROR_IS_OK(werr)) {
-                                       DEBUG(4,("debug: failed to convert object %s into a schema element, will try during next loop: %s\n",
+                                       DEBUG(4,("debug: failed to convert "
+                                                "object %s into a schema element, "
+                                                "will try during next loop: %s\n",
                                                 ldb_dn_get_linearized(object.msg->dn),
                                                 win_errstr(werr)));
                                        failed_obj_count++;
                                } else {
                                        DLIST_REMOVE(schema_list, schema_list_item);
-                                       talloc_free(schema_list_item);
+                                       TALLOC_FREE(schema_list_item);
                                        converted_obj_count++;
                                }
                        }
                }
-               talloc_free(tmp_ctx);
 
                DEBUG(4,("Schema load pass %d: converted %d, %d of %d objects left to be converted.\n",
                         pass_no, converted_obj_count, failed_obj_count, object_count));
@@ -157,7 +140,11 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
 
                /* check if we converted any objects in this pass */
                if (converted_obj_count == 0) {
-                       DEBUG(0,("Can't continue Schema load: didn't manage to convert any objects: all %d remaining of %d objects failed to convert\n", failed_obj_count, object_count));
+                       DEBUG(0,("Can't continue Schema load: "
+                                "didn't manage to convert any objects: "
+                                "all %d remaining of %d objects "
+                                "failed to convert\n",
+                                failed_obj_count, object_count));
                        return WERR_INTERNAL_ERROR;
                }
 
@@ -167,7 +154,61 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                        DEBUG(0,("Failed to create schema-cache indexes!\n"));
                        return WERR_INTERNAL_ERROR;
                }
-       };
+       }
+
+       return WERR_OK;
+}
+
+/**
+ * Multi-pass working schema creation
+ * Function will:
+ *  - shallow copy initial schema supplied
+ *  - create a working schema in multiple passes
+ *    until all objects are resolved
+ * Working schema is a schema with Attributes, Classes
+ * and indexes, but w/o subClassOf, possibleSupperiors etc.
+ * It is to be used just us cache for converting attribute values.
+ */
+WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
+                                    const struct dsdb_schema *initial_schema,
+                                    const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
+                                    uint32_t object_count,
+                                    const struct drsuapi_DsReplicaObjectListItemEx *first_object,
+                                    const DATA_BLOB *gensec_skey,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct dsdb_schema **_schema_out)
+{
+       WERROR werr;
+       struct dsdb_schema_prefixmap *pfm_remote;
+       struct dsdb_schema *working_schema;
+
+       /* make a copy of the iniatial_scheam so we don't mess with it */
+       working_schema = dsdb_schema_copy_shallow(mem_ctx, ldb, initial_schema);
+       if (!working_schema) {
+               DEBUG(0,(__location__ ": schema copy failed!\n"));
+               return WERR_NOMEM;
+       }
+
+       /* we are going to need remote prefixMap for decoding */
+       werr = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true,
+                                               mem_ctx, &pfm_remote, NULL);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s",
+                        win_errstr(werr)));
+               return werr;
+       }
+
+       werr = dsdb_repl_resolve_working_schema(ldb, mem_ctx,
+                                               pfm_remote,
+                                               working_schema,
+                                               working_schema,
+                                               object_count,
+                                               first_object);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0, ("%s: dsdb_repl_resolve_working_schema() failed: %s",
+                         __location__, win_errstr(werr)));
+               return werr;
+       }
 
        *_schema_out = working_schema;