]> git.samba.org - samba.git/commitdiff
r24060: Fix bug #4806 by Matthias Wallnöfer <mwallnoefer@yahoo.de>: We need to
authorAndrew Bartlett <abartlet@samba.org>
Fri, 27 Jul 2007 03:08:15 +0000 (03:08 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 20:01:21 +0000 (15:01 -0500)
include the attribute allowedChildClassesEffective for MMC to allow
the creation of containers.

This may need further refinement, but it seems to work for now.

Andrew Bartlett
(This used to be commit d053b8e218767cb12e20a00fb18995e30869db11)

source4/dsdb/samdb/ldb_modules/kludge_acl.c
source4/dsdb/schema/schema.h
source4/dsdb/schema/schema_init.c
source4/setup/provision_users_modify.ldif

index 1ce23d365ab0aa8f521ebc94ea659b1e60dc45c3..ed95d8112d97f03a2ca514e35578aa313bd4833d 100644 (file)
@@ -107,13 +107,15 @@ struct kludge_acl_context {
        enum user_is user_type;
        bool allowedAttributes;
        bool allowedAttributesEffective;
+       bool allowedChildClasses;
+       bool allowedChildClassesEffective;
        const char **attrs;
 };
 
 /* read all objectClasses */
 
 static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_message *msg,
-                                                        const char *attrName) 
+                                       const char *attrName) 
 {
        struct ldb_message_element *oc_el;
        struct ldb_message_element *allowedAttributes;
@@ -129,12 +131,13 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess
           we alter the element array in ldb_msg_add_empty() */
        oc_el = ldb_msg_find_element(msg, "objectClass");
 
-       for (i=0; i < oc_el->num_values; i++) {
+       for (i=0; oc_el && i < oc_el->num_values; i++) {
                class = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data);
                if (!class) {
                        /* We don't know this class?  what is going on? */
                        continue;
                }
+
                for (j=0; class->mayContain && class->mayContain[j]; j++) {
                        ldb_msg_add_string(msg, attrName, class->mayContain[j]);
                }
@@ -168,6 +171,57 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess
 
        return 0;
 
+}
+/* read all objectClasses */
+
+static int kludge_acl_childClasses(struct ldb_context *ldb, struct ldb_message *msg,
+                                  const char *attrName) 
+{
+       struct ldb_message_element *oc_el;
+       struct ldb_message_element *allowedClasses;
+       const struct dsdb_schema *schema = dsdb_get_schema(ldb);
+       const struct dsdb_class *class;
+       int i, j, ret;
+       ret = ldb_msg_add_empty(msg, attrName, 0, &allowedClasses);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+       
+       /* To ensure that oc_el is valid, we must look for it after 
+          we alter the element array in ldb_msg_add_empty() */
+       oc_el = ldb_msg_find_element(msg, "objectClass");
+
+       for (i=0; oc_el && i < oc_el->num_values; i++) {
+               class = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data);
+               if (!class) {
+                       /* We don't know this class?  what is going on? */
+                       continue;
+               }
+
+               for (j=0; class->possibleInferiors && class->possibleInferiors[j]; j++) {
+                       ldb_msg_add_string(msg, attrName, class->possibleInferiors[j]);
+               }
+       }
+               
+       if (allowedClasses->num_values > 1) {
+               qsort(allowedClasses->values, 
+                     allowedClasses->num_values, 
+                     sizeof(*allowedClasses->values),
+                     (comparison_fn_t)data_blob_cmp);
+       
+               for (i=1 ; i < allowedClasses->num_values; i++) {
+                       struct ldb_val *val1 = &allowedClasses->values[i-1];
+                       struct ldb_val *val2 = &allowedClasses->values[i];
+                       if (data_blob_cmp(val1, val2) == 0) {
+                               memmove(val1, val2, (allowedClasses->num_values - i) * sizeof( struct ldb_val)); 
+                               allowedClasses->num_values--;
+                               i--;
+                       }
+               }
+       }
+
+       return 0;
+
 }
 
 /* find all attributes allowed by all these objectClasses */
@@ -192,6 +246,13 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
 
        if (ac->allowedAttributes) {
                ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributes");
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+
+               }
+       }
+       if (ac->allowedChildClasses) {
+               ret = kludge_acl_childClasses(ldb, ares->message, "allowedChildClasses");
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
@@ -208,6 +269,12 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
                                        return ret;
                                }
                        }
+                       if (ac->allowedChildClassesEffective) {
+                               ret = kludge_acl_childClasses(ldb, ares->message, "allowedChildClassesEffective");
+                               if (ret != LDB_SUCCESS) {
+                                       return ret;
+                               }
+                       }
                        break;
                default:
                        /* remove password attributes */
@@ -217,7 +284,8 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
                }
        }
 
-       if ((ac->allowedAttributes || ac->allowedAttributesEffective) && 
+       if ((ac->allowedAttributes || ac->allowedAttributesEffective
+            || ac->allowedChildClasses || ac->allowedChildClassesEffective) && 
            (!ldb_attr_in_list(ac->attrs, "objectClass") && 
             !ldb_attr_in_list(ac->attrs, "*"))) {
                ldb_msg_remove_attr(ares->message, "objectClass");
@@ -267,7 +335,11 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
 
        ac->allowedAttributesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedAttributesEffective");
 
-       if (ac->allowedAttributes || ac->allowedAttributesEffective) {
+       ac->allowedChildClasses = ldb_attr_in_list(req->op.search.attrs, "allowedChildClasses");
+
+       ac->allowedChildClassesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedChildClassesEffective");
+
+       if (ac->allowedAttributes || ac->allowedAttributesEffective || ac->allowedChildClasses || ac->allowedChildClassesEffective) {
                down_req->op.search.attrs
                        = ldb_attr_list_copy_add(down_req, down_req->op.search.attrs, "objectClass");
        }
index ca1ebb038841174850ac301e8aa21f1909b72f77..dd50eae684b3f226e283925d209a28822f0a7f84 100644 (file)
@@ -111,6 +111,7 @@ struct dsdb_class {
        const char **possSuperiors;
        const char **mustContain;
        const char **mayContain;
+       const char **possibleInferiors;
 
        const char *defaultSecurityDescriptor;
 
index fbc4ff0727bb31bace307183578d2f41c725e40f..ce7645c4546c12c0a93a001532b6095dc776d33f 100644 (file)
@@ -492,16 +492,18 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
        GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, True);
 
        obj->systemAuxiliaryClass       = NULL;
-       obj->systemPossSuperiors        = NULL;
 
        obj->auxiliaryClass             = NULL;
-       obj->possSuperiors              = NULL;
 
        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, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, False);
+       GET_STRING_LIST_LDB(msg, "possSuperiors", mem_ctx, obj, possSuperiors, False);
+       GET_STRING_LIST_LDB(msg, "possibleInferiors", mem_ctx, obj, possibleInferiors, False);
+
        GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
 
        GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
@@ -832,6 +834,8 @@ WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
        obj->mustContain                = NULL;
        obj->mayContain                 = NULL;
 
+       obj->possibleInferiors          = NULL;
+
        GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
 
        GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);
index 04ff57368ec2c7ef6fcb8ef1b1a5cfda9a4b3790..5fbfebfd46075ba6610a47e53aa10fcca288c558 100644 (file)
@@ -17,7 +17,3 @@ objectCategory: CN=Container,${SCHEMADN}
 -
 replace: isCriticalSystemObject
 isCriticalSystemObject: TRUE
--
-replace: allowedChildClassesEffective
-allowedChildClassesEffective: user
-allowedChildClassesEffective: group