From e24fe5705e3c4d33705ebb584ea2009bb4a1a82c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 May 2013 23:18:55 +0200 Subject: [PATCH] libnet-vampire: make use of dsdb_repl_resolve_working_schema() Pair-Programmed-With: Matthieu Patou Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu May 23 14:18:03 CEST 2013 on sn-devel-104 --- source4/libnet/libnet_vampire.c | 227 +++------------------------------------- 1 file changed, 17 insertions(+), 210 deletions(-) diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 0f20b151abe..9489f0bccb0 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -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, -- 2.11.4.GIT