s4:dsdb/schema Simplify schema loading from ldb messages
authorAndrew Bartlett <abartlet@samba.org>
Mon, 9 Nov 2009 09:40:21 +0000 (20:40 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 11 Nov 2009 21:11:19 +0000 (08:11 +1100)
It turns out that we always add the class/attribute to the schema.

source4/dsdb/schema/schema_init.c
source4/dsdb/schema/schema_set.c
source4/torture/ldap/schema.c

index de370e0b23a8223a0fd9af05028034416ce5a6b2..19c72735cc5e6aa43ffac254f455126109786915 100644 (file)
@@ -508,7 +508,7 @@ static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb,
        (p)->elem = samdb_result_uint(msg, attr, 0);\
 } while (0)
 
-#define GET_UINT32_PTR_LDB(msg, attr, p, elem) do { \
+#define GET_UINT32_PTR_LDB(msg, attr, mem_ctx, p, elem) do {           \
        uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\
        if (_v == UINT64_MAX) { \
                (p)->elem = NULL; \
@@ -542,16 +542,18 @@ static int dsdb_schema_setup_ldb_schema_attribute(struct ldb_context *ldb,
 } while (0)
 
 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)
+                              struct dsdb_schema *schema,
+                              struct ldb_message *msg)
 {
        WERROR status;
+       struct dsdb_attribute *attr = talloc_zero(schema, struct dsdb_attribute);
+       if (!attr) {
+               return WERR_NOMEM;
+       }
 
-       GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, false);
-       GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true);
-       GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, true);
+       GET_STRING_LDB(msg, "cn", attr, attr, cn, false);
+       GET_STRING_LDB(msg, "lDAPDisplayName", attr, attr, lDAPDisplayName, true);
+       GET_STRING_LDB(msg, "attributeID", attr, attr, attributeID_oid, true);
        if (!schema->prefixmap || schema->prefixmap->length == 0) {
                /* set an invalid value */
                attr->attributeID_id = 0xFFFFFFFF;
@@ -576,7 +578,7 @@ WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb,
        GET_BOOL_LDB(msg, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, false);
        GET_UINT32_LDB(msg, "linkID", attr, linkID);
 
-       GET_STRING_LDB(msg, "attributeSyntax", mem_ctx, attr, attributeSyntax_oid, true);
+       GET_STRING_LDB(msg, "attributeSyntax", attr, attr, attributeSyntax_oid, true);
        if (!schema->prefixmap || schema->prefixmap->length == 0) {
                /* set an invalid value */
                attr->attributeSyntax_id = 0xFFFFFFFF;
@@ -592,20 +594,20 @@ WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb,
                }
        }
        GET_UINT32_LDB(msg, "oMSyntax", attr, oMSyntax);
-       GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
+       GET_BLOB_LDB(msg, "oMObjectClass", attr, attr, oMObjectClass);
 
        GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true);
-       GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower);
-       GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper);
+       GET_UINT32_PTR_LDB(msg, "rangeLower", attr, attr, rangeLower);
+       GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, attr, rangeUpper);
        GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
 
        GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
-       GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
+       GET_BLOB_LDB(msg, "msDs-Schema-Extensions", attr, attr, msDs_Schema_Extensions);
 
        GET_BOOL_LDB(msg, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false);
-       GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);
-       GET_STRING_LDB(msg, "adminDescription", mem_ctx, attr, adminDescription, false);
-       GET_STRING_LDB(msg, "classDisplayName", mem_ctx, attr, classDisplayName, false);
+       GET_STRING_LDB(msg, "adminDisplayName", attr, attr, adminDisplayName, false);
+       GET_STRING_LDB(msg, "adminDescription", attr, attr, adminDescription, false);
+       GET_STRING_LDB(msg, "classDisplayName", attr, attr, classDisplayName, false);
        GET_BOOL_LDB(msg, "isEphemeral", attr, isEphemeral, false);
        GET_BOOL_LDB(msg, "isDefunct", attr, isDefunct, false);
        GET_BOOL_LDB(msg, "systemOnly", attr, systemOnly, false);
@@ -619,19 +621,21 @@ WERROR dsdb_attribute_from_ldb(struct ldb_context *ldb,
                return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
        }
 
+       DLIST_ADD(schema->attributes, attr);
        return WERR_OK;
 }
 
-WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
-                          struct ldb_message *msg,
-                          TALLOC_CTX *mem_ctx,
-                          struct dsdb_class *obj)
+WERROR dsdb_class_from_ldb(struct dsdb_schema *schema,
+                          struct ldb_message *msg)
 {
        WERROR status;
-
-       GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, false);
-       GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true);
-       GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, true);
+       struct dsdb_class *obj = talloc_zero(schema, struct dsdb_class);
+       if (!obj) {
+               return WERR_NOMEM;
+       }
+       GET_STRING_LDB(msg, "cn", obj, obj, cn, false);
+       GET_STRING_LDB(msg, "lDAPDisplayName", obj, obj, lDAPDisplayName, true);
+       GET_STRING_LDB(msg, "governsID", obj, obj, governsID_oid, true);
        if (!schema->prefixmap || schema->prefixmap->length == 0) {
                /* set an invalid value */
                obj->governsID_id = 0xFFFFFFFF;
@@ -649,35 +653,36 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
        GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID);
 
        GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory);
-       GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, false);
-       GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, true);
+       GET_STRING_LDB(msg, "rDNAttID", obj, obj, rDNAttID, false);
+       GET_STRING_LDB(msg, "defaultObjectCategory", obj, obj, defaultObjectCategory, true);
  
-       GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, true);
+       GET_STRING_LDB(msg, "subClassOf", obj, obj, subClassOf, true);
 
-       GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass, false);
-       GET_STRING_LIST_LDB(msg, "auxiliaryClass", mem_ctx, obj, auxiliaryClass, false);
+       GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", obj, obj, systemAuxiliaryClass, false);
+       GET_STRING_LIST_LDB(msg, "auxiliaryClass", obj, obj, auxiliaryClass, false);
 
-       GET_STRING_LIST_LDB(msg, "systemMustContain", mem_ctx, obj, systemMustContain, false);
-       GET_STRING_LIST_LDB(msg, "systemMayContain", mem_ctx, obj, systemMayContain, false);
-       GET_STRING_LIST_LDB(msg, "mustContain", mem_ctx, obj, mustContain, false);
-       GET_STRING_LIST_LDB(msg, "mayContain", mem_ctx, obj, mayContain, false);
+       GET_STRING_LIST_LDB(msg, "systemMustContain", obj, obj, systemMustContain, false);
+       GET_STRING_LIST_LDB(msg, "systemMayContain", obj, obj, systemMayContain, false);
+       GET_STRING_LIST_LDB(msg, "mustContain", obj, obj, mustContain, false);
+       GET_STRING_LIST_LDB(msg, "mayContain", obj, obj, mayContain, false);
 
-       GET_STRING_LIST_LDB(msg, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);
-       GET_STRING_LIST_LDB(msg, "possSuperiors", mem_ctx, obj, possSuperiors, false);
+       GET_STRING_LIST_LDB(msg, "systemPossSuperiors", obj, obj, systemPossSuperiors, false);
+       GET_STRING_LIST_LDB(msg, "possSuperiors", obj, obj, possSuperiors, false);
 
-       GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
+       GET_STRING_LDB(msg, "defaultSecurityDescriptor", obj, obj, defaultSecurityDescriptor, false);
 
        GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
-       GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
+       GET_BLOB_LDB(msg, "msDs-Schema-Extensions", obj, obj, msDs_Schema_Extensions);
 
        GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false);
-       GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);
-       GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, false);
-       GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, false);
+       GET_STRING_LDB(msg, "adminDisplayName", obj, obj, adminDisplayName, false);
+       GET_STRING_LDB(msg, "adminDescription", obj, obj, adminDescription, false);
+       GET_STRING_LDB(msg, "classDisplayName", obj, obj, classDisplayName, false);
        GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, false);
        GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, false);
        GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, false);
 
+       DLIST_ADD(schema->classes, obj);
        return WERR_OK;
 }
 
@@ -736,15 +741,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
        }
 
        for (i=0; i < attrs_res->count; i++) {
-               struct dsdb_attribute *sa;
-
-               sa = talloc_zero(schema, struct dsdb_attribute);
-               if (!sa) {
-                       dsdb_oom(error_string, mem_ctx);
-                       return LDB_ERR_OPERATIONS_ERROR;
-               }
-
-               status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i], sa, sa);
+               status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i]);
                if (!W_ERROR_IS_OK(status)) {
                        *error_string = talloc_asprintf(mem_ctx, 
                                      "schema_fsmo_init: failed to load attribute definition: %s:%s",
@@ -753,20 +750,10 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
                        DEBUG(0,(__location__ ": %s\n", *error_string));
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
-
-               DLIST_ADD(schema->attributes, sa);
        }
 
        for (i=0; i < objectclass_res->count; i++) {
-               struct dsdb_class *sc;
-
-               sc = talloc_zero(schema, struct dsdb_class);
-               if (!sc) {
-                       dsdb_oom(error_string, mem_ctx);
-                       return LDB_ERR_OPERATIONS_ERROR;
-               }
-
-               status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i], sc, sc);
+               status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i]);
                if (!W_ERROR_IS_OK(status)) {
                        *error_string = talloc_asprintf(mem_ctx, 
                                      "schema_fsmo_init: failed to load class definition: %s:%s",
@@ -775,8 +762,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
                        DEBUG(0,(__location__ ": %s\n", *error_string));
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
-
-               DLIST_ADD(schema->classes, sc);
        }
 
        schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner");
index 9f22b3233407a4b37651ee95e737ac5d97994709..4c9e60880107fcf33c57bdbcf0e9aadfcea2da51 100644 (file)
@@ -456,6 +456,36 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
        dsdb_set_global_schema(ldb);
 }
 
+/** 
+ * 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) 
+{
+       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)) {
+               return dsdb_attribute_from_ldb(ldb, schema, msg);
+       } else if (ldb_match_msg(ldb, msg, class_tree, NULL, LDB_SCOPE_BASE)) {
+               return dsdb_class_from_ldb(schema, msg);
+       }
+
+       /* Don't fail on things not classes or attributes */
+       return WERR_OK;
+}
 
 /**
  * Rather than read a schema from the LDB itself, read it from an ldif
@@ -475,6 +505,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
        const struct ldb_val *info_val;
        struct ldb_val info_val_default;
 
+
        mem_ctx = talloc_new(ldb);
        if (!mem_ctx) {
                goto nomem;
@@ -529,9 +560,6 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
         * load the attribute and class definitions outof df
         */
        while ((ldif = ldb_ldif_read_string(ldb, &df))) {
-               bool is_sa;
-               bool is_sc;
-
                talloc_steal(mem_ctx, ldif);
 
                msg = ldb_msg_canonicalize(ldb, ldif->msg);
@@ -539,40 +567,10 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
                        goto nomem;
                }
 
-               talloc_steal(mem_ctx, msg);
+               status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, msg);
                talloc_free(ldif);
-
-               is_sa = ldb_msg_check_string_attribute(msg, "objectClass", "attributeSchema");
-               is_sc = ldb_msg_check_string_attribute(msg, "objectClass", "classSchema");
-
-               if (is_sa) {
-                       struct dsdb_attribute *sa;
-
-                       sa = talloc_zero(schema, struct dsdb_attribute);
-                       if (!sa) {
-                               goto nomem;
-                       }
-
-                       status = dsdb_attribute_from_ldb(ldb, schema, msg, sa, sa);
-                       if (!W_ERROR_IS_OK(status)) {
-                               goto failed;
-                       }
-
-                       DLIST_ADD(schema->attributes, sa);
-               } else if (is_sc) {
-                       struct dsdb_class *sc;
-
-                       sc = talloc_zero(schema, struct dsdb_class);
-                       if (!sc) {
-                               goto nomem;
-                       }
-
-                       status = dsdb_class_from_ldb(schema, msg, sc, sc);
-                       if (!W_ERROR_IS_OK(status)) {
-                               goto failed;
-                       }
-
-                       DLIST_ADD(schema->classes, sc);
+               if (!W_ERROR_IS_OK(status)) {
+                       goto failed;
                }
        }
 
index b0a4892d7a54650e841ea25ba3d603abe1436cf0..c9423409a8675bba0a594a9b79d2a46a56538a69 100644 (file)
@@ -211,43 +211,28 @@ again:
 static int test_add_attribute(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
 {
        struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
-       struct dsdb_attribute *attr = NULL;
        WERROR status;
 
-       attr = talloc_zero(schema, struct dsdb_attribute);
-       if (!attr) {
-               goto failed;
-       }
-
-       status = dsdb_attribute_from_ldb(ldb, schema, msg, attr, attr);
+       status = dsdb_attribute_from_ldb(ldb, schema, msg);
        if (!W_ERROR_IS_OK(status)) {
                goto failed;
        }
 
-       DLIST_ADD_END(schema->attributes, attr, struct dsdb_attribute *);
        return LDB_SUCCESS;
 failed:
-       talloc_free(attr);
        return LDB_ERR_OTHER;
 }
 
 static int test_add_class(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
 {
        struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
-       struct dsdb_class *obj;
        WERROR status;
 
-       obj = talloc_zero(schema, struct dsdb_class);
-       if (!obj) {
-               goto failed;
-       }
-
-       status = dsdb_class_from_ldb(schema, msg, obj, obj);
+       status = dsdb_class_from_ldb(schema, msg);
        if (!W_ERROR_IS_OK(status)) {
                goto failed;
        }
 
-       DLIST_ADD_END(schema->classes, obj, struct dsdb_class *);
        return LDB_SUCCESS;
 failed:
        return LDB_ERR_OTHER;