summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/libnet_vampire.c227
1 files changed, 17 insertions, 210 deletions
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index 0f20b151ab..9489f0bccb 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,