libnet-vampire: make use of dsdb_repl_resolve_working_schema()
authorStefan Metzmacher <metze@samba.org>
Fri, 17 May 2013 21:18:55 +0000 (23:18 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 23 May 2013 12:18:03 +0000 (14:18 +0200)
Pair-Programmed-With: Matthieu Patou <mat@matws.net>

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Thu May 23 14:18:03 CEST 2013 on sn-devel-104

source4/libnet/libnet_vampire.c

index 0f20b151abe2cc4f4c3a3cb7fc41585d0aa11231..9489f0bccb0151f24bbbfcef528733314fe035e6 100644 (file)
@@ -216,94 +216,15 @@ NTSTATUS libnet_vampire_cb_check_options(void *private_data,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS libnet_vampire_merge_schema(struct ldb_context *ldb,
-                                           struct dsdb_schema *dest_schema,
-                                           const struct dsdb_schema *ref_schema)
-{
-       const struct dsdb_class *cur_class = NULL;
-       const struct dsdb_attribute *cur_attr = NULL;
-       int ret;
-
-       for (cur_class = ref_schema->classes;
-            cur_class;
-            cur_class = cur_class->next)
-       {
-               const struct dsdb_class *tmp1;
-               struct dsdb_class *tmp2;
-
-               tmp1 = dsdb_class_by_governsID_id(dest_schema,
-                                                 cur_class->governsID_id);
-               if (tmp1 != NULL) {
-                       continue;
-               }
-
-               /*
-                * Do a shallow copy so that original next and prev are
-                * not modified, we don't need to do a deep copy
-                * as the rest won't be modified and this is for
-                * a short lived object.
-                */
-               tmp2 = talloc(dest_schema->classes, struct dsdb_class);
-               if (tmp2 == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               *tmp2 = *cur_class;
-               DLIST_ADD(dest_schema->classes, tmp2);
-       }
-
-       for (cur_attr = ref_schema->attributes;
-            cur_attr;
-            cur_attr = cur_attr->next)
-       {
-               const struct dsdb_attribute *tmp1;
-               struct dsdb_attribute *tmp2;
-
-               tmp1 = dsdb_attribute_by_attributeID_id(dest_schema,
-                                               cur_attr->attributeID_id);
-               if (tmp1 != NULL) {
-                       continue;
-               }
-
-               /*
-                * Do a shallow copy so that original next and prev are
-                * not modified, we don't need to do a deep copy
-                * as the rest won't be modified and this is for
-                * a short lived object.
-                */
-               tmp2 = talloc(dest_schema->attributes, struct dsdb_attribute);
-               if (tmp2 == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               *tmp2 = *cur_attr;
-               DLIST_ADD(dest_schema->attributes, tmp2);
-       }
-
-       ret = dsdb_setup_sorted_accessors(ldb, dest_schema);
-       if (LDB_SUCCESS != ret) {
-               DEBUG(0,("Failed to add new attribute to reference schema!\n"));
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s,
                                               const struct libnet_BecomeDC_StoreChunk *c)
 {
-       struct schema_list {
-               struct schema_list *next, *prev;
-               const struct drsuapi_DsReplicaObjectListItemEx *obj;
-       };
-
        WERROR status;
        struct dsdb_schema_prefixmap *pfm_remote;
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
-       struct schema_list *schema_list = NULL, *schema_list_item, *schema_list_next_item;
-       struct dsdb_schema *working_schema;
        struct dsdb_schema *provision_schema;
        uint32_t object_count = 0;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
-       const struct drsuapi_DsReplicaObjectListItemEx *cur;
        uint32_t linked_attributes_count;
        struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
        const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
@@ -314,17 +235,10 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
        struct ldb_message *msg;
        struct ldb_message_element *prefixMap_el;
        uint32_t i;
-       int ret, pass_no;
+       int ret;
        bool ok;
        uint64_t seq_num;
-       uint32_t ignore_attids[] = {
-                       DRSUAPI_ATTID_auxiliaryClass,
-                       DRSUAPI_ATTID_mayContain,
-                       DRSUAPI_ATTID_mustContain,
-                       DRSUAPI_ATTID_possSuperiors,
-                       DRSUAPI_ATTID_systemPossSuperiors,
-                       DRSUAPI_ATTID_INVALID
-       };
+       uint32_t cycle_before_switching;
 
        DEBUG(0,("Analyze and apply schema objects\n"));
 
@@ -372,7 +286,6 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
                return NT_STATUS_FOOBAR;
        }
 
-
        status = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true,
                                                  s, &pfm_remote, NULL);
        if (!W_ERROR_IS_OK(status)) {
@@ -414,131 +327,25 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
                talloc_free(schema_ldb);
        }
 
-       /* create a list of objects yet to be converted */
-       for (cur = first_object; cur; cur = cur->next_object) {
-               schema_list_item = talloc(s, struct schema_list);
-               schema_list_item->obj = cur;
-               DLIST_ADD_END(schema_list, schema_list_item, struct schema_list);
+       cycle_before_switching = lpcfg_parm_long(s->lp_ctx, NULL,
+                                                "become dc",
+                                                "schema convert retrial", 1);
+
+       status = dsdb_repl_resolve_working_schema(s->ldb, s,
+                                                 pfm_remote,
+                                                 cycle_before_switching,
+                                                 provision_schema,
+                                                 s->self_made_schema,
+                                                 object_count,
+                                                 first_object);
+       if (!W_ERROR_IS_OK(status)) {
+               DEBUG(0, ("%s: dsdb_repl_resolve_working_schema() failed: %s",
+                         __location__, win_errstr(status)));
+               return werror_to_ntstatus(status);
        }
 
-       /* resolve objects until all are resolved and in local schema */
-       pass_no = 1;
-       working_schema = provision_schema;
-
-       while (schema_list) {
-               uint32_t converted_obj_count = 0;
-               uint32_t failed_obj_count = 0;
-               int cycle_before_switching = 0;
-               TALLOC_CTX *tmp_ctx = talloc_new(s);
-               NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
-
-               if (s->self_made_schema != working_schema) {
-                       /*
-                        * If the selfmade schema is not the schema used to
-                        * translate and validate replicated object,
-                        * Which means that we are using the bootstrap schema
-                        * Then we add attributes and classes that were already
-                        * translated to the working schema, the idea is that
-                        * we might need to add new attributes and classes
-                        * to be able to translate critical replicated objects
-                        * and without that we wouldn't be able to translate them
-                        */
-                       NTSTATUS nt_status;
-
-                       nt_status = libnet_vampire_merge_schema(s->ldb,
-                                                       working_schema,
-                                                       s->self_made_schema);
-                       if (!NT_STATUS_IS_OK(nt_status)) {
-                               return nt_status;
-                       }
-               }
-
-               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
-                        * the current one, so we can DLIST_REMOVE it
-                        * safely */
-                       schema_list_next_item = schema_list_item->next;
-
-                       /*
-                        * Convert the objects into LDB messages using the
-                        * schema we have so far. It's ok if we fail to convert
-                        * an object. We should convert more objects on next pass.
-                        */
-                       status = dsdb_convert_object_ex(s->ldb, working_schema, pfm_remote,
-                                                       cur, c->gensec_skey,
-                                                       ignore_attids,
-                                                       0,
-                                                       tmp_ctx, &object);
-                       if (!W_ERROR_IS_OK(status)) {
-                               DEBUG(1,("Warning: Failed to convert schema object %s into ldb msg\n",
-                                        cur->object.identifier->dn));
-
-                               failed_obj_count++;
-                       } else {
-                               /*
-                                * Convert the schema from ldb_message format
-                                * (OIDs as OID strings) into schema, using
-                                * the remote prefixMap
-                                *
-                                * It's not likely, but possible to get the
-                                * same object twice and we should keep
-                                * the last instance.
-                                */
-                               status = dsdb_schema_set_el_from_ldb_msg_dups(s->ldb,
-                                                               s->self_made_schema,
-                                                               object.msg, true);
-                               if (!W_ERROR_IS_OK(status)) {
-                                       DEBUG(1,("Warning: failed to convert object %s into a schema element: %s\n",
-                                                ldb_dn_get_linearized(object.msg->dn),
-                                                win_errstr(status)));
-                                       failed_obj_count++;
-                               } else {
-                                       DEBUG(8,("Converted object %s into a schema element\n",
-                                                ldb_dn_get_linearized(object.msg->dn)));
-                                       DLIST_REMOVE(schema_list, 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));
-
-               /* 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));
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-
-               /*
-                * Don't try to load the schema if there is missing object
-                * _and_ we are on the first pass as some critical objects
-                * might be missing.
-                */
-               cycle_before_switching = lpcfg_parm_int(s->lp_ctx, NULL,
-                                                       "become dc",
-                                                       "schema convert retrial", 1);
-               if (failed_obj_count == 0 || pass_no > cycle_before_switching) {
-                       /* prepare for another cycle */
-                       working_schema = s->self_made_schema;
-
-                       ret = dsdb_setup_sorted_accessors(s->ldb, working_schema);
-                       if (LDB_SUCCESS != ret) {
-                               DEBUG(0,("Failed to create schema-cache indexes!\n"));
-                               return NT_STATUS_INTERNAL_ERROR;
-                       }
-               }
-               pass_no++;
-       };
-
        /* free temp objects for 1st conversion phase */
        talloc_unlink(s, provision_schema);
-       TALLOC_FREE(schema_list);
 
        /*
         * attach the schema we just brought over DRS to the ldb,