summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-07-27 03:08:15 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 15:01:21 -0500
commit4e697b288be11a195d493f2d6800ea8c1e251fee (patch)
tree0e9ec41f93dbacb6a1144a8168c7b598e8af05a7 /source4/dsdb/samdb
parentfe60cd993d518afc0e982da9591acc176b0c5036 (diff)
downloadsamba-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.c80
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");
}