diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/partition.c | 5 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/simple_ldap_map.c | 208 |
2 files changed, 68 insertions, 145 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 7f136338be..22826e4f33 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -599,6 +599,11 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque for (i=0; data && data->partitions && data->partitions[i]; i++) { struct ldb_module *next = make_module_for_next_request(req, module->ldb, data->partitions[i]->module); + ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, data->partitions[i]); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_next_request(next, req); talloc_free(next); if (ret != LDB_SUCCESS) { diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c index 05f11003c4..5da321b9e5 100644 --- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c +++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c @@ -34,10 +34,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/ndr/libndr.h" - -struct entryuuid_private { - struct ldb_dn **base_dns; -}; +#include "dsdb/samdb/samdb.h" static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val) { @@ -579,96 +576,14 @@ static const char * const nsuniqueid_wildcard_attributes[] = { NULL }; -static int get_remote_rootdse(struct ldb_context *ldb, void *context, - struct ldb_reply *ares) -{ - struct entryuuid_private *entryuuid_private; - entryuuid_private = talloc_get_type(context, - struct entryuuid_private); - if (ares->type == LDB_REPLY_ENTRY) { - int i; - struct ldb_message_element *el = ldb_msg_find_element(ares->message, "namingContexts"); - entryuuid_private->base_dns = talloc_realloc(entryuuid_private, entryuuid_private->base_dns, struct ldb_dn *, - el->num_values + 1); - for (i=0; i < el->num_values; i++) { - if (!entryuuid_private->base_dns) { - return LDB_ERR_OPERATIONS_ERROR; - } - entryuuid_private->base_dns[i] = ldb_dn_new(entryuuid_private->base_dns, ldb, (const char *)el->values[i].data); - if ( ! ldb_dn_validate(entryuuid_private->base_dns[i])) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - entryuuid_private->base_dns[i] = NULL; - } - - return LDB_SUCCESS; -} - -static int find_base_dns(struct ldb_module *module, - struct entryuuid_private *entryuuid_private) -{ - int ret; - struct ldb_request *req; - const char *naming_context_attr[] = { - "namingContexts", - NULL - }; - req = talloc(entryuuid_private, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEARCH; - req->op.search.base = ldb_dn_new(req, module->ldb, NULL); - req->op.search.scope = LDB_SCOPE_BASE; - - req->op.search.tree = ldb_parse_tree(req, "objectClass=*"); - if (req->op.search.tree == NULL) { - ldb_set_errstring(module->ldb, "Unable to parse search expression"); - talloc_free(req); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.search.attrs = naming_context_attr; - req->controls = NULL; - req->context = entryuuid_private; - req->callback = get_remote_rootdse; - ldb_set_timeout(module->ldb, req, 0); /* use default timeout */ - - ret = ldb_next_request(module, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - talloc_free(req); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - /* the context init function */ static int entryuuid_init(struct ldb_module *module) { int ret; - struct map_private *map_private; - struct entryuuid_private *entryuuid_private; - ret = ldb_map_init(module, entryuuid_attributes, entryuuid_objectclasses, entryuuid_wildcard_attributes, "samba4Top", NULL); if (ret != LDB_SUCCESS) return ret; - map_private = talloc_get_type(module->private_data, struct map_private); - - entryuuid_private = talloc_zero(map_private, struct entryuuid_private); - map_private->caller_private = entryuuid_private; - - ret = find_base_dns(module, entryuuid_private); - return ldb_next_init(module); } @@ -676,33 +591,21 @@ static int entryuuid_init(struct ldb_module *module) static int nsuniqueid_init(struct ldb_module *module) { int ret; - struct map_private *map_private; - struct entryuuid_private *entryuuid_private; - ret = ldb_map_init(module, nsuniqueid_attributes, NULL, nsuniqueid_wildcard_attributes, "samba4Top", NULL); if (ret != LDB_SUCCESS) return ret; - map_private = talloc_get_type(module->private_data, struct map_private); - - entryuuid_private = talloc_zero(map_private, struct entryuuid_private); - map_private->caller_private = entryuuid_private; - - ret = find_base_dns(module, entryuuid_private); - return ldb_next_init(module); } static int get_seq(struct ldb_context *ldb, void *context, struct ldb_reply *ares) { - unsigned long long *max_seq = (unsigned long long *)context; - unsigned long long seq; + unsigned long long *seq = (unsigned long long *)context; if (ares->type == LDB_REPLY_ENTRY) { struct ldb_message_element *el = ldb_msg_find_element(ares->message, "contextCSN"); if (el) { - seq = entryCSN_to_usn_int(ares, &el->values[0]); - *max_seq = MAX(seq, *max_seq); + *seq = entryCSN_to_usn_int(ares, &el->values[0]); } } @@ -711,69 +614,84 @@ static int get_seq(struct ldb_context *ldb, void *context, static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_request *req) { - int i, ret; + int ret; struct map_private *map_private; struct entryuuid_private *entryuuid_private; - unsigned long long max_seq = 0; + unsigned long long seq = 0; struct ldb_request *search_req; + + const struct ldb_control *partition_ctrl; + const struct dsdb_control_current_partition *partition; + + static const char *contextCSN_attr[] = { + "contextCSN", NULL + }; + map_private = talloc_get_type(module->private_data, struct map_private); entryuuid_private = talloc_get_type(map_private->caller_private, struct entryuuid_private); - /* Search the baseDNs for a sequence number */ - for (i=0; entryuuid_private && - entryuuid_private->base_dns && - entryuuid_private->base_dns[i]; - i++) { - static const char *contextCSN_attr[] = { - "contextCSN", NULL - }; - search_req = talloc(req, struct ldb_request); - if (search_req == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - search_req->operation = LDB_SEARCH; - search_req->op.search.base = entryuuid_private->base_dns[i]; - search_req->op.search.scope = LDB_SCOPE_BASE; - - search_req->op.search.tree = ldb_parse_tree(search_req, "objectClass=*"); - if (search_req->op.search.tree == NULL) { - ldb_set_errstring(module->ldb, "Unable to parse search expression"); - talloc_free(search_req); - return LDB_ERR_OPERATIONS_ERROR; - } - - search_req->op.search.attrs = contextCSN_attr; - search_req->controls = NULL; - search_req->context = &max_seq; - search_req->callback = get_seq; - ldb_set_timeout(module->ldb, search_req, 0); /* use default timeout */ - - ret = ldb_next_request(module, search_req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(search_req->handle, LDB_WAIT_ALL); - } - + /* All this to get the DN of the parition, so we can search the right thing */ + partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID); + if (!partition_ctrl) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "instancetype_add: no current partition control found"); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + partition = talloc_get_type(partition_ctrl->data, + struct dsdb_control_current_partition); + SMB_ASSERT(partition && partition->version == DSDB_CONTROL_CURRENT_PARTITION_VERSION); + + search_req = talloc(req, struct ldb_request); + if (search_req == NULL) { + ldb_set_errstring(module->ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Finally, we have it. This saves searching over more + * partitions than we expose to the client, such as a cn=samba + * configuration partition */ + + search_req->operation = LDB_SEARCH; + search_req->op.search.base = partition->dn; + search_req->op.search.scope = LDB_SCOPE_BASE; + + search_req->op.search.tree = ldb_parse_tree(search_req, "objectClass=*"); + if (search_req->op.search.tree == NULL) { + ldb_set_errstring(module->ldb, "Unable to parse search expression"); talloc_free(search_req); - if (ret != LDB_SUCCESS) { - return ret; - } + return LDB_ERR_OPERATIONS_ERROR; + } + + search_req->op.search.attrs = contextCSN_attr; + search_req->controls = NULL; + search_req->context = &seq; + search_req->callback = get_seq; + ldb_set_timeout(module->ldb, search_req, 0); /* use default timeout */ + + ret = ldb_next_request(module, search_req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(search_req->handle, LDB_WAIT_ALL); + } + + talloc_free(search_req); + if (ret != LDB_SUCCESS) { + return ret; } switch (req->op.seq_num.type) { case LDB_SEQ_HIGHEST_SEQ: - req->op.seq_num.seq_num = max_seq; + req->op.seq_num.seq_num = seq; break; case LDB_SEQ_NEXT: - req->op.seq_num.seq_num = max_seq; + req->op.seq_num.seq_num = seq; req->op.seq_num.seq_num++; break; case LDB_SEQ_HIGHEST_TIMESTAMP: { - req->op.seq_num.seq_num = (max_seq >> 24); + req->op.seq_num.seq_num = (seq >> 24); break; } } |