diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/simple_ldap_map.c')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/simple_ldap_map.c | 115 |
1 files changed, 72 insertions, 43 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c index 8f92995145..c353914e2c 100644 --- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c +++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c @@ -36,6 +36,11 @@ #include "librpc/ndr/libndr.h" #include "dsdb/samdb/samdb.h" +struct entryuuid_private { + struct ldb_context *ldb; + struct ldb_dn **base_dns; +}; + static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val) { struct GUID guid; @@ -598,10 +603,18 @@ static int nsuniqueid_init(struct ldb_module *module) return ldb_next_init(module); } -static int get_seq(struct ldb_context *ldb, void *context, - struct ldb_reply *ares) +static int get_seq_callback(struct ldb_request *req, + struct ldb_reply *ares) { - unsigned long long *seq = (unsigned long long *)context; + unsigned long long *seq = (unsigned long long *)req->context; + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + if (ares->type == LDB_REPLY_ENTRY) { struct ldb_message_element *el = ldb_msg_find_element(ares->message, "contextCSN"); if (el) { @@ -609,6 +622,11 @@ static int get_seq(struct ldb_context *ldb, void *context, } } + if (ares->type == LDB_REPLY_DONE) { + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); return LDB_SUCCESS; } @@ -617,7 +635,7 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque int ret; struct map_private *map_private; struct entryuuid_private *entryuuid_private; - unsigned long long seq = 0; + unsigned long long seq_num = 0; struct ldb_request *search_req; const struct ldb_control *partition_ctrl; @@ -627,6 +645,12 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque "contextCSN", NULL }; + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *seqr; + struct ldb_extended *ext; + + seq = talloc_get_type(req->op.extended.data, struct ldb_seqnum_request); + map_private = talloc_get_type(module->private_data, struct map_private); entryuuid_private = talloc_get_type(map_private->caller_private, struct entryuuid_private); @@ -635,7 +659,7 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque 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"); + "entryuuid_sequence_number: no current partition control found"); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -643,74 +667,79 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque 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; + ret = ldb_build_search_req(&search_req, module->ldb, req, + partition->dn, LDB_SCOPE_BASE, + NULL, contextCSN_attr, NULL, + &seq_num, get_seq_callback, + NULL); + if (ret != LDB_SUCCESS) { + return ret; } - - /* 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); - 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) { + ext = talloc_zero(req, struct ldb_extended); + if (!ext) { + return LDB_ERR_OPERATIONS_ERROR; + } + seqr = talloc_zero(req, struct ldb_seqnum_result); + if (seqr == NULL) { + talloc_free(ext); + return LDB_ERR_OPERATIONS_ERROR; + } + ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER; + ext->data = seqr; + + switch (seq->type) { case LDB_SEQ_HIGHEST_SEQ: - req->op.seq_num.seq_num = seq; + seqr->seq_num = seq_num; break; case LDB_SEQ_NEXT: - req->op.seq_num.seq_num = seq; - req->op.seq_num.seq_num++; + seqr->seq_num = seq_num; + seqr->seq_num++; break; case LDB_SEQ_HIGHEST_TIMESTAMP: { - req->op.seq_num.seq_num = (seq >> 24); + seqr->seq_num = (seq_num >> 24); break; } } - req->op.seq_num.flags = 0; - req->op.seq_num.flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; - req->op.seq_num.flags |= LDB_SEQ_GLOBAL_SEQUENCE; - return LDB_SUCCESS; + seqr->flags = 0; + seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; + seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE; + + /* send request done */ + return ldb_module_done(req, NULL, ext, LDB_SUCCESS); +} + +static int entryuuid_extended(struct ldb_module *module, struct ldb_request *req) +{ + if (strcmp(req->op.extended.oid, LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { + return entryuuid_sequence_number(module, req); + } + + return ldb_next_request(module, req); } _PUBLIC_ const struct ldb_module_ops ldb_entryuuid_module_ops = { .name = "entryuuid", .init_context = entryuuid_init, - .sequence_number = entryuuid_sequence_number, + .extended = entryuuid_extended, LDB_MAP_OPS }; _PUBLIC_ const struct ldb_module_ops ldb_nsuniqueid_module_ops = { .name = "nsuniqueid", .init_context = nsuniqueid_init, - .sequence_number = entryuuid_sequence_number, + .extended = entryuuid_extended, LDB_MAP_OPS }; |