diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/anr.c | 44 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/linked_attributes.c | 8 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/normalise.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/partition.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 207 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_syntax.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/simple_ldap_map.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 2 |
9 files changed, 240 insertions, 33 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/anr.c b/source4/dsdb/samdb/ldb_modules/anr.c index 1252c9ee42..4e2c527fe9 100644 --- a/source4/dsdb/samdb/ldb_modules/anr.c +++ b/source4/dsdb/samdb/ldb_modules/anr.c @@ -146,7 +146,7 @@ struct ldb_parse_tree *anr_replace_callback(TALLOC_CTX *mem_ctx, op = LDB_OP_SUBSTRING; } for (cur = schema->attributes; cur; cur = cur->next) { - if (!(cur->searchFlags & 0x4)) continue; + if (!(cur->searchFlags & SEARCH_FLAG_ANR)) continue; match_tree = make_match_tree(module, mem_ctx, op, cur->lDAPDisplayName, match); if (tree) { @@ -224,30 +224,26 @@ struct ldb_parse_tree *anr_replace_subtrees(struct ldb_parse_tree *tree, void *context) { int i; + struct ldb_parse_tree *tmp; + switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: for (i=0;i<tree->u.list.num_elements;i++) { - tree->u.list.elements[i] = anr_replace_subtrees(tree->u.list.elements[i], - attr, callback, context); - if (!tree->u.list.elements[i]) { - return NULL; - } + tmp = anr_replace_subtrees(tree->u.list.elements[i], + attr, callback, context); + if (tmp) tree->u.list.elements[i] = tmp; } break; case LDB_OP_NOT: - tree->u.isnot.child = anr_replace_subtrees(tree->u.isnot.child, attr, callback, context); - if (!tree->u.isnot.child) { - return NULL; - } + tmp = anr_replace_subtrees(tree->u.isnot.child, attr, callback, context); + if (tmp) tree->u.isnot.child = tmp; break; case LDB_OP_EQUALITY: if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) { - tree = callback(tree, &tree->u.equality.value, + tmp = callback(tree, &tree->u.equality.value, context); - if (!tree) { - return NULL; - } + if (tmp) tree = tmp; } break; case LDB_OP_SUBSTRING: @@ -256,10 +252,8 @@ struct ldb_parse_tree *anr_replace_subtrees(struct ldb_parse_tree *tree, tree->u.substring.end_with_wildcard == 1 && tree->u.substring.chunks[0] != NULL && tree->u.substring.chunks[1] == NULL) { - tree = callback(tree, tree->u.substring.chunks[0], context); - if (!tree) { - return NULL; - } + tmp = callback(tree, tree->u.substring.chunks[0], context); + if (tmp) tree = tmp; } } break; @@ -280,17 +274,29 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req) context->module = module; context->found_anr = false; +#if 0 + printf("oldanr : %s\n", ldb_filter_from_tree (0, req->op.search.tree)); +#endif + /* Yes, this is a problem with req->op.search.tree being const... */ anr_tree = anr_replace_subtrees(req->op.search.tree, "anr", anr_replace_callback, context); if (!anr_tree) { + talloc_free(context); return LDB_ERR_OPERATIONS_ERROR; } if (context->found_anr) { /* The above function modifies the tree if it finds "anr", so no * point just setting this on the down_req */ +#if 0 + printf("newtree: %s\n", ldb_filter_from_tree (0, anr_tree)); +#endif req->op.search.tree = talloc_steal(req, anr_tree); - + } else { + if (anr_tree != req->op.search.tree) { + talloc_free(anr_tree); + } + talloc_free(context); } return ldb_next_request(module, req); } diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 04b9987071..e64472432d 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -160,7 +160,7 @@ static int setup_modifies(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } - new_msg->dn = ldb_dn_new(new_msg, ldb, (char *)el->values[j].data); + new_msg->dn = ldb_dn_from_ldb_val(new_msg, ldb, &el->values[j]); if (!new_msg->dn) { ldb_asprintf_errstring(ldb, "attribute %s value %s was not a valid DN", msg->elements[i].name, @@ -330,7 +330,7 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb /* Add all the existing elements, marking as 'proposed for delete' by setting .add = false */ for (i=0; i < search_el->num_values; i++) { merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1); - merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)search_el->values[i].data); + merged_list[size].dn = ldb_dn_from_ldb_val(merged_list, ldb, &search_el->values[i]); merged_list[size].add = false; merged_list[size].ignore = false; size++; @@ -339,7 +339,7 @@ static int linked_attributes_mod_replace_search_callback(struct ldb_context *ldb /* Add all the new replacement elements, marking as 'proposed for add' by setting .add = true */ for (i=0; i < ac2->el->num_values; i++) { merged_list = talloc_realloc(ares, merged_list, struct merge, size + 1); - merged_list[size].dn = ldb_dn_new(merged_list, ldb, (char *)ac2->el->values[i].data); + merged_list[size].dn = ldb_dn_from_ldb_val(merged_list, ldb, &ac2->el->values[i]); merged_list[size].add = true; merged_list[size].ignore = false; size++; @@ -610,7 +610,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques ldb_oom(module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - new_msg->dn = ldb_dn_new(new_msg, module->ldb, (char *)el->values[j].data); + new_msg->dn = ldb_dn_from_ldb_val(new_msg, module->ldb, &el->values[j]); if (!new_msg->dn) { ldb_asprintf_errstring(module->ldb, "attribute %s value %s was not a valid DN", req->op.mod.message->elements[i].name, diff --git a/source4/dsdb/samdb/ldb_modules/normalise.c b/source4/dsdb/samdb/ldb_modules/normalise.c index 8de9e33002..3306fd3c33 100644 --- a/source4/dsdb/samdb/ldb_modules/normalise.c +++ b/source4/dsdb/samdb/ldb_modules/normalise.c @@ -112,7 +112,7 @@ static int normalise_search_callback(struct ldb_context *ldb, void *context, str } for (j = 0; j < ares->message->elements[i].num_values; j++) { const char *dn_str; - struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, (const char *)ares->message->elements[i].values[j].data); + struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &ares->message->elements[i].values[j]); if (!dn) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 9285d6d0d8..9cae6ab7b5 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -925,7 +925,7 @@ static int partition_init(struct ldb_module *module) } for (i=0; i < replicate_attributes->num_values; i++) { - data->replicate[i] = ldb_dn_new(data->replicate, module->ldb, (const char *)replicate_attributes->values[i].data); + data->replicate[i] = ldb_dn_from_ldb_val(data->replicate, module->ldb, &replicate_attributes->values[i]); if (!ldb_dn_validate(data->replicate[i])) { ldb_asprintf_errstring(module->ldb, "partition_init: " diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 88590f306b..bd491bd011 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -768,6 +768,10 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req) struct ldb_message_element *el, *el2; int ret; unsigned int group_type, user_account_control, account_type; + if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */ + return ldb_next_request(module, req); + } + if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != NULL) { ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be specified"); return LDB_ERR_UNWILLING_TO_PERFORM; diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index 87ada855d3..968b19c038 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -32,6 +32,40 @@ #include "lib/util/dlinklist.h" #include "param/param.h" +static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema); +static int generate_attributeTypes(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema); +static int generate_dITContentRules(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 *); +} generated_attrs[] = { + { + .attr = "objectClasses", + .fn = generate_objectClasses + }, + { + .attr = "attributeTypes", + .fn = generate_attributeTypes + }, + { + .attr = "dITContentRules", + .fn = generate_dITContentRules + } +}; + +struct schema_fsmo_private_data { + struct ldb_dn *aggregate_dn; +}; + +struct schema_fsmo_search_data { + struct schema_fsmo_private_data *module_context; + struct ldb_request *orig_req; +}; + static int schema_fsmo_init(struct ldb_module *module) { TALLOC_CTX *mem_ctx; @@ -39,10 +73,7 @@ static int schema_fsmo_init(struct ldb_module *module) struct dsdb_schema *schema; char *error_string = NULL; int ret; - - if (dsdb_get_schema(module->ldb)) { - return ldb_next_init(module); - } + struct schema_fsmo_private_data *data; schema_dn = samdb_schema_dn(module->ldb); if (!schema_dn) { @@ -52,6 +83,25 @@ static int schema_fsmo_init(struct ldb_module *module) return ldb_next_init(module); } + data = talloc(module, struct schema_fsmo_private_data); + if (data == NULL) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Check to see if this is a result on the CN=Aggregate schema */ + data->aggregate_dn = ldb_dn_copy(data, schema_dn); + if (!ldb_dn_add_child_fmt(data->aggregate_dn, "CN=Aggregate")) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + module->private_data = data; + + if (dsdb_get_schema(module->ldb)) { + return ldb_next_init(module); + } + mem_ctx = talloc_new(module); if (!mem_ctx) { ldb_oom(module->ldb); @@ -75,6 +125,7 @@ static int schema_fsmo_init(struct ldb_module *module) "schema_fsmo_init: dsdb_schema load failed: %s", error_string); talloc_free(mem_ctx); + return ret; } /* dsdb_set_schema() steal schema into the ldb_context */ @@ -208,9 +259,155 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r return LDB_SUCCESS; } +static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema) +{ + const struct dsdb_class *class; + int ret; + + for (class = schema->classes; class; class = class->next) { + ret = ldb_msg_add_string(msg, "objectClasses", schema_class_to_description(msg, class)); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} +static int generate_attributeTypes(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema) +{ + const struct dsdb_attribute *attribute; + int ret; + + for (attribute = schema->attributes; attribute; attribute = attribute->next) { + ret = ldb_msg_add_string(msg, "attributeTypes", schema_attribute_to_description(msg, attribute)); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} + +static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema) +{ + const struct dsdb_class *class; + int ret; + + for (class = schema->classes; class; class = class->next) { + if (class->auxiliaryClass || class->systemAuxiliaryClass) { + char *ditcontentrule = schema_class_to_dITContentRule(msg, class, schema); + if (!ditcontentrule) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_msg_add_steal_string(msg, "dITContentRules", ditcontentrule); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + return 0; +} + + + +/* Add objectClasses, attributeTypes and dITContentRules from the + schema object (they are not stored in the database) + */ +static int schema_fsmo_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) +{ + const struct dsdb_schema *schema = dsdb_get_schema(ldb); + struct schema_fsmo_search_data *search_data = talloc_get_type(context, struct schema_fsmo_search_data); + struct ldb_request *orig_req = search_data->orig_req; + TALLOC_CTX *mem_ctx; + int i, ret; + + /* Only entries are interesting, and we handle the case of the parent seperatly */ + if (ares->type != LDB_REPLY_ENTRY) { + return orig_req->callback(ldb, orig_req->context, ares); + } + + if (ldb_dn_compare(ares->message->dn, search_data->module_context->aggregate_dn) != 0) { + talloc_free(mem_ctx); + return orig_req->callback(ldb, orig_req->context, ares); + } + + mem_ctx = talloc_new(ares); + if (!mem_ctx) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0; i < ARRAY_SIZE(generated_attrs); i++) { + if (ldb_attr_in_list(orig_req->op.search.attrs, generated_attrs[i].attr)) { + ret = generated_attrs[i].fn(ldb, ares->message, schema); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + talloc_free(mem_ctx); + return orig_req->callback(ldb, orig_req->context, ares); +} + +/* search */ +static int schema_fsmo_search(struct ldb_module *module, struct ldb_request *req) +{ + int i, ret; + struct schema_fsmo_search_data *search_context; + struct ldb_request *down_req; + struct dsdb_schema *schema = dsdb_get_schema(module->ldb); + + if (!schema || !module->private_data) { + /* If there is no schema, there is little we can do */ + return ldb_next_request(module, req); + } + for (i=0; i < ARRAY_SIZE(generated_attrs); i++) { + if (ldb_attr_in_list(req->op.search.attrs, generated_attrs[i].attr)) { + break; + } + } + if (i == ARRAY_SIZE(generated_attrs)) { + /* No request for a generated attr found, nothing to + * see here, move along... */ + return ldb_next_request(module, req); + } + + search_context = talloc(req, struct schema_fsmo_search_data); + if (!search_context) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + down_req = talloc(req, struct ldb_request); + if (!down_req) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + *down_req = *req; + search_context->orig_req = req; + search_context->module_context = talloc_get_type(module->private_data, struct schema_fsmo_private_data); + down_req->context = search_context; + + down_req->callback = schema_fsmo_search_callback; + + ret = ldb_next_request(module, down_req); + + /* do not free down_req as the call results may be linked to it, + * it will be freed when the upper level request get freed */ + if (ret == LDB_SUCCESS) { + req->handle = down_req->handle; + } + return ret; +} + + _PUBLIC_ const struct ldb_module_ops ldb_schema_fsmo_module_ops = { .name = "schema_fsmo", .init_context = schema_fsmo_init, .add = schema_fsmo_add, - .extended = schema_fsmo_extended + .extended = schema_fsmo_extended, + .search = schema_fsmo_search }; diff --git a/source4/dsdb/samdb/ldb_modules/schema_syntax.c b/source4/dsdb/samdb/ldb_modules/schema_syntax.c index d800e4b6d2..ab9f32c913 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_syntax.c +++ b/source4/dsdb/samdb/ldb_modules/schema_syntax.c @@ -248,7 +248,7 @@ static int schema_validate_dn(struct ldb_context *ldb, struct ldb_val *val, int struct ldb_dn *dn; int ret = LDB_SUCCESS; - dn = ldb_dn_new(ldb, ldb, (const char *)val->data); + dn = ldb_dn_from_ldb_val(ldb, ldb, val); if ( ! ldb_dn_validate(dn)) { ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; } diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c index 6e967aab2f..8f92995145 100644 --- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c +++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c @@ -154,7 +154,7 @@ static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC struct ldb_val out = data_blob(NULL, 0); const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(module->ldb, "objectCategory"); - dn = ldb_dn_new(ctx, module->ldb, val->data); + dn = ldb_dn_from_ldb_val(ctx, module->ldb, val); if (dn && ldb_dn_validate(dn)) { talloc_free(dn); return val_copy(module, ctx, val); diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 7c408d0436..428e6b4d4b 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -47,7 +47,7 @@ class MapBaseTestCase(TestCaseInTempDir): ldb.add({"dn": "@PARTITION", "partition": [s4.basedn + ":" + s4.url, s3.basedn + ":" + s3.url], - "replicateEntries": ["@SUBCLASSES", "@ATTRIBUTES", "@INDEXLIST"]}) + "replicateEntries": ["@ATTRIBUTES", "@INDEXLIST"]}) def setUp(self): super(MapBaseTestCase, self).setUp() |