diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-07-27 03:08:15 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:01:21 -0500 |
commit | 4e697b288be11a195d493f2d6800ea8c1e251fee (patch) | |
tree | 0e9ec41f93dbacb6a1144a8168c7b598e8af05a7 /source4/dsdb/samdb | |
parent | fe60cd993d518afc0e982da9591acc176b0c5036 (diff) | |
download | samba-4e697b288be11a195d493f2d6800ea8c1e251fee.tar.gz samba-4e697b288be11a195d493f2d6800ea8c1e251fee.tar.bz2 samba-4e697b288be11a195d493f2d6800ea8c1e251fee.zip |
r24060: Fix bug #4806 by Matthias Wallnöfer <mwallnoefer@yahoo.de>: We need to
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)
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/kludge_acl.c | 80 |
1 files changed, 76 insertions, 4 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]); } @@ -169,6 +172,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 */ @@ -194,6 +248,13 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld 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"); } |