X-Git-Url: http://git.samba.org/?p=amitay%2Fsamba.git;a=blobdiff_plain;f=source4%2Fdsdb%2Fschema%2Fschema_set.c;h=8cb06bb70e834d84c226440341e94d0c9bd20746;hp=305a0d94f320334c46c6f0763baf1439c640b6cc;hb=b206a365eade7fbd2defddbadf14ca293409ede3;hpb=5a54b204c3d2b6c9282cdd459a3d1030fde48926 diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 305a0d94f32..8cb06bb70e8 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -1,38 +1,44 @@ -/* - Unix SMB/CIFS mplementation. +/* + Unix SMB/CIFS implementation. DSDB schema header - + Copyright (C) Stefan Metzmacher 2006-2007 Copyright (C) Andrew Bartlett 2006-2008 + Copyright (C) Matthieu Patou 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ #include "includes.h" #include "lib/util/dlinklist.h" #include "dsdb/samdb/samdb.h" -#include "lib/ldb/include/ldb_module.h" +#include #include "param/param.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_misc.h" #include "lib/util/tsort.h" +/* change this when we change something in our schema code that + * requires a re-index of the database + */ +#define SAMDB_INDEXING_VERSION "2" + /* override the name to attribute handler function */ -const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, +const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, void *private_data, const char *name) { @@ -65,7 +71,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem mem_ctx = talloc_new(ldb); if (!mem_ctx) { - return LDB_ERR_OPERATIONS_ERROR; + return ldb_oom(ldb); } msg = ldb_msg_new(mem_ctx); @@ -83,7 +89,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem ldb_oom(ldb); goto op_error; } - msg_idx->dn = ldb_dn_new(msg, ldb, "@INDEXLIST"); + msg_idx->dn = ldb_dn_new(msg_idx, ldb, "@INDEXLIST"); if (!msg_idx->dn) { ldb_oom(ldb); goto op_error; @@ -94,19 +100,28 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem goto op_error; } + + ret = ldb_msg_add_string(msg_idx, "@IDXVERSION", SAMDB_INDEXING_VERSION); + if (ret != LDB_SUCCESS) { + goto op_error; + } + for (attr = schema->attributes; attr; attr = attr->next) { const char *syntax = attr->syntax->ldb_syntax; - + if (!syntax) { syntax = attr->syntax->ldap_oid; } - /* Write out a rough approximation of the schema as an @ATTRIBUTES value, for bootstrapping */ + /* + * Write out a rough approximation of the schema + * as an @ATTRIBUTES value, for bootstrapping + */ if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER"); } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE"); - } + } if (ret != LDB_SUCCESS) { break; } @@ -124,8 +139,12 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Try to avoid churning the attributes too much - we only want to do this if they have changed */ - ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg->dn)); + /* + * Try to avoid churning the attributes too much, + * we only want to do this if they have changed + */ + ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, + NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = ldb_add(ldb, msg); } else if (ret != LDB_SUCCESS) { @@ -135,11 +154,16 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem ret = LDB_SUCCESS; /* Annoyingly added to our search results */ ldb_msg_remove_attr(res->msgs[0], "distinguishedName"); - - mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg); + + ret = ldb_msg_difference(ldb, mem_ctx, + res->msgs[0], msg, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } + talloc_free(mod_msg); } if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { @@ -151,9 +175,10 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Now write out the indexs, as found in the schema (if they have changed) */ + /* Now write out the indexes, as found in the schema (if they have changed) */ - ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, "dn=%s", ldb_dn_get_linearized(msg_idx->dn)); + ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, + NULL, NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { ret = ldb_add(ldb, msg_idx); } else if (ret != LDB_SUCCESS) { @@ -164,10 +189,15 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem /* Annoyingly added to our search results */ ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName"); - mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx); + ret = ldb_msg_difference(ldb, mem_ctx, + res_idx->msgs[0], msg_idx, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } + talloc_free(mod_msg); } if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS || ret == LDB_ERR_INVALID_DN_SYNTAX) { /* We might be on a read-only DB */ @@ -178,7 +208,45 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem op_error: talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_operr(ldb); +} + + +/* + create extra attribute shortcuts + */ +static void dsdb_setup_attribute_shortcuts(struct ldb_context *ldb, struct dsdb_schema *schema) +{ + struct dsdb_attribute *attribute; + + /* setup fast access to one_way_link and DN format */ + for (attribute=schema->attributes; attribute; attribute=attribute->next) { + attribute->dn_format = dsdb_dn_oid_to_format(attribute->syntax->ldap_oid); + + if (attribute->dn_format == DSDB_INVALID_DN) { + attribute->one_way_link = false; + continue; + } + + /* these are not considered to be one way links for + the purpose of DN link fixups */ + if (ldb_attr_cmp("distinguishedName", attribute->lDAPDisplayName) == 0 || + ldb_attr_cmp("objectCategory", attribute->lDAPDisplayName) == 0) { + attribute->one_way_link = false; + continue; + } + + if (attribute->linkID == 0) { + attribute->one_way_link = true; + continue; + } + /* handle attributes with a linkID but no backlink */ + if (dsdb_attribute_by_linkID(schema, attribute->linkID) == NULL) { + attribute->one_way_link = true; + continue; + } + attribute->one_way_link = false; + } } static int uint32_cmp(uint32_t c1, uint32_t c2) @@ -212,6 +280,10 @@ static int dsdb_compare_attribute_by_attributeID_id(struct dsdb_attribute **a1, { return uint32_cmp((*a1)->attributeID_id, (*a2)->attributeID_id); } +static int dsdb_compare_attribute_by_msDS_IntId(struct dsdb_attribute **a1, struct dsdb_attribute **a2) +{ + return uint32_cmp((*a1)->msDS_IntId, (*a2)->msDS_IntId); +} static int dsdb_compare_attribute_by_attributeID_oid(struct dsdb_attribute **a1, struct dsdb_attribute **a2) { return strcasecmp((*a1)->attributeID_oid, (*a2)->attributeID_oid); @@ -221,20 +293,38 @@ static int dsdb_compare_attribute_by_linkID(struct dsdb_attribute **a1, struct d return uint32_cmp((*a1)->linkID, (*a2)->linkID); } +/** + * Clean up Classes and Attributes accessor arrays + */ +static void dsdb_sorted_accessors_free(struct dsdb_schema *schema) +{ + /* free classes accessors */ + TALLOC_FREE(schema->classes_by_lDAPDisplayName); + TALLOC_FREE(schema->classes_by_governsID_id); + TALLOC_FREE(schema->classes_by_governsID_oid); + TALLOC_FREE(schema->classes_by_cn); + /* free attribute accessors */ + TALLOC_FREE(schema->attributes_by_lDAPDisplayName); + TALLOC_FREE(schema->attributes_by_attributeID_id); + TALLOC_FREE(schema->attributes_by_msDS_IntId); + TALLOC_FREE(schema->attributes_by_attributeID_oid); + TALLOC_FREE(schema->attributes_by_linkID); +} + /* create the sorted accessor arrays for the schema */ -static int dsdb_setup_sorted_accessors(struct ldb_context *ldb, - struct dsdb_schema *schema) +int dsdb_setup_sorted_accessors(struct ldb_context *ldb, + struct dsdb_schema *schema) { struct dsdb_class *cur; struct dsdb_attribute *a; unsigned int i; + unsigned int num_int_id; + int ret; - talloc_free(schema->classes_by_lDAPDisplayName); - talloc_free(schema->classes_by_governsID_id); - talloc_free(schema->classes_by_governsID_oid); - talloc_free(schema->classes_by_cn); + /* free all caches */ + dsdb_sorted_accessors_free(schema); /* count the classes */ for (i=0, cur=schema->classes; cur; i++, cur=cur->next) /* noop */ ; @@ -266,80 +356,76 @@ static int dsdb_setup_sorted_accessors(struct ldb_context *ldb, TYPESAFE_QSORT(schema->classes_by_cn, schema->num_classes, dsdb_compare_class_by_cn); /* now build the attribute accessor arrays */ - talloc_free(schema->attributes_by_lDAPDisplayName); - talloc_free(schema->attributes_by_attributeID_id); - talloc_free(schema->attributes_by_attributeID_oid); - talloc_free(schema->attributes_by_linkID); - /* count the attributes */ - for (i=0, a=schema->attributes; a; i++, a=a->next) /* noop */ ; + /* count the attributes + * and attributes with msDS-IntId set */ + num_int_id = 0; + for (i=0, a=schema->attributes; a; i++, a=a->next) { + if (a->msDS_IntId != 0) { + num_int_id++; + } + } schema->num_attributes = i; + schema->num_int_id_attr = num_int_id; /* setup attributes_by_* */ schema->attributes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_attributeID_id = talloc_array(schema, struct dsdb_attribute *, i); + schema->attributes_by_msDS_IntId = talloc_array(schema, + struct dsdb_attribute *, num_int_id); schema->attributes_by_attributeID_oid = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_linkID = talloc_array(schema, struct dsdb_attribute *, i); if (schema->attributes_by_lDAPDisplayName == NULL || schema->attributes_by_attributeID_id == NULL || + schema->attributes_by_msDS_IntId == NULL || schema->attributes_by_attributeID_oid == NULL || schema->attributes_by_linkID == NULL) { goto failed; } + num_int_id = 0; for (i=0, a=schema->attributes; a; i++, a=a->next) { schema->attributes_by_lDAPDisplayName[i] = a; schema->attributes_by_attributeID_id[i] = a; schema->attributes_by_attributeID_oid[i] = a; schema->attributes_by_linkID[i] = a; + /* append attr-by-msDS-IntId values */ + if (a->msDS_IntId != 0) { + schema->attributes_by_msDS_IntId[num_int_id] = a; + num_int_id++; + } } + SMB_ASSERT(num_int_id == schema->num_int_id_attr); /* sort the arrays */ TYPESAFE_QSORT(schema->attributes_by_lDAPDisplayName, schema->num_attributes, dsdb_compare_attribute_by_lDAPDisplayName); TYPESAFE_QSORT(schema->attributes_by_attributeID_id, schema->num_attributes, dsdb_compare_attribute_by_attributeID_id); + TYPESAFE_QSORT(schema->attributes_by_msDS_IntId, schema->num_int_id_attr, dsdb_compare_attribute_by_msDS_IntId); TYPESAFE_QSORT(schema->attributes_by_attributeID_oid, schema->num_attributes, dsdb_compare_attribute_by_attributeID_oid); TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID); - return LDB_SUCCESS; - -failed: - schema->classes_by_lDAPDisplayName = NULL; - schema->classes_by_governsID_id = NULL; - schema->classes_by_governsID_oid = NULL; - schema->classes_by_cn = NULL; - schema->attributes_by_lDAPDisplayName = NULL; - schema->attributes_by_attributeID_id = NULL; - schema->attributes_by_attributeID_oid = NULL; - schema->attributes_by_linkID = NULL; - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; -} - -int dsdb_setup_schema_inversion(struct ldb_context *ldb, struct dsdb_schema *schema) -{ - /* Walk the list of schema classes */ + dsdb_setup_attribute_shortcuts(ldb, schema); - /* For each subClassOf, add us to subclasses of the parent */ - - /* collect these subclasses into a recursive list of total subclasses, preserving order */ - - /* For each subclass under 'top', write the index from it's - * order as an integer in the dsdb_class (for sorting - * objectClass lists efficiently) */ + ret = schema_fill_constructed(schema); + if (ret != LDB_SUCCESS) { + dsdb_sorted_accessors_free(schema); + return ret; + } - /* Walk the list of scheam classes */ - - /* Create a 'total possible superiors' on each class */ return LDB_SUCCESS; + +failed: + dsdb_sorted_accessors_free(schema); + return ldb_oom(ldb); } /** - * Attach the schema to an opaque pointer on the ldb, so ldb modules - * can find it + * Attach the schema to an opaque pointer on the ldb, + * so ldb modules can find it */ - int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) { + struct dsdb_schema *old_schema; int ret; ret = dsdb_setup_sorted_accessors(ldb, schema); @@ -347,12 +433,21 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) return ret; } - ret = schema_fill_constructed(schema); + old_schema = ldb_get_opaque(ldb, "dsdb_schema"); + + ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { return ret; } - ret = ldb_set_opaque(ldb, "dsdb_schema", schema); + /* Remove the reference to the schema we just overwrote - if there was + * none, NULL is harmless here */ + if (old_schema != schema) { + talloc_unlink(ldb, old_schema); + talloc_steal(ldb, schema); + } + + ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL); if (ret != LDB_SUCCESS) { return ret; } @@ -363,8 +458,6 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) return ret; } - talloc_steal(ldb, schema); - return LDB_SUCCESS; } @@ -380,20 +473,30 @@ int dsdb_reference_schema(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_attributes) { int ret; + struct dsdb_schema *old_schema; + old_schema = ldb_get_opaque(ldb, "dsdb_schema"); ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { return ret; } - /* Set the new attributes based on the new schema */ - ret = dsdb_schema_set_attributes(ldb, schema, write_attributes); + /* Remove the reference to the schema we just overwrote - if there was + * none, NULL is harmless here */ + talloc_unlink(ldb, old_schema); + + if (talloc_reference(ldb, schema) == NULL) { + return ldb_oom(ldb); + } + + /* Make this ldb use local schema preferably */ + ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", NULL); if (ret != LDB_SUCCESS) { return ret; } - /* Keep a reference to this schema, just incase the original copy is replaced */ - if (talloc_reference(ldb, schema) == NULL) { - return LDB_ERR_OPERATIONS_ERROR; + ret = dsdb_schema_set_attributes(ldb, schema, write_attributes); + if (ret != LDB_SUCCESS) { + return ret; } return LDB_SUCCESS; @@ -404,43 +507,98 @@ int dsdb_reference_schema(struct ldb_context *ldb, struct dsdb_schema *schema, */ int dsdb_set_global_schema(struct ldb_context *ldb) { + int ret; + void *use_global_schema = (void *)1; if (!global_schema) { return LDB_SUCCESS; } + ret = ldb_set_opaque(ldb, "dsdb_use_global_schema", use_global_schema); + if (ret != LDB_SUCCESS) { + return ret; + } - return dsdb_reference_schema(ldb, global_schema, false /* Don't write attributes, it's expensive */); + /* Set the new attributes based on the new schema */ + ret = dsdb_schema_set_attributes(ldb, global_schema, false /* Don't write attributes, it's expensive */); + if (ret == LDB_SUCCESS) { + /* Keep a reference to this schema, just in case the original copy is replaced */ + if (talloc_reference(ldb, global_schema) == NULL) { + return ldb_oom(ldb); + } + } + + return ret; +} + +bool dsdb_uses_global_schema(struct ldb_context *ldb) +{ + return (ldb_get_opaque(ldb, "dsdb_use_global_schema") != NULL); } /** * Find the schema object for this ldb + * + * If reference_ctx is not NULL, then talloc_reference onto that context */ -struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb) +struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb, TALLOC_CTX *reference_ctx) { const void *p; - struct dsdb_schema *schema; + struct dsdb_schema *schema_out; + struct dsdb_schema *schema_in; + bool use_global_schema; + TALLOC_CTX *tmp_ctx = talloc_new(reference_ctx); + if (!tmp_ctx) { + return NULL; + } /* see if we have a cached copy */ - p = ldb_get_opaque(ldb, "dsdb_schema"); - if (!p) { - return NULL; + use_global_schema = dsdb_uses_global_schema(ldb); + if (use_global_schema) { + schema_in = global_schema; + } else { + p = ldb_get_opaque(ldb, "dsdb_schema"); + + schema_in = talloc_get_type(p, struct dsdb_schema); + if (!schema_in) { + talloc_free(tmp_ctx); + return NULL; + } } - schema = talloc_get_type(p, struct dsdb_schema); - if (!schema) { - return NULL; + if (schema_in->refresh_fn && !schema_in->refresh_in_progress) { + if (!talloc_reference(tmp_ctx, schema_in)) { + /* + * ensure that the schema_in->refresh_in_progress + * remains valid for the right amount of time + */ + talloc_free(tmp_ctx); + return NULL; + } + schema_in->refresh_in_progress = true; + /* This may change schema, if it needs to reload it from disk */ + schema_out = schema_in->refresh_fn(schema_in->loaded_from_module, + schema_in, + use_global_schema); + schema_in->refresh_in_progress = false; + } else { + schema_out = schema_in; } - return schema; + /* This removes the extra reference above */ + talloc_free(tmp_ctx); + if (!reference_ctx) { + return schema_out; + } else { + return talloc_reference(reference_ctx, schema_out); + } } /** * Make the schema found on this ldb the 'global' schema */ -void dsdb_make_schema_global(struct ldb_context *ldb) +void dsdb_make_schema_global(struct ldb_context *ldb, struct dsdb_schema *schema) { - struct dsdb_schema *schema = dsdb_get_schema(ldb); if (!schema) { return; } @@ -450,16 +608,18 @@ void dsdb_make_schema_global(struct ldb_context *ldb) } /* we want the schema to be around permanently */ - talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema); - + talloc_reparent(ldb, talloc_autofree_context(), schema); global_schema = schema; + /* This calls the talloc_reference() of the global schema back onto the ldb */ dsdb_set_global_schema(ldb); } -/* When loading the schema from LDIF files, we don't get the extended DNs. - - We need to set these up, so that from the moment we start the provision, the defaultObjectCategory links are set up correctly. +/** + * When loading the schema from LDIF files, we don't get the extended DNs. + * + * We need to set these up, so that from the moment we start the provision, + * the defaultObjectCategory links are set up correctly. */ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema) { @@ -484,11 +644,11 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc talloc_free(dn); return LDB_ERR_CONSTRAINT_VIOLATION; } - + status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid); if (!NT_STATUS_IS_OK(status)) { talloc_free(dn); - return LDB_ERR_OPERATIONS_ERROR; + return ldb_operr(ldb); } ldb_dn_set_extended_component(dn, "GUID", &guid); @@ -498,30 +658,17 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc return LDB_SUCCESS; } -/** +/** * Add an element to the schema (attribute or class) from an LDB message */ -WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, - struct ldb_message *msg) +WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, + struct ldb_message *msg) { - static struct ldb_parse_tree *attr_tree, *class_tree; - if (!attr_tree) { - attr_tree = ldb_parse_tree(talloc_autofree_context(), "(objectClass=attributeSchema)"); - if (!attr_tree) { - return WERR_NOMEM; - } - } - - if (!class_tree) { - class_tree = ldb_parse_tree(talloc_autofree_context(), "(objectClass=classSchema)"); - if (!class_tree) { - return WERR_NOMEM; - } - } - - if (ldb_match_msg(ldb, msg, attr_tree, NULL, LDB_SCOPE_BASE)) { + if (samdb_find_attribute(ldb, msg, + "objectclass", "attributeSchema") != NULL) { return dsdb_attribute_from_ldb(ldb, schema, msg); - } else if (ldb_match_msg(ldb, msg, class_tree, NULL, LDB_SCOPE_BASE)) { + } else if (samdb_find_attribute(ldb, msg, + "objectclass", "classSchema") != NULL) { return dsdb_class_from_ldb(schema, msg); } @@ -553,7 +700,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const goto nomem; } - schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm"))); + schema = dsdb_new_schema(mem_ctx); schema->fsmo.we_are_master = true; schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER"); @@ -571,11 +718,10 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const } talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; } - talloc_steal(mem_ctx, msg); talloc_free(ldif); prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap"); @@ -586,26 +732,23 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const info_val = ldb_msg_find_ldb_val(msg, "schemaInfo"); if (!info_val) { - info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000"); - if (!info_val_default.data) { - goto nomem; - } + status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); + W_ERROR_NOT_OK_GOTO(status, failed); info_val = &info_val_default; } status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("ERROR: dsdb_load_oid_mappings_ldb() failed with %s\n", win_errstr(status))); goto failed; } - /* - * load the attribute and class definitions outof df - */ + /* load the attribute and class definitions out of df */ while ((ldif = ldb_ldif_read_string(ldb, &df))) { talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; }