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;
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]);
}
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 */
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;
}
return ret;
}
}
+ if (ac->allowedChildClassesEffective) {
+ ret = kludge_acl_childClasses(ldb, ares->message, "allowedChildClassesEffective");
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
break;
default:
/* remove password attributes */
}
}
- 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");
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");
}
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);
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);