s4:dsdb - enhance "get_last_structural_class()" for optimisations
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Sun, 25 Mar 2012 21:25:01 +0000 (23:25 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 25 Mar 2012 22:57:29 +0000 (00:57 +0200)
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 <abartlet@samba.org>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/descriptor.c
source4/dsdb/samdb/ldb_modules/objectclass.c
source4/dsdb/samdb/ldb_modules/schema.c

index 409d08dea976bf848139fdedd45b85c53e3d549e..47207db2014b0eb1095defc9cff275834f65d123 100644 (file)
@@ -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);
        }
index b66b4d7a5f4f8f10199af62f6149bfd28bf31e32..0d75e5ff89705b512b23db9f0a5ff86203e400c2 100644 (file)
@@ -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);
index 51c6a658d6ede013af2c5097fe893c1138ab8a9e..f483fd386e3f332b5ef593dbaae6f3f7dbff5323 100644 (file)
 #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) {