From 206421c8fd28ca4bb6375b97e106d3531f1a5559 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sun, 25 Mar 2012 23:25:01 +0200 Subject: s4:dsdb - enhance "get_last_structural_class()" for optimisations If the objectclass entry has been sorted before we are able to determine the (last) structural or 88 object class in constant time. Reviewed-by: Andrew Bartlett Signed-off-by: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/descriptor.c | 6 ++++-- source4/dsdb/samdb/ldb_modules/objectclass.c | 8 +++++--- source4/dsdb/samdb/ldb_modules/schema.c | 25 ++++++++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) (limited to 'source4') diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index 409d08dea9..47207db201 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -542,7 +542,8 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) return ldb_operr(ldb); } - objectclass = get_last_structural_class(schema, objectclass_element, req); + objectclass = get_last_structural_class(schema, objectclass_element, + false); if (objectclass == NULL) { return ldb_operr(ldb); } @@ -660,7 +661,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) return ldb_operr(ldb); } - objectclass = get_last_structural_class(schema, objectclass_element, req); + objectclass = get_last_structural_class(schema, objectclass_element, + false); if (objectclass == NULL) { return ldb_operr(ldb); } diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index b66b4d7a5f..0d75e5ff89 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -637,7 +637,8 @@ static int objectclass_do_add(struct oc_context *ac) /* Make sure its valid to add an object of this type */ objectclass = get_last_structural_class(ac->schema, - objectclass_element, ac->req); + objectclass_element, + true); if(objectclass == NULL) { ldb_asprintf_errstring(ldb, "Failed to find a structural class for %s", @@ -1112,7 +1113,7 @@ static int objectclass_do_mod(struct oc_context *ac) /* Get the new top-most structural object class */ objectclass = get_last_structural_class(ac->schema, oc_el_entry, - ac->req); + false); if (objectclass == NULL) { ldb_set_errstring(ldb, "objectclass: cannot delete all structural objectclasses!"); @@ -1312,7 +1313,8 @@ static int objectclass_do_rename2(struct oc_context *ac) /* existing entry without a valid object class? */ return ldb_operr(ldb); } - objectclass = get_last_structural_class(ac->schema, oc_el_entry, ac->req); + objectclass = get_last_structural_class(ac->schema, oc_el_entry, + false); if (objectclass == NULL) { /* existing entry without a valid object class? */ return ldb_operr(ldb); diff --git a/source4/dsdb/samdb/ldb_modules/schema.c b/source4/dsdb/samdb/ldb_modules/schema.c index 51c6a658d6..f483fd386e 100644 --- a/source4/dsdb/samdb/ldb_modules/schema.c +++ b/source4/dsdb/samdb/ldb_modules/schema.c @@ -29,14 +29,29 @@ #include "libcli/security/security.h" #include "dsdb/samdb/ldb_modules/schema.h" - -const struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema,const struct ldb_message_element *element, - struct ldb_request *parent) +/* + * This function determines the (last) structural or 88 object class of a passed + * "objectClass" attribute. + * Without schema this does not work and hence NULL is returned. If the + * "objectClass" attribute has already been sorted then only a check on the + * last value is necessary (MS-ADTS 3.1.1.1.4) + */ +const struct dsdb_class *get_last_structural_class(const struct dsdb_schema *schema, + const struct ldb_message_element *element, + bool sorted) { const struct dsdb_class *last_class = NULL; - unsigned int i; + unsigned int i = 0; + + if (schema == NULL) { + return NULL; + } + + if (sorted && (element->num_values > 1)) { + i = element->num_values - 1; + } - for (i = 0; i < element->num_values; i++){ + for (; i < element->num_values; i++){ const struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]); if(tmp_class == NULL) { -- cgit