summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c91
1 files changed, 77 insertions, 14 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index edd451255e..b1d8711cfa 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -39,30 +39,43 @@ static int generate_extendedAttributeInfo(struct ldb_context *ldb, struct ldb_me
const struct dsdb_schema *schema);
static int generate_extendedClassInfo(struct ldb_context *ldb, struct ldb_message *msg,
const struct dsdb_schema *schema);
+static int generate_possibleInferiors(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema);
static const struct {
const char *attr;
int (*fn)(struct ldb_context *, struct ldb_message *, const struct dsdb_schema *);
+ bool aggregate;
} generated_attrs[] = {
{
.attr = "objectClasses",
- .fn = generate_objectClasses
+ .fn = generate_objectClasses,
+ .aggregate = true,
},
{
.attr = "attributeTypes",
- .fn = generate_attributeTypes
+ .fn = generate_attributeTypes,
+ .aggregate = true,
},
{
.attr = "dITContentRules",
- .fn = generate_dITContentRules
+ .fn = generate_dITContentRules,
+ .aggregate = true,
},
{
.attr = "extendedAttributeInfo",
- .fn = generate_extendedAttributeInfo
+ .fn = generate_extendedAttributeInfo,
+ .aggregate = true,
},
{
.attr = "extendedClassInfo",
- .fn = generate_extendedClassInfo
+ .fn = generate_extendedClassInfo,
+ .aggregate = true,
+ },
+ {
+ .attr = "possibleInferiors",
+ .fn = generate_possibleInferiors,
+ .aggregate = false,
}
};
@@ -385,6 +398,46 @@ static int generate_extendedClassInfo(struct ldb_context *ldb,
return LDB_SUCCESS;
}
+
+static int generate_possibleInferiors(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema)
+{
+ struct ldb_dn *dn = msg->dn;
+ int ret, i;
+ const char *first_component_name = ldb_dn_get_component_name(dn, 0);
+ const struct ldb_val *first_component_val;
+ const char *class_name;
+ const struct dsdb_class *schema_class;
+ const char **possibleInferiors;
+
+ if (strcasecmp(first_component_name, "cn") != 0) {
+ return LDB_SUCCESS;
+ }
+
+ first_component_val = ldb_dn_get_component_val(dn, 0);
+ class_name = (const char *)first_component_val->data;
+
+ schema_class = dsdb_class_by_cn(schema, class_name);
+ if (schema_class == NULL) {
+ return LDB_SUCCESS;
+ }
+
+ possibleInferiors = schema_class->possibleInferiors;
+ if (possibleInferiors == NULL) {
+ return LDB_SUCCESS;
+ }
+
+ for (i=0;possibleInferiors[i];i++) {
+ ret = ldb_msg_add_string(msg, "possibleInferiors", possibleInferiors[i]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
+
+
/* Add objectClasses, attributeTypes and dITContentRules from the
schema object (they are not stored in the database)
*/
@@ -412,19 +465,29 @@ static int schema_fsmo_search_callback(struct ldb_request *req, struct ldb_reply
switch (ares->type) {
case LDB_REPLY_ENTRY:
- if (ldb_dn_compare(ares->message->dn, mc->aggregate_dn) != 0) {
- return ldb_module_send_entry(ac->req, ares->message, ares->controls);
- }
-
- for (i=0; i < ARRAY_SIZE(generated_attrs); i++) {
- if (ldb_attr_in_list(ac->req->op.search.attrs, generated_attrs[i].attr)) {
- ret = generated_attrs[i].fn(ldb, ares->message, ac->schema);
- if (ret != LDB_SUCCESS) {
- return ret;
+ if (ldb_dn_compare(ares->message->dn, mc->aggregate_dn) == 0) {
+ for (i=0; i < ARRAY_SIZE(generated_attrs); i++) {
+ if (generated_attrs[i].aggregate &&
+ ldb_attr_in_list(ac->req->op.search.attrs, generated_attrs[i].attr)) {
+ ret = generated_attrs[i].fn(ldb, ares->message, ac->schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+ } else {
+ for (i=0; i < ARRAY_SIZE(generated_attrs); i++) {
+ if (!generated_attrs[i].aggregate &&
+ ldb_attr_in_list(ac->req->op.search.attrs, generated_attrs[i].attr)) {
+ ret = generated_attrs[i].fn(ldb, ares->message, ac->schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
}
}
}
+
return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL: