From 4e697b288be11a195d493f2d6800ea8c1e251fee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 27 Jul 2007 03:08:15 +0000 Subject: r24060: Fix bug #4806 by Matthias Wallnöfer : We need to include the attribute allowedChildClassesEffective for MMC to allow the creation of containers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 80 +++++++++++++++++++++++++++-- source4/dsdb/schema/schema.h | 1 + source4/dsdb/schema/schema_init.c | 8 ++- source4/setup/provision_users_modify.ldif | 4 -- 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 1ce23d365a..ed95d8112d 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -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"); } diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index ca1ebb0388..dd50eae684 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -111,6 +111,7 @@ struct dsdb_class { const char **possSuperiors; const char **mustContain; const char **mayContain; + const char **possibleInferiors; const char *defaultSecurityDescriptor; diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index fbc4ff0727..ce7645c454 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -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); diff --git a/source4/setup/provision_users_modify.ldif b/source4/setup/provision_users_modify.ldif index 04ff57368e..5fbfebfd46 100644 --- a/source4/setup/provision_users_modify.ldif +++ b/source4/setup/provision_users_modify.ldif @@ -17,7 +17,3 @@ objectCategory: CN=Container,${SCHEMADN} - replace: isCriticalSystemObject isCriticalSystemObject: TRUE -- -replace: allowedChildClassesEffective -allowedChildClassesEffective: user -allowedChildClassesEffective: group -- cgit