diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-04-02 16:42:21 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-04-02 16:42:21 +1100 |
commit | 9539e2b508b3340b49575e5022c365ec382b2097 (patch) | |
tree | 57f28e0743b527bcb28fad2a79863e47be9b1416 /source4/dsdb | |
parent | 1bc9c3923574d548810733b512716d5758814328 (diff) | |
download | samba-9539e2b508b3340b49575e5022c365ec382b2097.tar.gz samba-9539e2b508b3340b49575e5022c365ec382b2097.tar.bz2 samba-9539e2b508b3340b49575e5022c365ec382b2097.zip |
major upgrade to the ldb attribute handling
This is all working towards supporting the full WSPP schema without a
major performance penalty.
We now use binary searches when looking up classes and attributes. We
also avoid the loop loading the attributes into ldb, by adding a hook
to override the ldb attribute search function in a module. The
attributes can thus be loaded once, and then saved as part of the
global schema.
Also added support for a few more key attribute syntaxes, as needed
for the full schema.
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/schema/schema.h | 16 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_init.c | 59 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_query.c | 145 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_set.c | 207 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_syntax.c | 13 |
5 files changed, 325 insertions, 115 deletions
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index f7d59a7c39..98ccf5ed9e 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -91,6 +91,7 @@ struct dsdb_attribute { /* internal stuff */ const struct dsdb_syntax *syntax; + const struct ldb_schema_attribute *ldb_schema_attribute; }; struct dsdb_class { @@ -156,6 +157,21 @@ struct dsdb_schema { struct dsdb_attribute *attributes; struct dsdb_class *classes; + /* lists of classes sorted by various attributes, for faster + access */ + uint32_t num_classes; + struct dsdb_class **classes_by_lDAPDisplayName; + struct dsdb_class **classes_by_governsID_id; + struct dsdb_class **classes_by_governsID_oid; + struct dsdb_class **classes_by_cn; + + /* lists of attributes sorted by various fields */ + uint32_t num_attributes; + struct dsdb_attribute **attributes_by_lDAPDisplayName; + struct dsdb_attribute **attributes_by_attributeID_id; + struct dsdb_attribute **attributes_by_attributeID_oid; + struct dsdb_attribute **attributes_by_linkID; + struct { bool we_are_master; struct ldb_dn *master_dn; diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index e619e1ffac..3a65c474fb 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -28,6 +28,7 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "param/param.h" +#include "lib/ldb/include/ldb_module.h" struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) { @@ -582,6 +583,48 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return WERR_OK; } + +/* + setup the ldb_schema_attribute field for a dsdb_attribute + */ +static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb, + struct dsdb_attribute *attr) +{ + const char *syntax = attr->syntax->ldb_syntax; + const struct ldb_schema_syntax *s; + struct ldb_schema_attribute *a; + + if (!syntax) { + syntax = attr->syntax->ldap_oid; + } + + s = ldb_samba_syntax_by_lDAPDisplayName(ldb, attr->lDAPDisplayName); + if (s == NULL) { + s = ldb_samba_syntax_by_name(ldb, syntax); + } + if (s == NULL) { + s = ldb_standard_syntax_by_name(ldb, syntax); + } + + if (s == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + attr->ldb_schema_attribute = a = talloc(attr, struct ldb_schema_attribute); + if (attr->ldb_schema_attribute == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + a->name = attr->lDAPDisplayName; + a->flags = 0; + a->syntax = s; + + return LDB_SUCCESS; +} + + + #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \ (p)->elem = samdb_result_string(msg, attr, NULL);\ if (strict && (p)->elem == NULL) { \ @@ -676,7 +719,8 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, }\ } while (0) -WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema, +WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb, + const struct dsdb_schema *schema, struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_attribute *attr) @@ -745,6 +789,10 @@ WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema, return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; } + if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) { + return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; + } + return WERR_OK; } @@ -866,7 +914,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_ERR_OPERATIONS_ERROR; } - status = dsdb_attribute_from_ldb(schema, attrs_res->msgs[i], sa, sa); + status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i], sa, sa); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: failed to load attribute definition: %s:%s", @@ -1274,7 +1322,8 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb }\ } while (0) -WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema, +WERROR dsdb_attribute_from_drsuapi(struct ldb_context *ldb, + struct dsdb_schema *schema, struct drsuapi_DsReplicaObject *r, TALLOC_CTX *mem_ctx, struct dsdb_attribute *attr) @@ -1333,6 +1382,10 @@ WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema, return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; } + if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) { + return WERR_DS_ATT_SCHEMA_REQ_SYNTAX; + } + return WERR_OK; } diff --git a/source4/dsdb/schema/schema_query.c b/source4/dsdb/schema/schema_query.c index 00de0f8983..f894ef5b1e 100644 --- a/source4/dsdb/schema/schema_query.c +++ b/source4/dsdb/schema/schema_query.c @@ -23,10 +23,44 @@ #include "includes.h" #include "dsdb/samdb/samdb.h" +/* a binary array search, where the array is an array of pointers to structures, + and we want to find a match for 'target' on 'field' in those structures. + + Inputs: + array: base pointer to an array of structures + arrray_size: number of elements in the array + field: the name of the field in the structure we are keying off + target: the field value we are looking for + comparison_fn: the comparison function + result: where the result of the search is put + + if the element is found, then 'result' is set to point to the found array element. If not, + then 'result' is set to NULL. + + The array is assumed to be sorted by the same comparison_fn as the + search (with, for example, qsort) + */ +#define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i]->field); \ + if (_r == 0) { (result) = array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + } } while (0) + + +static int uint32_cmp(uint32_t c1, uint32_t c2) +{ + return c1 - c2; +} + + const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema, uint32_t id) { - struct dsdb_attribute *cur; + struct dsdb_attribute *c; /* * 0xFFFFFFFF is used as value when no mapping table is available, @@ -34,69 +68,49 @@ const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_ */ if (id == 0xFFFFFFFF) return NULL; - /* TODO: add binary search */ - for (cur = schema->attributes; cur; cur = cur->next) { - if (cur->attributeID_id != id) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->attributes_by_attributeID_id, + schema->num_attributes, attributeID_id, id, uint32_cmp, c); + return c; } const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema, const char *oid) { - struct dsdb_attribute *cur; + struct dsdb_attribute *c; if (!oid) return NULL; - /* TODO: add binary search */ - for (cur = schema->attributes; cur; cur = cur->next) { - if (strcmp(cur->attributeID_oid, oid) != 0) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->attributes_by_attributeID_oid, + schema->num_attributes, attributeID_oid, oid, strcasecmp, c); + return c; } const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema, const char *name) { - struct dsdb_attribute *cur; + struct dsdb_attribute *c; if (!name) return NULL; - /* TODO: add binary search */ - for (cur = schema->attributes; cur; cur = cur->next) { - if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->attributes_by_lDAPDisplayName, + schema->num_attributes, lDAPDisplayName, name, strcasecmp, c); + return c; } const struct dsdb_attribute *dsdb_attribute_by_linkID(const struct dsdb_schema *schema, int linkID) { - struct dsdb_attribute *cur; - - /* TODO: add binary search */ - for (cur = schema->attributes; cur; cur = cur->next) { - if (cur->linkID != linkID) continue; + struct dsdb_attribute *c; - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->attributes_by_linkID, + schema->num_attributes, linkID, linkID, uint32_cmp, c); + return c; } const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema, uint32_t id) { - struct dsdb_class *cur; + struct dsdb_class *c; /* * 0xFFFFFFFF is used as value when no mapping table is available, @@ -104,65 +118,39 @@ const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *sc */ if (id == 0xFFFFFFFF) return NULL; - /* TODO: add binary search */ - for (cur = schema->classes; cur; cur = cur->next) { - if (cur->governsID_id != id) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_governsID_id, + schema->num_classes, governsID_id, id, uint32_cmp, c); + return c; } const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema, const char *oid) { - struct dsdb_class *cur; - + struct dsdb_class *c; if (!oid) return NULL; - - /* TODO: add binary search */ - for (cur = schema->classes; cur; cur = cur->next) { - if (strcmp(cur->governsID_oid, oid) != 0) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_governsID_oid, + schema->num_classes, governsID_oid, oid, strcasecmp, c); + return c; } const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema, const char *name) { - struct dsdb_class *cur; - + struct dsdb_class *c; if (!name) return NULL; - - /* TODO: add binary search */ - for (cur = schema->classes; cur; cur = cur->next) { - if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_lDAPDisplayName, + schema->num_classes, lDAPDisplayName, name, strcasecmp, c); + return c; } const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema, const char *cn) { - struct dsdb_class *cur; - + struct dsdb_class *c; if (!cn) return NULL; - - /* TODO: add binary search */ - for (cur = schema->classes; cur; cur = cur->next) { - if (strcasecmp(cur->cn, cn) != 0) continue; - - return cur; - } - - return NULL; + BINARY_ARRAY_SEARCH(schema->classes_by_cn, + schema->num_classes, cn, cn, strcasecmp, c); + return c; } const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema, @@ -171,7 +159,6 @@ const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema, const struct dsdb_attribute *a; const struct dsdb_class *c; - /* TODO: add binary search */ a = dsdb_attribute_by_attributeID_id(schema, id); if (a) { return a->lDAPDisplayName; diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index d52976958d..9f23088c97 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -26,6 +26,21 @@ #include "lib/ldb/include/ldb_module.h" #include "param/param.h" +/* + override the name to attribute handler function + */ +const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, + void *private_data, + const char *name) +{ + struct dsdb_schema *schema = talloc_get_type_abort(private_data, struct dsdb_schema); + const struct dsdb_attribute *a = dsdb_attribute_by_lDAPDisplayName(schema, name); + if (a == NULL) { + /* this will fall back to ldb internal handling */ + return NULL; + } + return a->ldb_schema_attribute; +} static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schema *schema, bool write_attributes) { @@ -34,11 +49,19 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem struct ldb_result *res_idx; struct dsdb_attribute *attr; struct ldb_message *mod_msg; - TALLOC_CTX *mem_ctx = talloc_new(ldb); - + TALLOC_CTX *mem_ctx; struct ldb_message *msg; struct ldb_message *msg_idx; + /* setup our own attribute name to schema handler */ + ldb_schema_attribute_set_override_handler(ldb, dsdb_attribute_handler_override, schema); + + if (!write_attributes) { + talloc_free(mem_ctx); + return ret; + } + + mem_ctx = talloc_new(ldb); if (!mem_ctx) { return LDB_ERR_OPERATIONS_ERROR; } @@ -46,27 +69,27 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem msg = ldb_msg_new(mem_ctx); if (!msg) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + goto op_error; } msg_idx = ldb_msg_new(mem_ctx); if (!msg_idx) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + goto op_error; } msg->dn = ldb_dn_new(msg, ldb, "@ATTRIBUTES"); if (!msg->dn) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + goto op_error; } msg_idx->dn = ldb_dn_new(msg, ldb, "@INDEXLIST"); if (!msg_idx->dn) { ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; + goto op_error; } for (attr = schema->attributes; attr; attr = attr->next) { - const struct ldb_schema_syntax *s; const char *syntax = attr->syntax->ldb_syntax; + if (!syntax) { syntax = attr->syntax->ldap_oid; } @@ -87,33 +110,13 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem break; } } - - if (!attr->syntax) { - continue; - } - - ret = ldb_schema_attribute_add(ldb, attr->lDAPDisplayName, LDB_ATTR_FLAG_FIXED, - syntax); - if (ret != LDB_SUCCESS) { - s = ldb_samba_syntax_by_name(ldb, attr->syntax->ldap_oid); - if (s) { - ret = ldb_schema_attribute_add_with_syntax(ldb, attr->lDAPDisplayName, LDB_ATTR_FLAG_FIXED, s); - } else { - ret = LDB_SUCCESS; /* Nothing to do here */ - } - } - - if (ret != LDB_SUCCESS) { - break; - } } - if (!write_attributes || ret != LDB_SUCCESS) { + if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); 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)); if (ret == LDB_ERR_NO_SUCH_OBJECT) { @@ -165,6 +168,146 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem } talloc_free(mem_ctx); return ret; + +op_error: + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; +} + +static int dsdb_compare_class_by_lDAPDisplayName(struct dsdb_class **c1, struct dsdb_class **c2) +{ + return strcasecmp((*c1)->lDAPDisplayName, (*c2)->lDAPDisplayName); +} +static int dsdb_compare_class_by_governsID_id(struct dsdb_class **c1, struct dsdb_class **c2) +{ + return (*c1)->governsID_id - (*c2)->governsID_id; +} +static int dsdb_compare_class_by_governsID_oid(struct dsdb_class **c1, struct dsdb_class **c2) +{ + return strcasecmp((*c1)->governsID_oid, (*c2)->governsID_oid); +} +static int dsdb_compare_class_by_cn(struct dsdb_class **c1, struct dsdb_class **c2) +{ + return strcasecmp((*c1)->cn, (*c2)->cn); +} + +static int dsdb_compare_attribute_by_lDAPDisplayName(struct dsdb_attribute **a1, struct dsdb_attribute **a2) +{ + return strcasecmp((*a1)->lDAPDisplayName, (*a2)->lDAPDisplayName); +} +static int dsdb_compare_attribute_by_attributeID_id(struct dsdb_attribute **a1, struct dsdb_attribute **a2) +{ + return (*a1)->attributeID_id - (*a2)->attributeID_id; +} +static int dsdb_compare_attribute_by_attributeID_oid(struct dsdb_attribute **a1, struct dsdb_attribute **a2) +{ + return strcasecmp((*a1)->attributeID_oid, (*a2)->attributeID_oid); +} +static int dsdb_compare_attribute_by_linkID(struct dsdb_attribute **a1, struct dsdb_attribute **a2) +{ + return (*a1)->linkID - (*a2)->linkID; +} + +/* + create the sorted accessor arrays for the schema + */ +static int dsdb_setup_sorted_accessors(struct ldb_context *ldb, + struct dsdb_schema *schema) +{ + struct dsdb_class *cur; + struct dsdb_attribute *a; + uint32_t i; + + 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); + + /* count the classes */ + for (i=0, cur=schema->classes; cur; i++, cur=cur->next) /* noop */ ; + schema->num_classes = i; + + /* setup classes_by_* */ + schema->classes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_class *, i); + schema->classes_by_governsID_id = talloc_array(schema, struct dsdb_class *, i); + schema->classes_by_governsID_oid = talloc_array(schema, struct dsdb_class *, i); + schema->classes_by_cn = talloc_array(schema, struct dsdb_class *, i); + if (schema->classes_by_lDAPDisplayName == NULL || + schema->classes_by_governsID_id == NULL || + schema->classes_by_governsID_oid == NULL || + schema->classes_by_cn == NULL) { + goto failed; + } + + for (i=0, cur=schema->classes; cur; i++, cur=cur->next) { + schema->classes_by_lDAPDisplayName[i] = cur; + schema->classes_by_governsID_id[i] = cur; + schema->classes_by_governsID_oid[i] = cur; + schema->classes_by_cn[i] = cur; + } + + /* sort the arrays */ + qsort(schema->classes_by_lDAPDisplayName, schema->num_classes, + sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_lDAPDisplayName); + qsort(schema->classes_by_governsID_id, schema->num_classes, + sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_id); + qsort(schema->classes_by_governsID_oid, schema->num_classes, + sizeof(struct dsdb_class *), QSORT_CAST dsdb_compare_class_by_governsID_oid); + qsort(schema->classes_by_cn, schema->num_classes, + sizeof(struct dsdb_class *), QSORT_CAST 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 */ ; + schema->num_attributes = i; + + /* 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_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_attributeID_oid == NULL || + schema->attributes_by_linkID == NULL) { + goto failed; + } + + 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; + } + + /* sort the arrays */ + qsort(schema->attributes_by_lDAPDisplayName, schema->num_attributes, + sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_lDAPDisplayName); + qsort(schema->attributes_by_attributeID_id, schema->num_attributes, + sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_id); + qsort(schema->attributes_by_attributeID_oid, schema->num_attributes, + sizeof(struct dsdb_attribute *), QSORT_CAST dsdb_compare_attribute_by_attributeID_oid); + qsort(schema->attributes_by_linkID, schema->num_attributes, + sizeof(struct dsdb_attribute *), QSORT_CAST 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; } @@ -177,6 +320,11 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) { int ret; + ret = dsdb_setup_sorted_accessors(ldb, schema); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { return ret; @@ -207,6 +355,7 @@ int dsdb_set_global_schema(struct ldb_context *ldb) if (!global_schema) { return LDB_SUCCESS; } + ret = ldb_set_opaque(ldb, "dsdb_schema", global_schema); if (ret != LDB_SUCCESS) { return ret; @@ -367,7 +516,7 @@ WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, con goto nomem; } - status = dsdb_attribute_from_ldb(schema, msg, sa, sa); + status = dsdb_attribute_from_ldb(ldb, schema, msg, sa, sa); if (!W_ERROR_IS_OK(status)) { goto failed; } diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c index 27c9a6c4a4..4fd6501cc8 100644 --- a/source4/dsdb/schema/schema_syntax.c +++ b/source4/dsdb/schema/schema_syntax.c @@ -1227,7 +1227,7 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context static const struct dsdb_syntax dsdb_syntaxes[] = { { .name = "Boolean", - .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7", + .ldap_oid = LDB_SYNTAX_BOOLEAN, .oMSyntax = 1, .attributeSyntax_oid = "2.5.5.8", .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb, @@ -1289,7 +1289,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, .equality = "numericStringMatch", .substring = "numericStringSubstringsMatch", - .comment = "Numeric String" + .comment = "Numeric String", + .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING, },{ .name = "String(Printable)", .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44", @@ -1297,6 +1298,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .attributeSyntax_oid = "2.5.5.5", .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, + .ldb_syntax = LDB_SYNTAX_OCTET_STRING, },{ .name = "String(Teletex)", .ldap_oid = "1.2.840.113556.1.4.905", @@ -1316,7 +1318,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi, .equality = "caseExactIA5Match", - .comment = "Printable String" + .comment = "Printable String", + .ldb_syntax = LDB_SYNTAX_OCTET_STRING, },{ .name = "String(UTC-Time)", .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53", @@ -1423,7 +1426,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .attributeSyntax_oid = "2.5.5.13", .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi, - .comment = "Presentation Address" + .comment = "Presentation Address", + .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING, },{ /* not used in w2k3 schema */ .name = "Object(Access-Point)", @@ -1433,6 +1437,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .attributeSyntax_oid = "2.5.5.14", .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, + .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING, },{ /* not used in w2k3 schema */ .name = "Object(DN-String)", |