From f77c4100842f8c5357fa90822e04319810a04b8d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 15 Jun 2006 18:04:24 +0000 Subject: r16264: Add, but do not yet enable, the partitions module. This required changes to the rootDSE module, to allow registration of partitions. In doing so I renamed the 'register' operation to 'register_control' and 'register_partition', which changed a few more modules. Due to the behaviour of certain LDAP servers, we create the baseDN entry in two parts: Firstly, we allow the admin to export a simple LDIF file to add to their server. Then we perform a modify to add the remaining attributes. To delete all users in partitions, we must now search and delete all objects in the partition, rather than a simple search from the root. Against LDAP, this might not delete all objects, so we allow this to fail. In testing, we found that the 'Domain Controllers' container was misnamed, and should be 'CN=', rather than 'OU='. To avoid the Templates being found in default searches, they have been moved to CN=Templates from CN=Templates,${BASEDN}. Andrew Bartlett (This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a) --- source4/dsdb/samdb/ldb_modules/partition.c | 297 +++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 source4/dsdb/samdb/ldb_modules/partition.c (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c new file mode 100644 index 0000000000..6d3d42c23a --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -0,0 +1,297 @@ +/* + Partitions ldb module + + Copyright (C) Andrew Bartlett 2006 + + * NOTICE: this module is NOT released under the GNU LGPL license as + * other ldb code. This module is release under the GNU GPL v2 or + * later license. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Name: ldb + * + * Component: ldb partitions module + * + * Description: Implement LDAP partitions + * + * Author: Andrew Bartlett + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +struct partition { + struct ldb_module *module; + const char *backend; + struct ldb_dn *dn; +}; +struct partition_private_data { + struct partition **partitions; +}; + +struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) +{ + int i; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + for (i=0; data && data->partitions && data->partitions[i]; i++) { + if (ldb_dn_compare_base(module->ldb, + data->partitions[i]->dn, + dn) == 0) { + struct ldb_module *current; + static const struct ldb_module_ops ops; /* zero */ + current = talloc_zero(req, struct ldb_module); + if (current == NULL) { + return module; + } + + current->ldb = module->ldb; + current->ops = &ops; + current->prev = module; + current->next = data->partitions[i]->module; + return current; + } + } + + return module; +}; + +/* search */ +static int partition_search(struct ldb_module *module, struct ldb_request *req) +{ + /* Find backend */ + struct ldb_module *backend = find_backend(module, req, req->op.search.base); + + /* issue request */ + + /* (later) consider if we should be searching multiple + * partitions (for 'invisible' partition behaviour */ + return ldb_next_request(backend, req); +} + +/* add */ +static int partition_add(struct ldb_module *module, struct ldb_request *req) +{ + /* Find backend */ + struct ldb_module *backend = find_backend(module, req, req->op.add.message->dn); + + /* issue request */ + + return ldb_next_request(backend, req); +} + +/* modify */ +static int partition_modify(struct ldb_module *module, struct ldb_request *req) +{ + /* Find backend */ + struct ldb_module *backend = find_backend(module, req, req->op.mod.message->dn); + + /* issue request */ + + return ldb_next_request(backend, req); +} + +/* delete */ +static int partition_delete(struct ldb_module *module, struct ldb_request *req) +{ + /* Find backend */ + struct ldb_module *backend = find_backend(module, req, req->op.del.dn); + + /* issue request */ + + return ldb_next_request(backend, req); +} + +/* rename */ +static int partition_rename(struct ldb_module *module, struct ldb_request *req) +{ + /* Find backend */ + struct ldb_module *backend = find_backend(module, req, req->op.rename.olddn); + struct ldb_module *backend2 = find_backend(module, req, req->op.rename.newdn); + + if (backend->next != backend2->next) { + return LDB_ERR_AFFECTS_MULTIPLE_DSAS; + } + + /* issue request */ + + /* (later) consider if we should be searching multiple partitions */ + return ldb_next_request(backend, req); +} + +#if 0 +/* We should do this over the entire list of partitions */ + +/* start a transaction */ +static int partition_start_trans(struct ldb_module *module) +{ + return ldb_next_start_trans(module); +} + +/* end a transaction */ +static int partition_end_trans(struct ldb_module *module) +{ + return ldb_next_end_trans(module); +} + +/* delete a transaction */ +static int partition_del_trans(struct ldb_module *module) +{ + return ldb_next_del_trans(module); +} +#endif + +static int partition_init(struct ldb_module *module) +{ + int ret, i; + TALLOC_CTX *mem_ctx = talloc_new(module); + static const char *attrs[] = { "partition", NULL }; + struct ldb_result *res; + struct ldb_message *msg; + struct ldb_message_element *partition_attributes; + + struct partition_private_data *data; + + if (!mem_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + data = talloc(mem_ctx, struct partition_private_data); + if (data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search(module->ldb, ldb_dn_explode(mem_ctx, "@PARTITION"), + LDB_SCOPE_BASE, + NULL, attrs, + &res); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + talloc_steal(mem_ctx, res); + if (res->count == 0) { + talloc_free(mem_ctx); + return ldb_next_init(module); + } + + if (res->count > 1) { + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + msg = res->msgs[0]; + + partition_attributes = ldb_msg_find_element(msg, "partition"); + if (!partition_attributes) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "no partitions specified")); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + data->partitions = talloc_array(data, struct partition *, partition_attributes->num_values + 1); + if (!data->partitions) { + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + for (i=0; i < partition_attributes->num_values; i++) { + struct ldb_request *req; + + char *base = talloc_strdup(data->partitions, (char *)partition_attributes->values[i].data); + char *p = strchr(base, ':'); + if (!p) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "invalid form for partition record (missing ':'): %s", base)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + p[0] = '\0'; + p++; + if (!p[0]) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "invalid form for partition record (missing backend database): %s", base)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + data->partitions[i] = talloc(data->partitions, struct partition); + if (!data->partitions[i]) { + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + data->partitions[i]->dn = ldb_dn_explode(data->partitions[i], base); + if (!data->partitions[i]->dn) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "invalid DN in partition record: %s", base)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + data->partitions[i]->backend = private_path(data->partitions[i], p); + ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, 0, NULL, &data->partitions[i]->module); + if (ret != LDB_SUCCESS) { + return ret; + } + + req = talloc_zero(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out of memory!\n"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_REQ_REGISTER_PARTITION; + req->op.reg_partition.dn = data->partitions[i]->dn; + + ret = ldb_request(module->ldb, req); + if (ret != LDB_SUCCESS) { + ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Unable to register partition with rootdse!\n"); + return LDB_ERR_OTHER; + } + talloc_free(req); + } + data->partitions[i] = NULL; + + module->private_data = data; + talloc_steal(module, data); + + talloc_free(mem_ctx); + return ldb_next_init(module); +} + +static const struct ldb_module_ops partition_ops = { + .name = "partition", + .init_context = partition_init, + .search = partition_search, + .add = partition_add, + .modify = partition_modify, + .del = partition_delete, + .rename = partition_rename, +#if 0 + .start_transaction = partition_start_trans, + .end_transaction = partition_end_trans, + .del_transaction = partition_del_trans, +#endif +}; + +int ldb_partition_init(void) +{ + return ldb_register_module(&partition_ops); +} -- cgit From bfc02627ceb02046fb23c62f28dc69765c8aa8f0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Jul 2006 11:24:46 +0000 Subject: r16914: Add more tests for the partition module. Andrew Bartlett (This used to be commit 2728b60dfa50ded03e06f0bd53eee55fce5143bd) --- source4/dsdb/samdb/ldb_modules/partition.c | 162 ++++++++++++++++++++++++----- 1 file changed, 137 insertions(+), 25 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6d3d42c23a..c7c9aa7cfe 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -44,6 +44,24 @@ struct partition_private_data { struct partition **partitions; }; +struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + struct ldb_module *module) +{ + struct ldb_module *current; + static const struct ldb_module_ops ops; /* zero */ + current = talloc_zero(mem_ctx, struct ldb_module); + if (current == NULL) { + return module; + } + + current->ldb = ldb; + current->ops = &ops; + current->prev = NULL; + current->next = module; + return current; +} + struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) { int i; @@ -56,18 +74,7 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r if (ldb_dn_compare_base(module->ldb, data->partitions[i]->dn, dn) == 0) { - struct ldb_module *current; - static const struct ldb_module_ops ops; /* zero */ - current = talloc_zero(req, struct ldb_module); - if (current == NULL) { - return module; - } - - current->ldb = module->ldb; - current->ops = &ops; - current->prev = module; - current->next = data->partitions[i]->module; - return current; + return make_module_for_next_request(req, module->ldb, data->partitions[i]->module); } } @@ -137,27 +144,128 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(backend, req); } -#if 0 -/* We should do this over the entire list of partitions */ - /* start a transaction */ static int partition_start_trans(struct ldb_module *module) { - return ldb_next_start_trans(module); + int i, ret; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + ret = ldb_next_start_trans(module); + if (ret != LDB_SUCCESS) { + return ret; + } + + for (i=0; data && data->partitions && data->partitions[i]; i++) { + struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module); + + ret = ldb_next_start_trans(next); + talloc_free(next); + if (ret != LDB_SUCCESS) { + /* Back it out, if it fails on one */ + for (i--; i >= 0; i--) { + next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module); + ldb_next_del_trans(next); + talloc_free(next); + } + return ret; + } + } + return LDB_SUCCESS; } /* end a transaction */ static int partition_end_trans(struct ldb_module *module) { - return ldb_next_end_trans(module); + int i, ret, ret2 = LDB_SUCCESS; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + ret = ldb_next_end_trans(module); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + for (i=0; data && data->partitions && data->partitions[i]; i++) { + struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module); + + ret = ldb_next_end_trans(next); + talloc_free(next); + if (ret != LDB_SUCCESS) { + ret2 = ret; + } + } + + if (ret != LDB_SUCCESS) { + /* Back it out, if it fails on one */ + for (i=0; data && data->partitions && data->partitions[i]; i++) { + struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module); + ldb_next_del_trans(next); + talloc_free(next); + } + } + return ret; } /* delete a transaction */ static int partition_del_trans(struct ldb_module *module) { - return ldb_next_del_trans(module); + int i, ret, ret2 = LDB_SUCCESS; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + for (i=0; data && data->partitions && data->partitions[i]; i++) { + struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module); + + ret = ldb_next_del_trans(next); + talloc_free(next); + if (ret != LDB_SUCCESS) { + ret2 = ret; + } + } + return ret2; +} + +static int partition_sequence_number(struct ldb_module *module, struct ldb_request *req) +{ + int i, ret; + uint64_t seq_number = 0; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + 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_next_request(next, req); + talloc_free(next); + if (ret != LDB_SUCCESS) { + return ret; + } + seq_number = seq_number + req->op.seq_num.seq_num; + } + req->op.seq_num.seq_num = seq_number; + return LDB_SUCCESS; +} + +static int sort_compare(void *void1, + void *void2, void *opaque) +{ + struct ldb_context *ldb = talloc_get_type(opaque, struct ldb_context); + struct partition **pp1 = void1; + struct partition **pp2 = void2; + struct partition *partition1 = talloc_get_type(*pp1, struct partition); + struct partition *partition2 = talloc_get_type(*pp2, struct partition); + + return -ldb_dn_compare(ldb, partition1->dn, partition2->dn); } -#endif static int partition_init(struct ldb_module *module) { @@ -213,8 +321,6 @@ static int partition_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } for (i=0; i < partition_attributes->num_values; i++) { - struct ldb_request *req; - char *base = talloc_strdup(data->partitions, (char *)partition_attributes->values[i].data); char *p = strchr(base, ':'); if (!p) { @@ -250,7 +356,15 @@ static int partition_init(struct ldb_module *module) if (ret != LDB_SUCCESS) { return ret; } - + } + data->partitions[i] = NULL; + + /* sort these into order */ + ldb_qsort(data->partitions, partition_attributes->num_values, sizeof(*data->partitions), + module->ldb, sort_compare); + + for (i=0; data->partitions[i]; i++) { + struct ldb_request *req; req = talloc_zero(mem_ctx, struct ldb_request); if (req == NULL) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out of memory!\n"); @@ -267,7 +381,6 @@ static int partition_init(struct ldb_module *module) } talloc_free(req); } - data->partitions[i] = NULL; module->private_data = data; talloc_steal(module, data); @@ -284,11 +397,10 @@ static const struct ldb_module_ops partition_ops = { .modify = partition_modify, .del = partition_delete, .rename = partition_rename, -#if 0 .start_transaction = partition_start_trans, .end_transaction = partition_end_trans, .del_transaction = partition_del_trans, -#endif + .sequence_number = partition_sequence_number }; int ldb_partition_init(void) -- cgit From fdbbabe60223062ac72f1853d3c236a1de8ebe0e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 11 Jul 2006 02:04:43 +0000 Subject: r16933: Sort the partitions in order from most, to least specific. Remember to perform operations on the base database as well. Andrew Bartlett (This used to be commit eae232530c967fe949355cf1914ca0cb8c0ea8c2) --- source4/dsdb/samdb/ldb_modules/partition.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index c7c9aa7cfe..05ba701653 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -217,6 +217,11 @@ static int partition_del_trans(struct ldb_module *module) int i, ret, ret2 = LDB_SUCCESS; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); + ret = ldb_next_del_trans(module); + if (ret != LDB_SUCCESS) { + ret2 = ret; + } + /* Look at base DN */ /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ @@ -238,6 +243,12 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque uint64_t seq_number = 0; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); + ret = ldb_next_request(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + seq_number = seq_number + req->op.seq_num.seq_num; + /* Look at base DN */ /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ @@ -264,7 +275,7 @@ static int sort_compare(void *void1, struct partition *partition1 = talloc_get_type(*pp1, struct partition); struct partition *partition2 = talloc_get_type(*pp2, struct partition); - return -ldb_dn_compare(ldb, partition1->dn, partition2->dn); + return ldb_dn_compare(ldb, partition1->dn, partition2->dn); } static int partition_init(struct ldb_module *module) @@ -359,7 +370,7 @@ static int partition_init(struct ldb_module *module) } data->partitions[i] = NULL; - /* sort these into order */ + /* sort these into order, most to least specific */ ldb_qsort(data->partitions, partition_attributes->num_values, sizeof(*data->partitions), module->ldb, sort_compare); -- cgit From 32ab51876728577375b954a04103f71ddd4d93dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 12 Jul 2006 04:59:41 +0000 Subject: r16972: Replace the sequence_number function pointer in ldb with the ldb flags. The function pointer was meant to be unused, this patch fixes partition.c to use ldb_sequence_number(). (No backend provided the pointer any more). Set the flags onto the ldb structure, so that all backends opened by the partitions module inherit the flags. Set the read-ony flag when accessed as the global catalog Modify the LDAP server to track that this query is for the global catalog (by incoming port), and set a opqaue pointer. Next step is to read that opaque pointer in the partitions module. Andrew Bartlett (This used to be commit a1161cb30e4ffa09657a89e03ca85dd6efd4feba) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 05ba701653..6f41513200 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -363,7 +363,7 @@ static int partition_init(struct ldb_module *module) } data->partitions[i]->backend = private_path(data->partitions[i], p); - ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, 0, NULL, &data->partitions[i]->module); + ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module); if (ret != LDB_SUCCESS) { return ret; } -- cgit From 37eab825287d73f2b2b79342369d17da56dca5dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Jul 2006 22:36:04 +0000 Subject: r17103: Big updates to the not-yet-enabled partitions module. It now services the Global Catalog port 'correctly' (in a very simple sense) in that it should be no worse than what we had before. We now combine partitions together to search over the whole tree, when we are marked as 'global catalog'. Andrew Bartlett (This used to be commit 0a354a1ddeccd9a6b1610bc6813a86fcdfc4d310) --- source4/dsdb/samdb/ldb_modules/partition.c | 193 ++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6f41513200..f523119e21 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -44,6 +44,43 @@ struct partition_private_data { struct partition **partitions; }; +struct partition_async_context { + struct ldb_module *module; + struct ldb_request *orig_req; + + struct ldb_request **search_req; + BOOL *finished_search; + int num_searches; +}; + +static struct ldb_async_handle *partition_init_handle(struct ldb_request *req, struct ldb_module *module) +{ + struct partition_async_context *ac; + struct ldb_async_handle *h; + + h = talloc_zero(req, struct ldb_async_handle); + if (h == NULL) { + ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); + return NULL; + } + + h->module = module; + + ac = talloc_zero(h, struct partition_async_context); + if (ac == NULL) { + ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); + talloc_free(h); + return NULL; + } + + h->private_data = (void *)ac; + + ac->module = module; + ac->orig_req = req; + + return h; +} + struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_module *module) @@ -81,17 +118,98 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r return module; }; +static int partition_send_search(struct partition_async_context *ac, struct ldb_module *partition) +{ + int ret; + struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition); + + ac->search_req = talloc_realloc(ac, ac->search_req, + struct ldb_request *, ac->num_searches + 1); + if (!ac->search_req) { + ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->search_req[ac->num_searches] = talloc(ac, struct ldb_request); + if (ac->search_req[ac->num_searches] == NULL) { + ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); + return LDB_ERR_OPERATIONS_ERROR; + } + + *ac->search_req[ac->num_searches] = *ac->orig_req; /* copy the request */ + + /* Spray off search requests to all backends */ + ret = ldb_next_request(next, ac->search_req[ac->num_searches]); + if (ret != LDB_SUCCESS) { + return ret; + } + + ac->num_searches++; + return LDB_SUCCESS; +} + /* search */ static int partition_search(struct ldb_module *module, struct ldb_request *req) { /* Find backend */ - struct ldb_module *backend = find_backend(module, req, req->op.search.base); - + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); /* issue request */ /* (later) consider if we should be searching multiple * partitions (for 'invisible' partition behaviour */ - return ldb_next_request(backend, req); + if (ldb_get_opaque(module->ldb, "global_catalog")) { + int ret, i; + struct ldb_async_handle *h; + struct partition_async_context *ac; + + h = partition_init_handle(req, module); + if (!h) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* return our own handle to deal with this call */ + req->async.handle = h; + + ac = talloc_get_type(h->private_data, struct partition_async_context); + + ac->orig_req = req; + ac->num_searches = 0; + + for (i=0; data && data->partitions && data->partitions[i]; i++) { + /* Find all partitions under the search base */ + if (ldb_dn_compare_base(module->ldb, + req->op.search.base, + data->partitions[i]->dn) == 0) { + ret = partition_send_search(ac, data->partitions[i]->module); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + /* Perhaps we didn't match any partitions. Try the main partition, then all partitions */ + if (ac->num_searches == 0) { + ret = partition_send_search(ac, module->next); + if (ret != LDB_SUCCESS) { + return ret; + } + for (i=0; data && data->partitions && data->partitions[i]; i++) { + ret = partition_send_search(ac, data->partitions[i]->module); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + ac->finished_search = talloc_zero_array(ac, BOOL, ac->num_searches); + if (!ac->finished_search) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; + } else { + struct ldb_module *backend = find_backend(module, req, req->op.search.base); + + return ldb_next_request(backend, req); + } } /* add */ @@ -400,6 +518,72 @@ static int partition_init(struct ldb_module *module) return ldb_next_init(module); } +static int partition_async_wait_none(struct ldb_async_handle *handle) { + struct partition_async_context *ac; + int ret; + int i; + + if (!handle || !handle->private_data) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (handle->state == LDB_ASYNC_DONE) { + return handle->status; + } + + handle->state = LDB_ASYNC_PENDING; + handle->status = LDB_SUCCESS; + + ac = talloc_get_type(handle->private_data, struct partition_async_context); + + for (i=0; i < ac->num_searches; i++) { + ret = ldb_async_wait(ac->search_req[i]->async.handle, LDB_WAIT_NONE); + + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->search_req[i]->async.handle->status != LDB_SUCCESS) { + handle->status = ac->search_req[i]->async.handle->status; + goto done; + } + + if (ac->search_req[i]->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; + } + } + + ret = LDB_SUCCESS; + +done: + handle->state = LDB_ASYNC_DONE; + return ret; +} + + +static int partition_async_wait_all(struct ldb_async_handle *handle) { + + int ret; + + while (handle->state != LDB_ASYNC_DONE) { + ret = partition_async_wait_none(handle); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return handle->status; +} + +static int partition_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type) +{ + if (type == LDB_WAIT_ALL) { + return partition_async_wait_all(handle); + } else { + return partition_async_wait_none(handle); + } +} + static const struct ldb_module_ops partition_ops = { .name = "partition", .init_context = partition_init, @@ -411,7 +595,8 @@ static const struct ldb_module_ops partition_ops = { .start_transaction = partition_start_trans, .end_transaction = partition_end_trans, .del_transaction = partition_del_trans, - .sequence_number = partition_sequence_number + .sequence_number = partition_sequence_number, + .async_wait = partition_async_wait }; int ldb_partition_init(void) -- cgit From c93817b36d3ff7f44cb7b3e1d1a29e37ec12affe Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 22 Jul 2006 16:56:33 +0000 Subject: r17185: Oh, I wanted to do this for sooo long time. Finally acknowledge that ldb is inherently async and does not have a dual personality anymore Rename all ldb_async_XXX functions to ldb_XXX except for ldb_async_result, it is now ldb_reply to reflect the real function of this structure. Simo. (This used to be commit 25fc7354049d62efeba17681ef1cdd326bc3f2ef) --- source4/dsdb/samdb/ldb_modules/partition.c | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index f523119e21..0dcf710ba4 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -44,7 +44,7 @@ struct partition_private_data { struct partition **partitions; }; -struct partition_async_context { +struct partition_context { struct ldb_module *module; struct ldb_request *orig_req; @@ -53,12 +53,12 @@ struct partition_async_context { int num_searches; }; -static struct ldb_async_handle *partition_init_handle(struct ldb_request *req, struct ldb_module *module) +static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct ldb_module *module) { - struct partition_async_context *ac; - struct ldb_async_handle *h; + struct partition_context *ac; + struct ldb_handle *h; - h = talloc_zero(req, struct ldb_async_handle); + h = talloc_zero(req, struct ldb_handle); if (h == NULL) { ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); return NULL; @@ -66,7 +66,7 @@ static struct ldb_async_handle *partition_init_handle(struct ldb_request *req, s h->module = module; - ac = talloc_zero(h, struct partition_async_context); + ac = talloc_zero(h, struct partition_context); if (ac == NULL) { ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); talloc_free(h); @@ -118,7 +118,7 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r return module; }; -static int partition_send_search(struct partition_async_context *ac, struct ldb_module *partition) +static int partition_send_search(struct partition_context *ac, struct ldb_module *partition) { int ret; struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition); @@ -159,8 +159,8 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) * partitions (for 'invisible' partition behaviour */ if (ldb_get_opaque(module->ldb, "global_catalog")) { int ret, i; - struct ldb_async_handle *h; - struct partition_async_context *ac; + struct ldb_handle *h; + struct partition_context *ac; h = partition_init_handle(req, module); if (!h) { @@ -169,7 +169,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* return our own handle to deal with this call */ req->async.handle = h; - ac = talloc_get_type(h->private_data, struct partition_async_context); + ac = talloc_get_type(h->private_data, struct partition_context); ac->orig_req = req; ac->num_searches = 0; @@ -518,8 +518,8 @@ static int partition_init(struct ldb_module *module) return ldb_next_init(module); } -static int partition_async_wait_none(struct ldb_async_handle *handle) { - struct partition_async_context *ac; +static int partition_wait_none(struct ldb_handle *handle) { + struct partition_context *ac; int ret; int i; @@ -534,10 +534,10 @@ static int partition_async_wait_none(struct ldb_async_handle *handle) { handle->state = LDB_ASYNC_PENDING; handle->status = LDB_SUCCESS; - ac = talloc_get_type(handle->private_data, struct partition_async_context); + ac = talloc_get_type(handle->private_data, struct partition_context); for (i=0; i < ac->num_searches; i++) { - ret = ldb_async_wait(ac->search_req[i]->async.handle, LDB_WAIT_NONE); + ret = ldb_wait(ac->search_req[i]->async.handle, LDB_WAIT_NONE); if (ret != LDB_SUCCESS) { handle->status = ret; @@ -561,12 +561,12 @@ done: } -static int partition_async_wait_all(struct ldb_async_handle *handle) { +static int partition_wait_all(struct ldb_handle *handle) { int ret; while (handle->state != LDB_ASYNC_DONE) { - ret = partition_async_wait_none(handle); + ret = partition_wait_none(handle); if (ret != LDB_SUCCESS) { return ret; } @@ -575,12 +575,12 @@ static int partition_async_wait_all(struct ldb_async_handle *handle) { return handle->status; } -static int partition_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type) +static int partition_wait(struct ldb_handle *handle, enum ldb_wait_type type) { if (type == LDB_WAIT_ALL) { - return partition_async_wait_all(handle); + return partition_wait_all(handle); } else { - return partition_async_wait_none(handle); + return partition_wait_none(handle); } } @@ -596,7 +596,7 @@ static const struct ldb_module_ops partition_ops = { .end_transaction = partition_end_trans, .del_transaction = partition_del_trans, .sequence_number = partition_sequence_number, - .async_wait = partition_async_wait + .wait = partition_wait }; int ldb_partition_init(void) -- cgit From 49f68caed20d2a7d1850e493005bdf85929d6365 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 22 Jul 2006 17:21:59 +0000 Subject: r17186: "async" word abuse clean-up part 2 (This used to be commit c6aa60c7e69abf1f83efc150b1c3ed02751c45fc) --- source4/dsdb/samdb/ldb_modules/partition.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 0dcf710ba4..92fddca270 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -167,7 +167,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } /* return our own handle to deal with this call */ - req->async.handle = h; + req->handle = h; ac = talloc_get_type(h->private_data, struct partition_context); @@ -537,18 +537,18 @@ static int partition_wait_none(struct ldb_handle *handle) { ac = talloc_get_type(handle->private_data, struct partition_context); for (i=0; i < ac->num_searches; i++) { - ret = ldb_wait(ac->search_req[i]->async.handle, LDB_WAIT_NONE); + ret = ldb_wait(ac->search_req[i]->handle, LDB_WAIT_NONE); if (ret != LDB_SUCCESS) { handle->status = ret; goto done; } - if (ac->search_req[i]->async.handle->status != LDB_SUCCESS) { - handle->status = ac->search_req[i]->async.handle->status; + if (ac->search_req[i]->handle->status != LDB_SUCCESS) { + handle->status = ac->search_req[i]->handle->status; goto done; } - if (ac->search_req[i]->async.handle->state != LDB_ASYNC_DONE) { + if (ac->search_req[i]->handle->state != LDB_ASYNC_DONE) { return LDB_SUCCESS; } } -- cgit From 77bb75ead0b5b13539ab89531542cc2e9813fda4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Jul 2006 01:13:53 +0000 Subject: r17299: Improve the partition module to replicate attribute records into all partitions. Test that we do that correctly. Andrew Bartlett (This used to be commit 90c07b88010b848423dee9556a24e8d181c365dd) --- source4/dsdb/samdb/ldb_modules/partition.c | 240 ++++++++++++++++++++++------- 1 file changed, 181 insertions(+), 59 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 92fddca270..a21fabb747 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -42,15 +42,16 @@ struct partition { }; struct partition_private_data { struct partition **partitions; + struct ldb_dn **replicate; }; struct partition_context { struct ldb_module *module; struct ldb_request *orig_req; - struct ldb_request **search_req; - BOOL *finished_search; - int num_searches; + struct ldb_request **down_req; + int num_requests; + int finished_requests; }; static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct ldb_module *module) @@ -118,35 +119,163 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r return module; }; -static int partition_send_search(struct partition_context *ac, struct ldb_module *partition) + +/* + fire the caller's callback for every entry, but only send 'done' once. +*/ +static int partition_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) +{ + struct partition_context *ac; + + if (!context || !ares) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); + goto error; + } + + ac = talloc_get_type(context, struct partition_context); + + if (ares->type == LDB_REPLY_ENTRY) { + return ac->orig_req->callback(ldb, ac->orig_req->context, ares); + } else { + ac->finished_requests++; + if (ac->finished_requests == ac->num_requests) { + return ac->orig_req->callback(ldb, ac->orig_req->context, ares); + } else { + talloc_free(ares); + return LDB_SUCCESS; + } + } +error: + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + only fire the 'last' callback, and only for START-TLS for now +*/ +static int partition_other_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) +{ + struct partition_context *ac; + + if (!context || !ares) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); + goto error; + } + + ac = talloc_get_type(context, struct partition_context); + + if (ares->type == LDB_REPLY_EXTENDED && strcmp(ares->response->oid, LDB_EXTENDED_START_TLS_OID)) { + ac->finished_requests++; + if (ac->finished_requests == ac->num_requests) { + return ac->orig_req->callback(ldb, ac->orig_req->context, ares); + } + talloc_free(ares); + return LDB_SUCCESS; + } + ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_other_callback: Unknown reply type, only supports START_TLS")); +error: + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; +} + + +static int partition_send_request(struct partition_context *ac, struct ldb_module *partition) { int ret; struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition); - ac->search_req = talloc_realloc(ac, ac->search_req, - struct ldb_request *, ac->num_searches + 1); - if (!ac->search_req) { + ac->down_req = talloc_realloc(ac, ac->down_req, + struct ldb_request *, ac->num_requests + 1); + if (!ac->down_req) { ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); return LDB_ERR_OPERATIONS_ERROR; } - ac->search_req[ac->num_searches] = talloc(ac, struct ldb_request); - if (ac->search_req[ac->num_searches] == NULL) { + ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request); + if (ac->down_req[ac->num_requests] == NULL) { ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); return LDB_ERR_OPERATIONS_ERROR; } - *ac->search_req[ac->num_searches] = *ac->orig_req; /* copy the request */ + *ac->down_req[ac->num_requests] = *ac->orig_req; /* copy the request */ + if (ac->down_req[ac->num_requests]->operation == LDB_SEARCH) { + ac->down_req[ac->num_requests]->callback = partition_search_callback; + ac->down_req[ac->num_requests]->context = ac; + } else { + ac->down_req[ac->num_requests]->callback = partition_other_callback; + ac->down_req[ac->num_requests]->context = ac; + } + /* Spray off search requests to all backends */ - ret = ldb_next_request(next, ac->search_req[ac->num_searches]); + ret = ldb_next_request(next, ac->down_req[ac->num_requests]); if (ret != LDB_SUCCESS) { return ret; } - ac->num_searches++; + ac->num_requests++; return LDB_SUCCESS; } +/* Send a request down to all the partitions */ +static int partition_send_all(struct ldb_module *module, + struct partition_context *ac, struct ldb_request *req) +{ + int i; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + int ret = partition_send_request(ac, module->next); + if (ret != LDB_SUCCESS) { + return ret; + } + for (i=0; data && data->partitions && data->partitions[i]; i++) { + ret = partition_send_request(ac, data->partitions[i]->module); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} + +/* Figure out which backend a request needs to be aimed at. Some + * requests must be replicated to all backends */ +static int partition_replicate(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) +{ + int i; + struct ldb_module *backend; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + + /* Is this a special DN, we need to replicate to every backend? */ + for (i=0; data->replicate && data->replicate[i]; i++) { + if (ldb_dn_compare(module->ldb, + data->replicate[i], + dn) == 0) { + struct ldb_handle *h; + struct partition_context *ac; + + h = partition_init_handle(req, module); + if (!h) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* return our own handle to deal with this call */ + req->handle = h; + + ac = talloc_get_type(h->private_data, struct partition_context); + + return partition_send_all(module, ac, req); + } + } + + /* Otherwise, we need to find the backend to fire it to */ + + /* Find backend */ + backend = find_backend(module, req, req->op.add.message->dn); + + /* issue request */ + return ldb_next_request(backend, req); + +} + /* search */ static int partition_search(struct ldb_module *module, struct ldb_request *req) { @@ -171,15 +300,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) ac = talloc_get_type(h->private_data, struct partition_context); - ac->orig_req = req; - ac->num_searches = 0; - for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ if (ldb_dn_compare_base(module->ldb, req->op.search.base, data->partitions[i]->dn) == 0) { - ret = partition_send_search(ac, data->partitions[i]->module); + ret = partition_send_request(ac, data->partitions[i]->module); if (ret != LDB_SUCCESS) { return ret; } @@ -187,23 +313,10 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) } /* Perhaps we didn't match any partitions. Try the main partition, then all partitions */ - if (ac->num_searches == 0) { - ret = partition_send_search(ac, module->next); - if (ret != LDB_SUCCESS) { - return ret; - } - for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_send_search(ac, data->partitions[i]->module); - if (ret != LDB_SUCCESS) { - return ret; - } - } + if (ac->num_requests == 0) { + return partition_send_all(module, ac, req); } - ac->finished_search = talloc_zero_array(ac, BOOL, ac->num_searches); - if (!ac->finished_search) { - return LDB_ERR_OPERATIONS_ERROR; - } return LDB_SUCCESS; } else { struct ldb_module *backend = find_backend(module, req, req->op.search.base); @@ -215,34 +328,19 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* add */ static int partition_add(struct ldb_module *module, struct ldb_request *req) { - /* Find backend */ - struct ldb_module *backend = find_backend(module, req, req->op.add.message->dn); - - /* issue request */ - - return ldb_next_request(backend, req); + return partition_replicate(module, req, req->op.add.message->dn); } /* modify */ static int partition_modify(struct ldb_module *module, struct ldb_request *req) { - /* Find backend */ - struct ldb_module *backend = find_backend(module, req, req->op.mod.message->dn); - - /* issue request */ - - return ldb_next_request(backend, req); + return partition_replicate(module, req, req->op.mod.message->dn); } /* delete */ static int partition_delete(struct ldb_module *module, struct ldb_request *req) { - /* Find backend */ - struct ldb_module *backend = find_backend(module, req, req->op.del.dn); - - /* issue request */ - - return ldb_next_request(backend, req); + return partition_replicate(module, req, req->op.del.dn); } /* rename */ @@ -256,10 +354,7 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } - /* issue request */ - - /* (later) consider if we should be searching multiple partitions */ - return ldb_next_request(backend, req); + return partition_replicate(module, req, req->op.rename.olddn); } /* start a transaction */ @@ -400,10 +495,11 @@ static int partition_init(struct ldb_module *module) { int ret, i; TALLOC_CTX *mem_ctx = talloc_new(module); - static const char *attrs[] = { "partition", NULL }; + static const char *attrs[] = { "partition", "replicateEntries", NULL }; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *partition_attributes; + struct ldb_message_element *replicate_attributes; struct partition_private_data *data; @@ -511,6 +607,32 @@ static int partition_init(struct ldb_module *module) talloc_free(req); } + replicate_attributes = ldb_msg_find_element(msg, "replicateEntries"); + if (!replicate_attributes) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "no entries to replicate specified")); + data->replicate = NULL; + } else { + data->replicate = talloc_array(data, struct ldb_dn *, replicate_attributes->num_values + 1); + if (!data->replicate) { + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0; i < replicate_attributes->num_values; i++) { + data->replicate[i] = ldb_dn_explode(data->replicate[i], replicate_attributes->values[i].data); + if (!data->replicate[i]) { + ldb_set_errstring(module->ldb, + talloc_asprintf(module, "partition_init: " + "invalid DN in partition replicate record: %s", + replicate_attributes->values[i].data)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + } + data->replicate[i] = NULL; + } + module->private_data = data; talloc_steal(module, data); @@ -536,19 +658,19 @@ static int partition_wait_none(struct ldb_handle *handle) { ac = talloc_get_type(handle->private_data, struct partition_context); - for (i=0; i < ac->num_searches; i++) { - ret = ldb_wait(ac->search_req[i]->handle, LDB_WAIT_NONE); + for (i=0; i < ac->num_requests; i++) { + ret = ldb_wait(ac->down_req[i]->handle, LDB_WAIT_NONE); if (ret != LDB_SUCCESS) { handle->status = ret; goto done; } - if (ac->search_req[i]->handle->status != LDB_SUCCESS) { - handle->status = ac->search_req[i]->handle->status; + if (ac->down_req[i]->handle->status != LDB_SUCCESS) { + handle->status = ac->down_req[i]->handle->status; goto done; } - if (ac->search_req[i]->handle->state != LDB_ASYNC_DONE) { + if (ac->down_req[i]->handle->state != LDB_ASYNC_DONE) { return LDB_SUCCESS; } } -- cgit From cfa762ff8781531cf7dffc0f81377b90be6f439a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Jul 2006 01:52:15 +0000 Subject: r17302: Testing! This confirms that records are replicated into the correct databases, and that the case insensitive flags really work. Andrew Bartlett (This used to be commit ad463c1a5243019548bdbeea3070ec2e6cbcfcdf) --- source4/dsdb/samdb/ldb_modules/partition.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index a21fabb747..aa692547ce 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -128,7 +128,7 @@ static int partition_search_callback(struct ldb_context *ldb, void *context, str struct partition_context *ac; if (!context || !ares) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); + ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_search_callback: NULL Context or Result in 'search' callback")); goto error; } @@ -157,14 +157,16 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru { struct partition_context *ac; - if (!context || !ares) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); + if (!context) { + ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_other_callback: NULL Context in 'other' callback")); goto error; } ac = talloc_get_type(context, struct partition_context); - if (ares->type == LDB_REPLY_EXTENDED && strcmp(ares->response->oid, LDB_EXTENDED_START_TLS_OID)) { + if (!ares + || (ares->type == LDB_REPLY_EXTENDED + && strcmp(ares->response->oid, LDB_EXTENDED_START_TLS_OID))) { ac->finished_requests++; if (ac->finished_requests == ac->num_requests) { return ac->orig_req->callback(ldb, ac->orig_req->context, ares); @@ -621,7 +623,7 @@ static int partition_init(struct ldb_module *module) } for (i=0; i < replicate_attributes->num_values; i++) { - data->replicate[i] = ldb_dn_explode(data->replicate[i], replicate_attributes->values[i].data); + data->replicate[i] = ldb_dn_explode(data->replicate, replicate_attributes->values[i].data); if (!data->replicate[i]) { ldb_set_errstring(module->ldb, talloc_asprintf(module, "partition_init: " -- cgit From 5d7b99804acb921496248956542645889b05e928 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Jul 2006 02:00:33 +0000 Subject: r17303: More testing results: Don't try and call a NULL callback, and use the correct parameter, as this is called for more than just 'add'. Andrew Bartlett (This used to be commit be51b7240889bfcc752f92a2920d8b6a2eccecd6) --- source4/dsdb/samdb/ldb_modules/partition.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index aa692547ce..c94c843a83 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -164,6 +164,11 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru ac = talloc_get_type(context, struct partition_context); + if (!ac->orig_req->callback) { + talloc_free(ares); + return LDB_SUCCESS; + } + if (!ares || (ares->type == LDB_REPLY_EXTENDED && strcmp(ares->response->oid, LDB_EXTENDED_START_TLS_OID))) { @@ -271,7 +276,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re /* Otherwise, we need to find the backend to fire it to */ /* Find backend */ - backend = find_backend(module, req, req->op.add.message->dn); + backend = find_backend(module, req, dn); /* issue request */ return ldb_next_request(backend, req); -- cgit From ecfdd5fc6cd704eaf496f4d31c18b6db97589fb3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 10 Aug 2006 01:51:27 +0000 Subject: r17474: Allow the partitions module to load modules for specific backends. Andrew Bartlett (This used to be commit c016db2187120991e8ad779b9df35480d7c19400) --- source4/dsdb/samdb/ldb_modules/partition.c | 79 ++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index c94c843a83..af8fa475d1 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -502,11 +502,12 @@ static int partition_init(struct ldb_module *module) { int ret, i; TALLOC_CTX *mem_ctx = talloc_new(module); - static const char *attrs[] = { "partition", "replicateEntries", NULL }; + static const char *attrs[] = { "partition", "replicateEntries", "modules", NULL }; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *partition_attributes; struct ldb_message_element *replicate_attributes; + struct ldb_message_element *modules_attributes; struct partition_private_data *data; @@ -545,6 +546,7 @@ static int partition_init(struct ldb_module *module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "partition_init: " "no partitions specified")); + talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } data->partitions = talloc_array(data, struct partition *, partition_attributes->num_values + 1); @@ -559,6 +561,7 @@ static int partition_init(struct ldb_module *module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "partition_init: " "invalid form for partition record (missing ':'): %s", base)); + talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } p[0] = '\0'; @@ -567,6 +570,7 @@ static int partition_init(struct ldb_module *module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "partition_init: " "invalid form for partition record (missing backend database): %s", base)); + talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } data->partitions[i] = talloc(data->partitions, struct partition); @@ -580,12 +584,14 @@ static int partition_init(struct ldb_module *module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "partition_init: " "invalid DN in partition record: %s", base)); + talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } data->partitions[i]->backend = private_path(data->partitions[i], p); ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module); if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); return ret; } } @@ -600,6 +606,7 @@ static int partition_init(struct ldb_module *module) req = talloc_zero(mem_ctx, struct ldb_request); if (req == NULL) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out of memory!\n"); + talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } @@ -609,6 +616,7 @@ static int partition_init(struct ldb_module *module) ret = ldb_request(module->ldb, req); if (ret != LDB_SUCCESS) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Unable to register partition with rootdse!\n"); + talloc_free(mem_ctx); return LDB_ERR_OTHER; } talloc_free(req); @@ -616,9 +624,6 @@ static int partition_init(struct ldb_module *module) replicate_attributes = ldb_msg_find_element(msg, "replicateEntries"); if (!replicate_attributes) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "no entries to replicate specified")); data->replicate = NULL; } else { data->replicate = talloc_array(data, struct ldb_dn *, replicate_attributes->num_values + 1); @@ -634,12 +639,78 @@ static int partition_init(struct ldb_module *module) talloc_asprintf(module, "partition_init: " "invalid DN in partition replicate record: %s", replicate_attributes->values[i].data)); + talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } } data->replicate[i] = NULL; } + modules_attributes = ldb_msg_find_element(msg, "modules"); + if (modules_attributes) { + for (i=0; i < modules_attributes->num_values; i++) { + struct ldb_dn *base_dn; + int partition_idx; + struct partition *partition = NULL; + const char **modules = NULL; + + char *base = talloc_strdup(data->partitions, (char *)modules_attributes->values[i].data); + char *p = strchr(base, ':'); + if (!p) { + ldb_set_errstring(module->ldb, + talloc_asprintf(mem_ctx, "partition_init: " + "invalid form for partition module record (missing ':'): %s", base)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + p[0] = '\0'; + p++; + if (!p[0]) { + ldb_set_errstring(module->ldb, + talloc_asprintf(mem_ctx, "partition_init: " + "invalid form for partition module record (missing backend database): %s", base)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + modules = ldb_modules_list_from_string(module->ldb, mem_ctx, + p); + + base_dn = ldb_dn_explode(mem_ctx, base); + if (!base_dn) { + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) { + if (ldb_dn_compare(module->ldb, data->partitions[partition_idx]->dn, + base_dn) == 0) { + partition = data->partitions[partition_idx]; + break; + } + } + + if (!partition) { + ldb_set_errstring(module->ldb, + talloc_asprintf(mem_ctx, "partition_init: " + "invalid form for partition module record (no such partition): %s", base)); + talloc_free(mem_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + ret = ldb_load_modules_list(module->ldb, modules, partition->module, &partition->module); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + ret = ldb_init_module_chain(module->ldb, partition->module); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } + } + module->private_data = data; talloc_steal(module, data); -- cgit From faed8175063b16df94d5332581baf1af0562bb09 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 13 Aug 2006 07:33:57 +0000 Subject: r17514: Simplify the way to set ldb errors and add another helper function to set them. (This used to be commit 260868bae56194fcb98d55afc22fc66d96a303df) --- source4/dsdb/samdb/ldb_modules/partition.c | 61 ++++++++++++++---------------- 1 file changed, 29 insertions(+), 32 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index af8fa475d1..ba0c2bc9f4 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -61,7 +61,7 @@ static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct h = talloc_zero(req, struct ldb_handle); if (h == NULL) { - ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); + ldb_set_errstring(module->ldb, "Out of Memory"); return NULL; } @@ -69,7 +69,7 @@ static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct ac = talloc_zero(h, struct partition_context); if (ac == NULL) { - ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); + ldb_set_errstring(module->ldb, "Out of Memory"); talloc_free(h); return NULL; } @@ -128,7 +128,7 @@ static int partition_search_callback(struct ldb_context *ldb, void *context, str struct partition_context *ac; if (!context || !ares) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_search_callback: NULL Context or Result in 'search' callback")); + ldb_set_errstring(ldb, "partition_search_callback: NULL Context or Result in 'search' callback"); goto error; } @@ -158,7 +158,7 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru struct partition_context *ac; if (!context) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_other_callback: NULL Context in 'other' callback")); + ldb_set_errstring(ldb, "partition_other_callback: NULL Context in 'other' callback"); goto error; } @@ -179,7 +179,7 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru talloc_free(ares); return LDB_SUCCESS; } - ldb_set_errstring(ldb, talloc_asprintf(ldb, "partition_other_callback: Unknown reply type, only supports START_TLS")); + ldb_set_errstring(ldb, "partition_other_callback: Unknown reply type, only supports START_TLS"); error: talloc_free(ares); return LDB_ERR_OPERATIONS_ERROR; @@ -194,12 +194,12 @@ static int partition_send_request(struct partition_context *ac, struct ldb_modul ac->down_req = talloc_realloc(ac, ac->down_req, struct ldb_request *, ac->num_requests + 1); if (!ac->down_req) { - ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); + ldb_set_errstring(ac->module->ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request); if (ac->down_req[ac->num_requests] == NULL) { - ldb_set_errstring(ac->module->ldb, talloc_asprintf(ac->module->ldb, "Out of memory!")); + ldb_set_errstring(ac->module->ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } @@ -543,9 +543,7 @@ static int partition_init(struct ldb_module *module) partition_attributes = ldb_msg_find_element(msg, "partition"); if (!partition_attributes) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "no partitions specified")); + ldb_set_errstring(module->ldb, "partition_init: no partitions specified"); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -558,18 +556,18 @@ static int partition_init(struct ldb_module *module) char *base = talloc_strdup(data->partitions, (char *)partition_attributes->values[i].data); char *p = strchr(base, ':'); if (!p) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "invalid form for partition record (missing ':'): %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid form for partition record (missing ':'): %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } p[0] = '\0'; p++; if (!p[0]) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "invalid form for partition record (missing backend database): %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid form for partition record (missing backend database): %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -581,9 +579,8 @@ static int partition_init(struct ldb_module *module) data->partitions[i]->dn = ldb_dn_explode(data->partitions[i], base); if (!data->partitions[i]->dn) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "invalid DN in partition record: %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: invalid DN in partition record: %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -635,10 +632,10 @@ static int partition_init(struct ldb_module *module) for (i=0; i < replicate_attributes->num_values; i++) { data->replicate[i] = ldb_dn_explode(data->replicate, replicate_attributes->values[i].data); if (!data->replicate[i]) { - ldb_set_errstring(module->ldb, - talloc_asprintf(module, "partition_init: " - "invalid DN in partition replicate record: %s", - replicate_attributes->values[i].data)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid DN in partition replicate record: %s", + replicate_attributes->values[i].data); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -657,18 +654,18 @@ static int partition_init(struct ldb_module *module) char *base = talloc_strdup(data->partitions, (char *)modules_attributes->values[i].data); char *p = strchr(base, ':'); if (!p) { - ldb_set_errstring(module->ldb, - talloc_asprintf(mem_ctx, "partition_init: " - "invalid form for partition module record (missing ':'): %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid form for partition module record (missing ':'): %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } p[0] = '\0'; p++; if (!p[0]) { - ldb_set_errstring(module->ldb, - talloc_asprintf(mem_ctx, "partition_init: " - "invalid form for partition module record (missing backend database): %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid form for partition module record (missing backend database): %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -691,9 +688,9 @@ static int partition_init(struct ldb_module *module) } if (!partition) { - ldb_set_errstring(module->ldb, - talloc_asprintf(mem_ctx, "partition_init: " - "invalid form for partition module record (no such partition): %s", base)); + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "invalid form for partition module record (no such partition): %s", base); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } -- cgit From 6ddd5f6e6686644be8163f289c9480253b45db12 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Aug 2006 10:05:20 +0000 Subject: r17703: Fixes to enable the entryUUID module to work for it's objectClass -> OID mappings. The key point is to 'enable' the partitions in the partitions module before the init is complete. That way, the modules can perform searches that use partitions. Andrew Bartlett (This used to be commit 420d1920a6824a6c0cb70b4ba832ddb90b0e95ff) --- source4/dsdb/samdb/ldb_modules/partition.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index ba0c2bc9f4..889c0bfeb0 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -643,6 +643,10 @@ static int partition_init(struct ldb_module *module) data->replicate[i] = NULL; } + /* Make the private data available to any searches the modules may trigger in initialisation */ + module->private_data = data; + talloc_steal(module, data); + modules_attributes = ldb_msg_find_element(msg, "modules"); if (modules_attributes) { for (i=0; i < modules_attributes->num_values; i++) { @@ -708,9 +712,6 @@ static int partition_init(struct ldb_module *module) } } - module->private_data = data; - talloc_steal(module, data); - talloc_free(mem_ctx); return ldb_next_init(module); } -- cgit From 1e4f5a096cb75f0db0219fc55a6f654c485b0427 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 14 Sep 2006 03:15:30 +0000 Subject: r18495: More work on the LDAP backend (which now passes a lot of our tests!) This adds a list of attributes that are in our wildcard seaches, but the remote server requires to be explicitly listed. This also cleans up the handling of wildcards in ldb_map to be more consistant. Also fix the partitions module to rebase the search, if on the GC port, we do a subtree search. (Otherwise backends can rightly complain that the search is not in their scope). Andrew Bartlett (This used to be commit bc58792b7102f086b19353635d5d5ef9d40a0aae) --- source4/dsdb/samdb/ldb_modules/partition.c | 53 +++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 889c0bfeb0..bb085e0b11 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -186,35 +186,43 @@ error: } -static int partition_send_request(struct partition_context *ac, struct ldb_module *partition) +static int partition_send_request(struct partition_context *ac, struct ldb_module *partition, + struct ldb_dn *partition_base_dn) { int ret; struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition); - + struct ldb_request *req; ac->down_req = talloc_realloc(ac, ac->down_req, struct ldb_request *, ac->num_requests + 1); if (!ac->down_req) { ldb_set_errstring(ac->module->ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } - ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request); - if (ac->down_req[ac->num_requests] == NULL) { + req = ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request); + if (req == NULL) { ldb_set_errstring(ac->module->ldb, "Out of Memory"); return LDB_ERR_OPERATIONS_ERROR; } *ac->down_req[ac->num_requests] = *ac->orig_req; /* copy the request */ - - if (ac->down_req[ac->num_requests]->operation == LDB_SEARCH) { - ac->down_req[ac->num_requests]->callback = partition_search_callback; - ac->down_req[ac->num_requests]->context = ac; + + if (req->operation == LDB_SEARCH) { + /* If the search is for 'more' than this partition, + * then change the basedn, so a remote LDAP server + * doesn't object */ + if (ldb_dn_compare_base(ac->module->ldb, + partition_base_dn, req->op.search.base) != 0) { + req->op.search.base = partition_base_dn; + } + req->callback = partition_search_callback; + req->context = ac; } else { - ac->down_req[ac->num_requests]->callback = partition_other_callback; - ac->down_req[ac->num_requests]->context = ac; + req->callback = partition_other_callback; + req->context = ac; } /* Spray off search requests to all backends */ - ret = ldb_next_request(next, ac->down_req[ac->num_requests]); + ret = ldb_next_request(next, req); if (ret != LDB_SUCCESS) { return ret; } @@ -230,12 +238,12 @@ static int partition_send_all(struct ldb_module *module, int i; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - int ret = partition_send_request(ac, module->next); + int ret = partition_send_request(ac, module->next, NULL); if (ret != LDB_SUCCESS) { return ret; } for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_send_request(ac, data->partitions[i]->module); + ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); if (ret != LDB_SUCCESS) { return ret; } @@ -307,21 +315,26 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) ac = talloc_get_type(h->private_data, struct partition_context); + /* Search from the base DN */ + if (!req->op.search.base || req->op.search.base->comp_num == 0) { + return partition_send_all(module, ac, req); + } for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ if (ldb_dn_compare_base(module->ldb, req->op.search.base, data->partitions[i]->dn) == 0) { - ret = partition_send_request(ac, data->partitions[i]->module); + ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); if (ret != LDB_SUCCESS) { return ret; } } } - /* Perhaps we didn't match any partitions. Try the main partition, then all partitions */ + /* Perhaps we didn't match any partitions. Try the main partition, only */ if (ac->num_requests == 0) { - return partition_send_all(module, ac, req); + talloc_free(h); + return ldb_next_request(module, req); } return LDB_SUCCESS; @@ -701,11 +714,19 @@ static int partition_init(struct ldb_module *module) ret = ldb_load_modules_list(module->ldb, modules, partition->module, &partition->module); if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "loading backend for %s failed: %s", + base, ldb_errstring(module->ldb)); talloc_free(mem_ctx); return ret; } ret = ldb_init_module_chain(module->ldb, partition->module); if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(module->ldb, + "partition_init: " + "initialising backend for %s failed: %s", + base, ldb_errstring(module->ldb)); talloc_free(mem_ctx); return ret; } -- cgit From 77db3973c417cc934485dbd6bf1a8a1c84c1b30b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Sep 2006 06:44:12 +0000 Subject: r18781: Move the usnCreated and usnChanged handling around again. This moves these attributes from objectguid into an optional backend (objectguid), used by ltdb. For OpenLDAP, the entryUUID module converts entryCSN into usnChanged. This also changes the sequence number API, and uses 'time based' sequence numbers, when an LDAP or similar backend is detected. To assist this, we also store the last modified time in the TDB, whenever we change a value. Andrew Bartlett (This used to be commit 72858f859483c0c532dddb2c146d6bd7b9be5072) --- source4/dsdb/samdb/ldb_modules/partition.c | 105 ++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 15 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index bb085e0b11..437e288be5 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -474,28 +474,103 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque { int i, ret; uint64_t seq_number = 0; + uint64_t timestamp_sequence = 0; + uint64_t timestamp = 0; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - ret = ldb_next_request(module, req); - if (ret != LDB_SUCCESS) { - return ret; - } - seq_number = seq_number + req->op.seq_num.seq_num; - /* Look at base DN */ - /* Figure out which partition it is under */ - /* Skip the lot if 'data' isn't here yet (initialistion) */ - 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_next_request(next, req); - talloc_free(next); + switch (req->op.seq_num.type) { + case LDB_SEQ_NEXT: + case LDB_SEQ_HIGHEST_SEQ: + ret = ldb_next_request(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { + timestamp_sequence = req->op.seq_num.seq_num; + } else { + seq_number = seq_number + req->op.seq_num.seq_num; + } + + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + 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_next_request(next, req); + talloc_free(next); + if (ret != LDB_SUCCESS) { + return ret; + } + if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { + timestamp_sequence = MAX(timestamp_sequence, req->op.seq_num.seq_num); + } else { + seq_number = seq_number + req->op.seq_num.seq_num; + } + } + /* fall though */ + case LDB_SEQ_HIGHEST_TIMESTAMP: + { + struct ldb_request *date_req = talloc(req, struct ldb_request); + if (!date_req) { + return LDB_ERR_OPERATIONS_ERROR; + } + *date_req = *req; + date_req->op.seq_num.flags = LDB_SEQ_HIGHEST_TIMESTAMP; + + ret = ldb_next_request(module, date_req); if (ret != LDB_SUCCESS) { return ret; } - seq_number = seq_number + req->op.seq_num.seq_num; + timestamp = date_req->op.seq_num.seq_num; + + /* Look at base DN */ + /* Figure out which partition it is under */ + /* Skip the lot if 'data' isn't here yet (initialistion) */ + 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_next_request(next, date_req); + talloc_free(next); + if (ret != LDB_SUCCESS) { + return ret; + } + timestamp = MAX(timestamp, date_req->op.seq_num.seq_num); + } + break; + } + } + + switch (req->op.seq_num.flags) { + case LDB_SEQ_NEXT: + case LDB_SEQ_HIGHEST_SEQ: + + req->op.seq_num.flags = 0; + + /* Has someone above set a timebase sequence? */ + if (timestamp_sequence) { + req->op.seq_num.seq_num = (((unsigned long long)timestamp << 24) | (seq_number & 0xFFFFFF)); + } else { + req->op.seq_num.seq_num = seq_number; + } + + if (timestamp_sequence > req->op.seq_num.seq_num) { + req->op.seq_num.seq_num = timestamp_sequence; + req->op.seq_num.flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; + } + + req->op.seq_num.flags |= LDB_SEQ_GLOBAL_SEQUENCE; + break; + case LDB_SEQ_HIGHEST_TIMESTAMP: + req->op.seq_num.seq_num = timestamp; + break; + } + + switch (req->op.seq_num.flags) { + case LDB_SEQ_NEXT: + req->op.seq_num.seq_num++; } - req->op.seq_num.seq_num = seq_number; return LDB_SUCCESS; } -- cgit From ce02a7e9dc974b49444f716060df21a1412f0aaf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Sep 2006 06:42:19 +0000 Subject: r18945: fix compiler warnings and end-of-non-void function bugs metze (This used to be commit ed195999c0c7d89cdc61e980576d191fc05d65d7) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 437e288be5..a38f08e104 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -718,7 +718,7 @@ static int partition_init(struct ldb_module *module) } for (i=0; i < replicate_attributes->num_values; i++) { - data->replicate[i] = ldb_dn_explode(data->replicate, replicate_attributes->values[i].data); + data->replicate[i] = ldb_dn_explode(data->replicate, (const char *)replicate_attributes->values[i].data); if (!data->replicate[i]) { ldb_asprintf_errstring(module->ldb, "partition_init: " -- cgit From b7774527faf095f612eb1de48efacec6bd710a87 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 1 Nov 2006 23:31:26 +0000 Subject: r19531: Make struct ldb_dn opaque and local to ldb_dn.c (This used to be commit 889fb983ba1cf8a11424a8b3dc3a5ef76e780082) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index a38f08e104..d678364b6e 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -316,7 +316,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) ac = talloc_get_type(h->private_data, struct partition_context); /* Search from the base DN */ - if (!req->op.search.base || req->op.search.base->comp_num == 0) { + if (!req->op.search.base || (ldb_dn_get_comp_num(req->op.search.base) == 0)) { return partition_send_all(module, ac, req); } for (i=0; data && data->partitions && data->partitions[i]; i++) { -- cgit From 4889eb9f7aae9349e426d0f6d2217adff67eaebd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 00:59:34 +0000 Subject: r19831: Big ldb_dn optimization and interfaces enhancement patch This patch changes a lot of the code in ldb_dn.c, and also removes and add a number of manipulation functions around. The aim is to avoid validating a dn if not necessary as the validation code is necessarily slow. This is mainly to speed up internal operations where input is not user generated and so we can assume the DNs need no validation. The code is designed to keep the data as a string if possible. The code is not yet 100% perfect, but pass all the tests so far. A memleak is certainly present, I'll work on that next. Simo. (This used to be commit a580c871d3784602a9cce32d33419e63c8236e63) --- source4/dsdb/samdb/ldb_modules/partition.c | 35 +++++++++++++----------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index d678364b6e..625c846bdc 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -100,7 +100,7 @@ struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, return current; } -struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) +struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) { int i; struct partition_private_data *data = talloc_get_type(module->private_data, @@ -109,8 +109,7 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ for (i=0; data && data->partitions && data->partitions[i]; i++) { - if (ldb_dn_compare_base(module->ldb, - data->partitions[i]->dn, + if (ldb_dn_compare_base(data->partitions[i]->dn, dn) == 0) { return make_module_for_next_request(req, module->ldb, data->partitions[i]->module); } @@ -210,8 +209,7 @@ static int partition_send_request(struct partition_context *ac, struct ldb_modul /* If the search is for 'more' than this partition, * then change the basedn, so a remote LDAP server * doesn't object */ - if (ldb_dn_compare_base(ac->module->ldb, - partition_base_dn, req->op.search.base) != 0) { + if (ldb_dn_compare_base(partition_base_dn, req->op.search.base) != 0) { req->op.search.base = partition_base_dn; } req->callback = partition_search_callback; @@ -253,7 +251,7 @@ static int partition_send_all(struct ldb_module *module, /* Figure out which backend a request needs to be aimed at. Some * requests must be replicated to all backends */ -static int partition_replicate(struct ldb_module *module, struct ldb_request *req, const struct ldb_dn *dn) +static int partition_replicate(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) { int i; struct ldb_module *backend; @@ -262,8 +260,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re /* Is this a special DN, we need to replicate to every backend? */ for (i=0; data->replicate && data->replicate[i]; i++) { - if (ldb_dn_compare(module->ldb, - data->replicate[i], + if (ldb_dn_compare(data->replicate[i], dn) == 0) { struct ldb_handle *h; struct partition_context *ac; @@ -316,13 +313,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) ac = talloc_get_type(h->private_data, struct partition_context); /* Search from the base DN */ - if (!req->op.search.base || (ldb_dn_get_comp_num(req->op.search.base) == 0)) { + if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) { return partition_send_all(module, ac, req); } for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ - if (ldb_dn_compare_base(module->ldb, - req->op.search.base, + if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) { ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); if (ret != LDB_SUCCESS) { @@ -577,13 +573,12 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque static int sort_compare(void *void1, void *void2, void *opaque) { - struct ldb_context *ldb = talloc_get_type(opaque, struct ldb_context); struct partition **pp1 = void1; struct partition **pp2 = void2; struct partition *partition1 = talloc_get_type(*pp1, struct partition); struct partition *partition2 = talloc_get_type(*pp2, struct partition); - return ldb_dn_compare(ldb, partition1->dn, partition2->dn); + return ldb_dn_compare(partition1->dn, partition2->dn); } static int partition_init(struct ldb_module *module) @@ -608,7 +603,7 @@ static int partition_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - ret = ldb_search(module->ldb, ldb_dn_explode(mem_ctx, "@PARTITION"), + ret = ldb_search(module->ldb, ldb_dn_new(mem_ctx, module->ldb, "@PARTITION"), LDB_SCOPE_BASE, NULL, attrs, &res); @@ -665,7 +660,7 @@ static int partition_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - data->partitions[i]->dn = ldb_dn_explode(data->partitions[i], base); + data->partitions[i]->dn = ldb_dn_new(data->partitions[i], module->ldb, base); if (!data->partitions[i]->dn) { ldb_asprintf_errstring(module->ldb, "partition_init: invalid DN in partition record: %s", base); @@ -718,8 +713,8 @@ static int partition_init(struct ldb_module *module) } for (i=0; i < replicate_attributes->num_values; i++) { - data->replicate[i] = ldb_dn_explode(data->replicate, (const char *)replicate_attributes->values[i].data); - if (!data->replicate[i]) { + data->replicate[i] = ldb_dn_new(data->replicate, module->ldb, (const char *)replicate_attributes->values[i].data); + if (!ldb_dn_validate(data->replicate[i])) { ldb_asprintf_errstring(module->ldb, "partition_init: " "invalid DN in partition replicate record: %s", @@ -765,14 +760,14 @@ static int partition_init(struct ldb_module *module) modules = ldb_modules_list_from_string(module->ldb, mem_ctx, p); - base_dn = ldb_dn_explode(mem_ctx, base); - if (!base_dn) { + base_dn = ldb_dn_new(mem_ctx, module->ldb, base); + if (!ldb_dn_validate(base_dn)) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) { - if (ldb_dn_compare(module->ldb, data->partitions[partition_idx]->dn, + if (ldb_dn_compare(data->partitions[partition_idx]->dn, base_dn) == 0) { partition = data->partitions[partition_idx]; break; -- cgit From 353b968025f126dc1dd0c0f7ac547f7a0cb5a83d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 23 Nov 2006 22:06:07 +0000 Subject: r19869: fix memleaks (This used to be commit 3a662a2d985bf801284c5dc1123dec6705e6d092) --- source4/dsdb/samdb/ldb_modules/partition.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 625c846bdc..278b727df7 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -109,8 +109,7 @@ struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *r /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ for (i=0; data && data->partitions && data->partitions[i]; i++) { - if (ldb_dn_compare_base(data->partitions[i]->dn, - dn) == 0) { + if (ldb_dn_compare_base(data->partitions[i]->dn, dn) == 0) { return make_module_for_next_request(req, module->ldb, data->partitions[i]->module); } } @@ -318,8 +317,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) } for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ - if (ldb_dn_compare_base(req->op.search.base, - data->partitions[i]->dn) == 0) { + if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) { ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); if (ret != LDB_SUCCESS) { return ret; @@ -767,8 +765,7 @@ static int partition_init(struct ldb_module *module) } for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) { - if (ldb_dn_compare(data->partitions[partition_idx]->dn, - base_dn) == 0) { + if (ldb_dn_compare(data->partitions[partition_idx]->dn, base_dn) == 0) { partition = data->partitions[partition_idx]; break; } -- cgit From a04a3b8bc21101e6a11bad04c3d5c9655fa606b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 7 Jan 2007 19:11:27 +0000 Subject: r20599: - forward extended operations in the partitions module - by default the operations goes to all partitions - but some wellkown ones will go to just one partition (DSDB_EXTENDED_REPLICATED_OBJECTS_OID for now) I'll soon change the partitions module so that it'll attach a DSDB_CONTROL_PARTITION_CONTEXT_OID control to give the repl_meta_data or other partition specific modules a chance to to know for which partition it should work. metze (This used to be commit 0ed53c6d0f4a4e43ff9c8943730eeb57c735201b) --- source4/dsdb/samdb/ldb_modules/partition.c | 47 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 278b727df7..3face5f051 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -2,6 +2,7 @@ Partitions ldb module Copyright (C) Andrew Bartlett 2006 + Copyright (C) Stefan Metzmacher 2007 * NOTICE: this module is NOT released under the GNU LGPL license as * other ldb code. This module is release under the GNU GPL v2 or @@ -30,10 +31,12 @@ * Description: Implement LDAP partitions * * Author: Andrew Bartlett + * Author: Stefan Metzmacher */ #include "includes.h" #include "ldb/include/includes.h" +#include "dsdb/samdb/samdb.h" struct partition { struct ldb_module *module; @@ -84,7 +87,7 @@ static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, - struct ldb_module *module) + struct ldb_module *module) { struct ldb_module *current; static const struct ldb_module_ops ops; /* zero */ @@ -568,6 +571,45 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque return LDB_SUCCESS; } +static int partition_extended_replicated_objects(struct ldb_module *module, struct ldb_request *req) +{ + struct dsdb_extended_replicated_objects *ext; + + ext = talloc_get_type(req->op.extended.data, struct dsdb_extended_replicated_objects); + if (!ext) { + return LDB_ERR_OTHER; + } + + return partition_replicate(module, req, ext->partition_dn); +} + +/* extended */ +static int partition_extended(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_handle *h; + struct partition_context *ac; + + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_REPLICATED_OBJECTS_OID) == 0) { + return partition_extended_replicated_objects(module, req); + } + + /* + * as the extended operation has no dn + * we need to send it to all partitions + */ + + h = partition_init_handle(req, module); + if (!h) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* return our own handle to deal with this call */ + req->handle = h; + + ac = talloc_get_type(h->private_data, struct partition_context); + + return partition_send_all(module, ac, req); +} + static int sort_compare(void *void1, void *void2, void *opaque) { @@ -878,10 +920,11 @@ static const struct ldb_module_ops partition_ops = { .modify = partition_modify, .del = partition_delete, .rename = partition_rename, + .extended = partition_extended, + .sequence_number = partition_sequence_number, .start_transaction = partition_start_trans, .end_transaction = partition_end_trans, .del_transaction = partition_del_trans, - .sequence_number = partition_sequence_number, .wait = partition_wait }; -- cgit From ee3c15860248259777028b7f16526b93adc410f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 Jan 2007 09:38:21 +0000 Subject: r20679: make the init_handle stuff a bit easier and get rid of really ugly talloc_get_type() usage simo: if you change more modules, please include also this change metze (This used to be commit 88051a82c4918ba8183e0d6909161b2af2109446) --- source4/dsdb/samdb/ldb_modules/partition.c | 41 +++++++++++------------------- 1 file changed, 15 insertions(+), 26 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 3face5f051..31150b5f7b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -50,6 +50,7 @@ struct partition_private_data { struct partition_context { struct ldb_module *module; + struct ldb_handle *handle; struct ldb_request *orig_req; struct ldb_request **down_req; @@ -57,7 +58,7 @@ struct partition_context { int finished_requests; }; -static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct ldb_module *module) +static struct partition_context *partition_init_handle(struct ldb_request *req, struct ldb_module *module) { struct partition_context *ac; struct ldb_handle *h; @@ -77,12 +78,15 @@ static struct ldb_handle *partition_init_handle(struct ldb_request *req, struct return NULL; } - h->private_data = (void *)ac; + h->private_data = ac; ac->module = module; + ac->handle = h; ac->orig_req = req; - return h; + req->handle = h; + + return ac; } struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, @@ -264,17 +268,12 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re for (i=0; data->replicate && data->replicate[i]; i++) { if (ldb_dn_compare(data->replicate[i], dn) == 0) { - struct ldb_handle *h; struct partition_context *ac; - h = partition_init_handle(req, module); - if (!h) { + ac = partition_init_handle(req, module); + if (!ac) { return LDB_ERR_OPERATIONS_ERROR; } - /* return our own handle to deal with this call */ - req->handle = h; - - ac = talloc_get_type(h->private_data, struct partition_context); return partition_send_all(module, ac, req); } @@ -302,18 +301,13 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) * partitions (for 'invisible' partition behaviour */ if (ldb_get_opaque(module->ldb, "global_catalog")) { int ret, i; - struct ldb_handle *h; struct partition_context *ac; - h = partition_init_handle(req, module); - if (!h) { + ac = partition_init_handle(req, module); + if (!ac) { return LDB_ERR_OPERATIONS_ERROR; } - /* return our own handle to deal with this call */ - req->handle = h; - - ac = talloc_get_type(h->private_data, struct partition_context); - + /* Search from the base DN */ if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) { return partition_send_all(module, ac, req); @@ -330,7 +324,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* Perhaps we didn't match any partitions. Try the main partition, only */ if (ac->num_requests == 0) { - talloc_free(h); + talloc_free(ac); return ldb_next_request(module, req); } @@ -586,7 +580,6 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru /* extended */ static int partition_extended(struct ldb_module *module, struct ldb_request *req) { - struct ldb_handle *h; struct partition_context *ac; if (strcmp(req->op.extended.oid, DSDB_EXTENDED_REPLICATED_OBJECTS_OID) == 0) { @@ -598,14 +591,10 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req * we need to send it to all partitions */ - h = partition_init_handle(req, module); - if (!h) { + ac = partition_init_handle(req, module); + if (!ac) { return LDB_ERR_OPERATIONS_ERROR; } - /* return our own handle to deal with this call */ - req->handle = h; - - ac = talloc_get_type(h->private_data, struct partition_context); return partition_send_all(module, ac, req); } -- cgit From 21729fff115046ede3a316028b6a4e95cc7c590b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 13 Jan 2007 11:37:13 +0000 Subject: r20729: add a version number to struct dsdb_extended_replicated_objects metze (This used to be commit 2e79863d54030526841e5858e7be6a815c25593b) --- source4/dsdb/samdb/ldb_modules/partition.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 31150b5f7b..6ed113857d 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -571,7 +571,14 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru ext = talloc_get_type(req->op.extended.data, struct dsdb_extended_replicated_objects); if (!ext) { - return LDB_ERR_OTHER; + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended_replicated_objects: invalid extended data\n"); + return LDB_ERR_PROTOCOL_ERROR; + } + + if (ext->version != DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION) { + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended_replicated_objects: extended data invalid version [%u != %u]\n", + ext->version, DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION); + return LDB_ERR_PROTOCOL_ERROR; } return partition_replicate(module, req, ext->partition_dn); -- cgit From 842e2804d8ab4b3bf0ee9d719204c66464a570ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2007 17:53:53 +0000 Subject: r20809: rename struct partition into struct dsdb_control_current_partition we'll soon pass this down as DSDB_CONTROL_CURRENT_PARTITION_OID control so that the repl_meta_data module knows where to update the replUpToDateVector attribute metze (This used to be commit e5de40f8c2377d6dce54109a8d8bf9c6b681b813) --- source4/dsdb/samdb/ldb_modules/partition.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6ed113857d..c05fc215dc 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -38,13 +38,13 @@ #include "ldb/include/includes.h" #include "dsdb/samdb/samdb.h" -struct partition { +struct dsdb_control_current_partition { struct ldb_module *module; const char *backend; struct ldb_dn *dn; }; struct partition_private_data { - struct partition **partitions; + struct dsdb_control_current_partition **partitions; struct ldb_dn **replicate; }; @@ -609,10 +609,12 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req static int sort_compare(void *void1, void *void2, void *opaque) { - struct partition **pp1 = void1; - struct partition **pp2 = void2; - struct partition *partition1 = talloc_get_type(*pp1, struct partition); - struct partition *partition2 = talloc_get_type(*pp2, struct partition); + struct dsdb_control_current_partition **pp1 = void1; + struct dsdb_control_current_partition **pp2 = void2; + struct dsdb_control_current_partition *partition1 = talloc_get_type(*pp1, + struct dsdb_control_current_partition); + struct dsdb_control_current_partition *partition2 = talloc_get_type(*pp2, + struct dsdb_control_current_partition); return ldb_dn_compare(partition1->dn, partition2->dn); } @@ -666,7 +668,7 @@ static int partition_init(struct ldb_module *module) talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } - data->partitions = talloc_array(data, struct partition *, partition_attributes->num_values + 1); + data->partitions = talloc_array(data, struct dsdb_control_current_partition *, partition_attributes->num_values + 1); if (!data->partitions) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; @@ -690,7 +692,7 @@ static int partition_init(struct ldb_module *module) talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } - data->partitions[i] = talloc(data->partitions, struct partition); + data->partitions[i] = talloc(data->partitions, struct dsdb_control_current_partition); if (!data->partitions[i]) { talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; @@ -771,7 +773,7 @@ static int partition_init(struct ldb_module *module) for (i=0; i < modules_attributes->num_values; i++) { struct ldb_dn *base_dn; int partition_idx; - struct partition *partition = NULL; + struct dsdb_control_current_partition *partition = NULL; const char **modules = NULL; char *base = talloc_strdup(data->partitions, (char *)modules_attributes->values[i].data); -- cgit From 21206f36c6f59fe5f31ecf531013ae8fee60ea63 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 Jan 2007 10:57:55 +0000 Subject: r20826: make the dsdb_control_current_partition struct public and allocate an oid for the control metze (This used to be commit 684eee52e8812f6d104d8706ab059643ff4faa46) --- source4/dsdb/samdb/ldb_modules/partition.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index c05fc215dc..a7456c48f1 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -38,11 +38,6 @@ #include "ldb/include/includes.h" #include "dsdb/samdb/samdb.h" -struct dsdb_control_current_partition { - struct ldb_module *module; - const char *backend; - struct ldb_dn *dn; -}; struct partition_private_data { struct dsdb_control_current_partition **partitions; struct ldb_dn **replicate; @@ -697,6 +692,7 @@ static int partition_init(struct ldb_module *module) talloc_free(mem_ctx); return LDB_ERR_OPERATIONS_ERROR; } + data->partitions[i]->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION; data->partitions[i]->dn = ldb_dn_new(data->partitions[i], module->ldb, base); if (!data->partitions[i]->dn) { -- cgit From 7730ff44afea09f8765f8efdb7a4e5ad61f19ff4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jan 2007 13:46:16 +0000 Subject: r20847: - split some code out into a new function find_partition() - make all functions static metze (This used to be commit 3d313f08c7d6b201011f3b4744c8e54b1d0640c7) --- source4/dsdb/samdb/ldb_modules/partition.c | 35 +++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index a7456c48f1..8a497411df 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -84,9 +84,9 @@ static struct partition_context *partition_init_handle(struct ldb_request *req, return ac; } -struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - struct ldb_module *module) +static struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + struct ldb_module *module) { struct ldb_module *current; static const struct ldb_module_ops ops; /* zero */ @@ -102,21 +102,40 @@ struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, return current; } -struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) +static struct dsdb_control_current_partition *find_partition(struct partition_private_data *data, + struct ldb_dn *dn) { int i; - struct partition_private_data *data = talloc_get_type(module->private_data, - struct partition_private_data); + /* Look at base DN */ /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ for (i=0; data && data->partitions && data->partitions[i]; i++) { if (ldb_dn_compare_base(data->partitions[i]->dn, dn) == 0) { - return make_module_for_next_request(req, module->ldb, data->partitions[i]->module); + return data->partitions[i]; } } - return module; + return NULL; +}; + +static struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) +{ + struct dsdb_control_current_partition *partition; + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + + /* Skip the lot if 'data' isn't here yet (initialistion) */ + if (!data) { + return module; + } + + partition = find_partition(data, dn); + if (!partition) { + return module; + } + + return make_module_for_next_request(req, module->ldb, partition->module); }; -- cgit From a35a071fc95823cea74fdd3cb1858df4d7104901 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jan 2007 14:19:06 +0000 Subject: r20849: first step to move away from using find_backend() and use find_partition() instead metze (This used to be commit 0d75cca6f37975a3855973468dc55520cb3b3fb7) --- source4/dsdb/samdb/ldb_modules/partition.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 8a497411df..5ac954d65b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -138,7 +138,6 @@ static struct ldb_module *find_backend(struct ldb_module *module, struct ldb_req return make_module_for_next_request(req, module->ldb, partition->module); }; - /* fire the caller's callback for every entry, but only send 'done' once. */ @@ -274,6 +273,7 @@ static int partition_send_all(struct ldb_module *module, static int partition_replicate(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) { int i; + struct dsdb_control_current_partition *partition; struct ldb_module *backend; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); @@ -293,11 +293,26 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re } } - /* Otherwise, we need to find the backend to fire it to */ + /* Otherwise, we need to find the partition to fire it to */ + + /* Find partition */ + partition = find_partition(data, dn); + if (!partition) { + /* + * if we haven't found a matching partition + * pass the request to the main ldb + * + * TODO: we should maybe return an error here + * if it's not a special dn + */ + return ldb_next_request(module, req); + } + + backend = make_module_for_next_request(req, module->ldb, partition->module); + if (!backend) { + return LDB_ERR_OPERATIONS_ERROR; + } - /* Find backend */ - backend = find_backend(module, req, dn); - /* issue request */ return ldb_next_request(backend, req); -- cgit From f58e49ade829067064602cd8d143c7223f75057e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jan 2007 16:11:46 +0000 Subject: r20853: attach the DSDB_CONTROL_CURRENT_PARTITION_OID control when requests are passed to a specific partition metze (This used to be commit 06a46b1db46251989676fb04548f038930c83eb5) --- source4/dsdb/samdb/ldb_modules/partition.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 5ac954d65b..9a0dd9ca0a 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -272,7 +272,8 @@ static int partition_send_all(struct ldb_module *module, * requests must be replicated to all backends */ static int partition_replicate(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) { - int i; + unsigned i; + int ret; struct dsdb_control_current_partition *partition; struct ldb_module *backend; struct partition_private_data *data = talloc_get_type(module->private_data, @@ -313,9 +314,13 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re return LDB_ERR_OPERATIONS_ERROR; } + ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); + if (ret != LDB_SUCCESS) { + return ret; + } + /* issue request */ return ldb_next_request(backend, req); - } /* search */ -- cgit From 1500cd79d97b623816e6e13ea8da4e1ed194fdad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jan 2007 16:55:37 +0000 Subject: r20855: pass the DSDB_CONTROL_CURRENT_PARTITION_OID control also for the send_all case metze (This used to be commit b3fce383d3824ee418cbb7343f5d06720f5d31df) --- source4/dsdb/samdb/ldb_modules/partition.c | 37 ++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 9a0dd9ca0a..b23ceebf1b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -204,12 +204,18 @@ error: } -static int partition_send_request(struct partition_context *ac, struct ldb_module *partition, - struct ldb_dn *partition_base_dn) +static int partition_send_request(struct partition_context *ac, struct dsdb_control_current_partition *partition) { int ret; - struct ldb_module *next = make_module_for_next_request(ac->module, ac->module->ldb, partition); + struct ldb_module *backend; struct ldb_request *req; + + if (partition) { + backend = make_module_for_next_request(ac, ac->module->ldb, partition->module); + } else { + backend = ac->module; + } + ac->down_req = talloc_realloc(ac, ac->down_req, struct ldb_request *, ac->num_requests + 1); if (!ac->down_req) { @@ -228,8 +234,12 @@ static int partition_send_request(struct partition_context *ac, struct ldb_modul /* If the search is for 'more' than this partition, * then change the basedn, so a remote LDAP server * doesn't object */ - if (ldb_dn_compare_base(partition_base_dn, req->op.search.base) != 0) { - req->op.search.base = partition_base_dn; + if (partition) { + if (ldb_dn_compare_base(partition->dn, req->op.search.base) != 0) { + req->op.search.base = partition->dn; + } + } else { + req->op.search.base = NULL; } req->callback = partition_search_callback; req->context = ac; @@ -238,12 +248,19 @@ static int partition_send_request(struct partition_context *ac, struct ldb_modul req->context = ac; } + if (partition) { + ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); + if (ret != LDB_SUCCESS) { + return ret; + } + } + /* Spray off search requests to all backends */ - ret = ldb_next_request(next, req); + ret = ldb_next_request(backend, req); if (ret != LDB_SUCCESS) { return ret; } - + ac->num_requests++; return LDB_SUCCESS; } @@ -255,12 +272,12 @@ static int partition_send_all(struct ldb_module *module, int i; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - int ret = partition_send_request(ac, module->next, NULL); + int ret = partition_send_request(ac, NULL); if (ret != LDB_SUCCESS) { return ret; } for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); + ret = partition_send_request(ac, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } @@ -349,7 +366,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) { - ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn); + ret = partition_send_request(ac, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } -- cgit From 7dc7156bd76425df129102a42dd29a85fd8c7ebc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Feb 2007 01:54:40 +0000 Subject: r21496: A number of ldb control and LDAP changes, surrounding the 'phantom_root' flag in the search_options control - Add in support for LDB controls to the js layer - Test the behaviour - Implement support for the 'phantom_root' flag in the partitions module - Make the LDAP server set the 'phantom_root' flag in the search_options control - This replaces the global_catalog flag passed down as an opaque pointer - Rework the string-format control parsing function into ldb_parse_control_strings(), returning errors by ldb_errorstring() method, rather than with printf to stderr - Rework some of the ldb_control handling logic Andrew Bartlett (This used to be commit 2b3df7f38d7790358dbb4de1b8609bf794a351fb) --- source4/dsdb/samdb/ldb_modules/partition.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index b23ceebf1b..bd037066ca 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -1,3 +1,4 @@ + /* Partitions ldb module @@ -219,16 +220,26 @@ static int partition_send_request(struct partition_context *ac, struct dsdb_cont ac->down_req = talloc_realloc(ac, ac->down_req, struct ldb_request *, ac->num_requests + 1); if (!ac->down_req) { - ldb_set_errstring(ac->module->ldb, "Out of Memory"); + ldb_oom(ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } req = ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request); if (req == NULL) { - ldb_set_errstring(ac->module->ldb, "Out of Memory"); + ldb_oom(ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - *ac->down_req[ac->num_requests] = *ac->orig_req; /* copy the request */ + *req = *ac->orig_req; /* copy the request */ + + if (ac->orig_req->controls) { + req->controls + = talloc_memdup(req, + ac->orig_req->controls, talloc_get_size(ac->orig_req->controls)); + if (req->controls == NULL) { + ldb_oom(ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + } if (req->operation == LDB_SEARCH) { /* If the search is for 'more' than this partition, @@ -350,7 +361,14 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* (later) consider if we should be searching multiple * partitions (for 'invisible' partition behaviour */ - if (ldb_get_opaque(module->ldb, "global_catalog")) { + struct ldb_control *search_control = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID); + + struct ldb_search_options_control *search_options = NULL; + if (search_control) { + search_options = talloc_get_type(search_control->data, struct ldb_search_options_control); + } + + if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { int ret, i; struct partition_context *ac; -- cgit From 9b03286b32a916dbef59f1459eefa01f0ebfeed3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Mar 2007 00:59:06 +0000 Subject: r21806: I've been working over the last week to fix up the LDAP backend for Samba4. This only broke on global catalog queries, which turned out to be due to changes in the partitions module that metze needed for his DRSUAPI work. I've reworked partitions.c to always include the 'problematic' control, and therefore demonstrated that this is the issue. This ensures consistency, and should help with finding issues like this in future. As this control (DSDB_CONTROL_CURRENT_PARTITION_OID) is not intended to be linearised, I've added logic to allow it to be skipped when creating network packets. I've likewise make our LDAP server skip unknown controls, when marked 'not critical' on it's input, rather than just dropping the entire request. I need some help to generate a correct error packet when it is marked critical. Further work could perhaps be to have the ldap_encode routine return a textual description of what failed to encode, as that would have saved me a lot of time... Andrew Bartlett (This used to be commit eef710668f91d1bbaa2d834d9e653e11c8aac817) --- source4/dsdb/samdb/ldb_modules/partition.c | 61 +++++++++++++++++++----------- 1 file changed, 38 insertions(+), 23 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index bd037066ca..614431c563 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -205,11 +205,13 @@ error: } -static int partition_send_request(struct partition_context *ac, struct dsdb_control_current_partition *partition) +static int partition_send_request(struct partition_context *ac, struct ldb_control *remove_control, + struct dsdb_control_current_partition *partition) { int ret; struct ldb_module *backend; struct ldb_request *req; + struct ldb_control **saved_controls; if (partition) { backend = make_module_for_next_request(ac, ac->module->ldb, partition->module); @@ -231,7 +233,7 @@ static int partition_send_request(struct partition_context *ac, struct dsdb_cont *req = *ac->orig_req; /* copy the request */ - if (ac->orig_req->controls) { + if (req->controls) { req->controls = talloc_memdup(req, ac->orig_req->controls, talloc_get_size(ac->orig_req->controls)); @@ -259,6 +261,12 @@ static int partition_send_request(struct partition_context *ac, struct dsdb_cont req->context = ac; } + /* Remove a control, so we don't confuse a backend server */ + if (remove_control && !save_controls(remove_control, req, &saved_controls)) { + ldb_oom(ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + if (partition) { ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); if (ret != LDB_SUCCESS) { @@ -278,17 +286,19 @@ static int partition_send_request(struct partition_context *ac, struct dsdb_cont /* Send a request down to all the partitions */ static int partition_send_all(struct ldb_module *module, - struct partition_context *ac, struct ldb_request *req) + struct partition_context *ac, + struct ldb_control *remove_control, + struct ldb_request *req) { int i; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - int ret = partition_send_request(ac, NULL); + int ret = partition_send_request(ac, remove_control, NULL); if (ret != LDB_SUCCESS) { return ret; } for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_send_request(ac, data->partitions[i]); + ret = partition_send_request(ac, remove_control, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } @@ -307,18 +317,20 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - /* Is this a special DN, we need to replicate to every backend? */ - for (i=0; data->replicate && data->replicate[i]; i++) { - if (ldb_dn_compare(data->replicate[i], - dn) == 0) { - struct partition_context *ac; - - ac = partition_init_handle(req, module); - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; + if (req->operation != LDB_SEARCH) { + /* Is this a special DN, we need to replicate to every backend? */ + for (i=0; data->replicate && data->replicate[i]; i++) { + if (ldb_dn_compare(data->replicate[i], + dn) == 0) { + struct partition_context *ac; + + ac = partition_init_handle(req, module); + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return partition_send_all(module, ac, NULL, req); } - - return partition_send_all(module, ac, req); } } @@ -371,7 +383,11 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { int ret, i; struct partition_context *ac; - + struct ldb_control *remove_control = NULL; + if ((search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) { + /* We have processed this flag, so we are done with this control now */ + remove_control = search_control; + } ac = partition_init_handle(req, module); if (!ac) { return LDB_ERR_OPERATIONS_ERROR; @@ -379,12 +395,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* Search from the base DN */ if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) { - return partition_send_all(module, ac, req); + return partition_send_all(module, ac, remove_control, req); } for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) { - ret = partition_send_request(ac, data->partitions[i]); + ret = partition_send_request(ac, remove_control, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } @@ -399,9 +415,8 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) return LDB_SUCCESS; } else { - struct ldb_module *backend = find_backend(module, req, req->op.search.base); - - return ldb_next_request(backend, req); + /* Handle this like all other requests */ + return partition_replicate(module, req, req->op.search.base); } } @@ -672,7 +687,7 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req return LDB_ERR_OPERATIONS_ERROR; } - return partition_send_all(module, ac, req); + return partition_send_all(module, ac, NULL, req); } static int sort_compare(void *void1, -- cgit From f34c57f4fc1a1817735ddb653011e6deb0edf912 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Apr 2007 15:18:25 +0000 Subject: r22557: Simo has long bugged me that the paths in the sam.ldb partitions were not relative to the location of the sam.ldb, but instead lp_private_dir(). This fixes that issue. Andrew Bartlett (This used to be commit c0fd6f63399d55a1938e31ae7b10689cc02ff2fa) --- source4/dsdb/samdb/ldb_modules/partition.c | 31 +++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 614431c563..b301a98534 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -703,6 +703,33 @@ static int sort_compare(void *void1, return ldb_dn_compare(partition1->dn, partition2->dn); } +static const char *relative_path(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + const char *name) +{ + const char *base_url = ldb_get_opaque(module->ldb, "ldb_url"); + char *path, *p, *full_name; + if (name == NULL) { + return NULL; + } + if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { + return talloc_strdup(mem_ctx, name); + } + path = talloc_strdup(mem_ctx, base_url); + if (path == NULL) { + return NULL; + } + if ( (p = strrchr(path, '/')) != NULL) { + p[0] = '\0'; + } else { + talloc_free(path); + return NULL; + } + full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); + talloc_free(path); + return full_name; +} + static int partition_init(struct ldb_module *module) { int ret, i; @@ -791,7 +818,9 @@ static int partition_init(struct ldb_module *module) return LDB_ERR_CONSTRAINT_VIOLATION; } - data->partitions[i]->backend = private_path(data->partitions[i], p); + data->partitions[i]->backend = relative_path(module, + data->partitions[i], + p); ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); -- cgit From 52fb06edc25e8538c413df1aaabba18c859a00cf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 May 2007 18:50:56 +0000 Subject: r22681: Fix standalone ldb build when parent directory name != ldb. (This used to be commit 1093875d59f1ea9b8bd82277d4f9d8366e584952) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index b301a98534..b0875d2965 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -36,7 +36,7 @@ */ #include "includes.h" -#include "ldb/include/includes.h" +#include "ldb/include/ldb_includes.h" #include "dsdb/samdb/samdb.h" struct partition_private_data { -- cgit From 2d2cde7d95e0871ea66ce8186a54c3b28834051b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 Jul 2007 12:31:35 +0000 Subject: r23762: Fix DN renames over LDAP, and instrument the partition module. Add a test to prove the behaviour of LDAP renames etc. Fix LDB to return correct error code when failing to rename one DN onto another. Andrew Bartlett (This used to be commit 3f3da9c4710b7752ed97f55c2fc3d32a63d352af) --- source4/dsdb/samdb/ldb_modules/partition.c | 46 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index b0875d2965..73ee4ef3a6 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -120,25 +120,6 @@ static struct dsdb_control_current_partition *find_partition(struct partition_pr return NULL; }; -static struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) -{ - struct dsdb_control_current_partition *partition; - struct partition_private_data *data = talloc_get_type(module->private_data, - struct partition_private_data); - - /* Skip the lot if 'data' isn't here yet (initialistion) */ - if (!data) { - return module; - } - - partition = find_partition(data, dn); - if (!partition) { - return module; - } - - return make_module_for_next_request(req, module->ldb, partition->module); -}; - /* fire the caller's callback for every entry, but only send 'done' once. */ @@ -442,10 +423,31 @@ static int partition_delete(struct ldb_module *module, struct ldb_request *req) static int partition_rename(struct ldb_module *module, struct ldb_request *req) { /* Find backend */ - struct ldb_module *backend = find_backend(module, req, req->op.rename.olddn); - struct ldb_module *backend2 = find_backend(module, req, req->op.rename.newdn); + struct dsdb_control_current_partition *backend, *backend2; + + struct partition_private_data *data = talloc_get_type(module->private_data, + struct partition_private_data); + + /* Skip the lot if 'data' isn't here yet (initialistion) */ + if (!data) { + return LDB_ERR_OPERATIONS_ERROR; + } + + backend = find_partition(data, req->op.rename.olddn); + backend2 = find_partition(data, req->op.rename.newdn); + + if ((backend && !backend2) || (!backend && backend2)) { + return LDB_ERR_AFFECTS_MULTIPLE_DSAS; + } - if (backend->next != backend2->next) { + if (backend != backend2) { + ldb_asprintf_errstring(module->ldb, + "Cannot rename from %s in %s to %s in %s: %s", + ldb_dn_get_linearized(req->op.rename.olddn), + ldb_dn_get_linearized(backend->dn), + ldb_dn_get_linearized(req->op.rename.newdn), + ldb_dn_get_linearized(backend2->dn), + ldb_strerror(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/dsdb/samdb/ldb_modules/partition.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 73ee4ef3a6..21eb9a74d7 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -11,7 +11,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -20,8 +20,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* -- cgit From 67729cf71fa6796c79cee576db461b4523bd75a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Aug 2007 22:58:29 +0000 Subject: r24655: Fix bug 4919 reported by Matthias Wallnöfer : MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > When you change to the SAMBA private directory on a shell (default > /usr/local/samba/private) and start there for example ldbedit with the sam.ldb, > the application crashes if you don't put the "./" before the filename. I've adapted Matthias's patch. Andrew Bartlett (This used to be commit ba82197e30da8e626419e877d224431703edc866) --- source4/dsdb/samdb/ldb_modules/partition.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 21eb9a74d7..4c0c632139 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -722,11 +722,10 @@ static const char *relative_path(struct ldb_module *module, } if ( (p = strrchr(path, '/')) != NULL) { p[0] = '\0'; + full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); } else { - talloc_free(path); - return NULL; + full_name = talloc_asprintf(mem_ctx, "./%s", name); } - full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); talloc_free(path); return full_name; } -- cgit From 538e9842f6d2ee46ede3c5d25d2b69c17adffd3b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 27 Aug 2007 00:31:14 +0000 Subject: r24690: Further fix to bug 4919: Ensure we don't supply a NULL URL argument to ldb_connect_backend(). Andrew Bartlett (This used to be commit d0595e7a3d15c40dd49062efa0ddc6864b6b9030) --- source4/dsdb/samdb/ldb_modules/partition.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 4c0c632139..ae739f9b00 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -821,6 +821,11 @@ static int partition_init(struct ldb_module *module) data->partitions[i]->backend = relative_path(module, data->partitions[i], p); + if (!data->partitions[i]->backend) { + ldb_asprintf_errstring(module->ldb, + "partition_init: unable to determine an relative path for partition: %s", base); + talloc_free(mem_ctx); + } ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); -- cgit From 714c5c92ef8e80b3510e222ce621401e55d05d7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Aug 2007 05:43:26 +0000 Subject: r24731: Remove unused code - if we hit these error conditions, then we are dead anyway, and a segfault would leave us with more infomation. Andrew Bartlett (This used to be commit 62320616ff8795ff18c8f49029d81f12558c10ed) --- source4/dsdb/samdb/ldb_modules/partition.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index ae739f9b00..0675f38c56 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -45,7 +45,6 @@ struct partition_private_data { struct partition_context { struct ldb_module *module; - struct ldb_handle *handle; struct ldb_request *orig_req; struct ldb_request **down_req; @@ -76,7 +75,6 @@ static struct partition_context *partition_init_handle(struct ldb_request *req, h->private_data = ac; ac->module = module; - ac->handle = h; ac->orig_req = req; req->handle = h; @@ -126,11 +124,6 @@ static int partition_search_callback(struct ldb_context *ldb, void *context, str { struct partition_context *ac; - if (!context || !ares) { - ldb_set_errstring(ldb, "partition_search_callback: NULL Context or Result in 'search' callback"); - goto error; - } - ac = talloc_get_type(context, struct partition_context); if (ares->type == LDB_REPLY_ENTRY) { @@ -144,9 +137,6 @@ static int partition_search_callback(struct ldb_context *ldb, void *context, str return LDB_SUCCESS; } } -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; } /* @@ -156,11 +146,6 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru { struct partition_context *ac; - if (!context) { - ldb_set_errstring(ldb, "partition_other_callback: NULL Context in 'other' callback"); - goto error; - } - ac = talloc_get_type(context, struct partition_context); if (!ac->orig_req->callback) { @@ -179,7 +164,6 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru return LDB_SUCCESS; } ldb_set_errstring(ldb, "partition_other_callback: Unknown reply type, only supports START_TLS"); -error: talloc_free(ares); return LDB_ERR_OPERATIONS_ERROR; } -- cgit From cd962355abad90a2161765a7be7d26e63572cab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:08:14 +0000 Subject: r25000: Fix some more C++ compatibility warnings. (This used to be commit 08bb1ef643ab906f1645cf6f32763dc73b1884e4) --- source4/dsdb/samdb/ldb_modules/partition.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 0675f38c56..76e8578573 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -678,8 +678,10 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req static int sort_compare(void *void1, void *void2, void *opaque) { - struct dsdb_control_current_partition **pp1 = void1; - struct dsdb_control_current_partition **pp2 = void2; + struct dsdb_control_current_partition **pp1 = + (struct dsdb_control_current_partition **)void1; + struct dsdb_control_current_partition **pp2 = + (struct dsdb_control_current_partition **)void2; struct dsdb_control_current_partition *partition1 = talloc_get_type(*pp1, struct dsdb_control_current_partition); struct dsdb_control_current_partition *partition2 = talloc_get_type(*pp2, @@ -692,7 +694,8 @@ static const char *relative_path(struct ldb_module *module, TALLOC_CTX *mem_ctx, const char *name) { - const char *base_url = ldb_get_opaque(module->ldb, "ldb_url"); + const char *base_url = + (const char *)ldb_get_opaque(module->ldb, "ldb_url"); char *path, *p, *full_name; if (name == NULL) { return NULL; -- cgit From 761997855344befecaf0c1c18809387f0e8c9e3a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 19 Oct 2007 05:39:08 +0200 Subject: r25701: Clarify comment (This used to be commit cea496d2163db6dde371526dd5a79d4c090839ef) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 76e8578573..6f60b25a4b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -238,7 +238,7 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr } } - /* Spray off search requests to all backends */ + /* Spray off search requests the backend */ ret = ldb_next_request(backend, req); if (ret != LDB_SUCCESS) { return ret; -- cgit From 5cfa7732023e38b262b681efdb07c6d9f7d14cd7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Oct 2007 04:32:24 +0200 Subject: r25710: Finally fix subtree renames. Untested code is broken code and in this case an oddity of the javascript caused the test to 'pass'. For the same oddity, we have a failure in ldb's handling of spaces in DNs. We need to resolve that too. Andrew Bartlett (This used to be commit e8cbac1a46f4d3b083e6bb5a509ef1ba47bebff1) --- source4/dsdb/samdb/ldb_modules/partition.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 6f60b25a4b..5d3663be33 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -405,6 +405,7 @@ static int partition_delete(struct ldb_module *module, struct ldb_request *req) /* rename */ static int partition_rename(struct ldb_module *module, struct ldb_request *req) { + int i, matched = -1; /* Find backend */ struct dsdb_control_current_partition *backend, *backend2; @@ -434,6 +435,22 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } + for (i=0; data && data->partitions && data->partitions[i]; i++) { + if (ldb_dn_compare_base(req->op.rename.olddn, data->partitions[i]->dn) == 0) { + matched = i; + } + } + + if (matched > 0) { + ldb_asprintf_errstring(module->ldb, + "Cannot rename from %s to %s, subtree rename would cross partition %s: %s", + ldb_dn_get_linearized(req->op.rename.olddn), + ldb_dn_get_linearized(req->op.rename.newdn), + ldb_dn_get_linearized(data->partitions[matched]->dn), + ldb_strerror(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); + return LDB_ERR_AFFECTS_MULTIPLE_DSAS; + } + return partition_replicate(module, req, req->op.rename.olddn); } -- cgit From 7f18e15e3f48d92a4f8f2b929a6337761b26fc67 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2007 22:40:42 +0100 Subject: r25941: Use samdb_relative_path() (new function in samdb.c) in the partitions module. Andrew Bartlett (This used to be commit c8d1ab30845fa1496c85630b138b1cb512c2b6aa) --- source4/dsdb/samdb/ldb_modules/partition.c | 33 +++--------------------------- 1 file changed, 3 insertions(+), 30 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 5d3663be33..f40cf5ef42 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -707,33 +707,6 @@ static int sort_compare(void *void1, return ldb_dn_compare(partition1->dn, partition2->dn); } -static const char *relative_path(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - const char *name) -{ - const char *base_url = - (const char *)ldb_get_opaque(module->ldb, "ldb_url"); - char *path, *p, *full_name; - if (name == NULL) { - return NULL; - } - if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { - return talloc_strdup(mem_ctx, name); - } - path = talloc_strdup(mem_ctx, base_url); - if (path == NULL) { - return NULL; - } - if ( (p = strrchr(path, '/')) != NULL) { - p[0] = '\0'; - full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); - } else { - full_name = talloc_asprintf(mem_ctx, "./%s", name); - } - talloc_free(path); - return full_name; -} - static int partition_init(struct ldb_module *module) { int ret, i; @@ -822,9 +795,9 @@ static int partition_init(struct ldb_module *module) return LDB_ERR_CONSTRAINT_VIOLATION; } - data->partitions[i]->backend = relative_path(module, - data->partitions[i], - p); + data->partitions[i]->backend = samdb_relative_path(module->ldb, + data->partitions[i], + p); if (!data->partitions[i]->backend) { ldb_asprintf_errstring(module->ldb, "partition_init: unable to determine an relative path for partition: %s", base); -- cgit From 2e1f142ab03d9accbf4c61b0b11986bc1cb33d12 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:39 +0100 Subject: r26360: Add some const. (This used to be commit 3616ced29ed2385300f7268a742a9090840b626f) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index f40cf5ef42..bf4421ab0d 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -711,7 +711,7 @@ static int partition_init(struct ldb_module *module) { int ret, i; TALLOC_CTX *mem_ctx = talloc_new(module); - static const char *attrs[] = { "partition", "replicateEntries", "modules", NULL }; + const char *attrs[] = { "partition", "replicateEntries", "modules", NULL }; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *partition_attributes; -- cgit From 71e2cafe96f4755b67d01ced497bf5b63aad30f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 04:22:44 +0100 Subject: r26483: Merge ldb module dependency fixes, fix auth python module. (This used to be commit 85eeecf997a071ca7e7ad0247e8d34d49b7ffcbb) --- source4/dsdb/samdb/ldb_modules/partition.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index bf4421ab0d..4586810d96 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -117,9 +117,9 @@ static struct dsdb_control_current_partition *find_partition(struct partition_pr return NULL; }; -/* - fire the caller's callback for every entry, but only send 'done' once. -*/ +/** + * fire the caller's callback for every entry, but only send 'done' once. + */ static int partition_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) { struct partition_context *ac; @@ -139,9 +139,9 @@ static int partition_search_callback(struct ldb_context *ldb, void *context, str } } -/* - only fire the 'last' callback, and only for START-TLS for now -*/ +/** + * only fire the 'last' callback, and only for START-TLS for now + */ static int partition_other_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) { struct partition_context *ac; @@ -248,7 +248,9 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr return LDB_SUCCESS; } -/* Send a request down to all the partitions */ +/** + * Send a request down to all the partitions + */ static int partition_send_all(struct ldb_module *module, struct partition_context *ac, struct ldb_control *remove_control, @@ -270,8 +272,10 @@ static int partition_send_all(struct ldb_module *module, return LDB_SUCCESS; } -/* Figure out which backend a request needs to be aimed at. Some - * requests must be replicated to all backends */ +/** + * Figure out which backend a request needs to be aimed at. Some + * requests must be replicated to all backends + */ static int partition_replicate(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn) { unsigned i; -- cgit From 483164e1eb2a5b863cdd8adb515f4e4925f33a25 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jan 2008 08:49:54 +1100 Subject: Rework control handling to remove the 'domain_scope' control Also remove the search_options control earlier, before, rather than after duplicating the request. When we generate referalls in the partition module, the domain_scope control with suppress them. Andrew Bartlett (This used to be commit fc57a119f53a7bc0a0eb76b868bbd7386b3c5008) --- source4/dsdb/samdb/ldb_modules/partition.c | 54 ++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 4586810d96..61b64441a7 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -169,13 +169,12 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru } -static int partition_send_request(struct partition_context *ac, struct ldb_control *remove_control, +static int partition_send_request(struct partition_context *ac, struct dsdb_control_current_partition *partition) { int ret; struct ldb_module *backend; struct ldb_request *req; - struct ldb_control **saved_controls; if (partition) { backend = make_module_for_next_request(ac, ac->module->ldb, partition->module); @@ -225,12 +224,6 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr req->context = ac; } - /* Remove a control, so we don't confuse a backend server */ - if (remove_control && !save_controls(remove_control, req, &saved_controls)) { - ldb_oom(ac->module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - if (partition) { ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); if (ret != LDB_SUCCESS) { @@ -253,18 +246,17 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr */ static int partition_send_all(struct ldb_module *module, struct partition_context *ac, - struct ldb_control *remove_control, struct ldb_request *req) { int i; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); - int ret = partition_send_request(ac, remove_control, NULL); + int ret = partition_send_request(ac, NULL); if (ret != LDB_SUCCESS) { return ret; } for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_send_request(ac, remove_control, data->partitions[i]); + ret = partition_send_request(ac, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } @@ -297,7 +289,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re return LDB_ERR_OPERATIONS_ERROR; } - return partition_send_all(module, ac, NULL, req); + return partition_send_all(module, ac, req); } } } @@ -314,6 +306,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re * TODO: we should maybe return an error here * if it's not a special dn */ + return ldb_next_request(module, req); } @@ -334,6 +327,8 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re /* search */ static int partition_search(struct ldb_module *module, struct ldb_request *req) { + struct ldb_control **saved_controls; + /* Find backend */ struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); @@ -342,19 +337,34 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* (later) consider if we should be searching multiple * partitions (for 'invisible' partition behaviour */ struct ldb_control *search_control = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID); + struct ldb_control *domain_scope_control = ldb_request_get_control(req, LDB_CONTROL_DOMAIN_SCOPE_OID); struct ldb_search_options_control *search_options = NULL; if (search_control) { search_options = talloc_get_type(search_control->data, struct ldb_search_options_control); } + /* Remove the domain_scope control, so we don't confuse a backend server */ + if (domain_scope_control && !save_controls(domain_scope_control, req, &saved_controls)) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* TODO: + Generate referrals (look for a partition under this DN) if we don't have the above control specified + */ + if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { int ret, i; struct partition_context *ac; - struct ldb_control *remove_control = NULL; if ((search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) { /* We have processed this flag, so we are done with this control now */ - remove_control = search_control; + + /* Remove search control, so we don't confuse a backend server */ + if (search_control && !save_controls(search_control, req, &saved_controls)) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } } ac = partition_init_handle(req, module); if (!ac) { @@ -363,12 +373,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) /* Search from the base DN */ if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) { - return partition_send_all(module, ac, remove_control, req); + return partition_send_all(module, ac, req); } for (i=0; data && data->partitions && data->partitions[i]; i++) { /* Find all partitions under the search base */ if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) { - ret = partition_send_request(ac, remove_control, data->partitions[i]); + ret = partition_send_request(ac, data->partitions[i]); if (ret != LDB_SUCCESS) { return ret; } @@ -384,6 +394,16 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) return LDB_SUCCESS; } else { /* Handle this like all other requests */ + if (search_control && (search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) { + /* We have processed this flag, so we are done with this control now */ + + /* Remove search control, so we don't confuse a backend server */ + if (search_control && !save_controls(search_control, req, &saved_controls)) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + } + return partition_replicate(module, req, req->op.search.base); } } @@ -693,7 +713,7 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req return LDB_ERR_OPERATIONS_ERROR; } - return partition_send_all(module, ac, NULL, req); + return partition_send_all(module, ac, req); } static int sort_compare(void *void1, -- cgit From 16109a40c0abd8c30a5eb9bf9ef692bfae9dfc7d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Feb 2008 01:54:32 +0100 Subject: Use struct-based rather than function-based initialization for ldb modules everywhere. (This used to be commit 85c96a325867f7bcdb412ebc53f8a47dbf7cd89b) --- source4/dsdb/samdb/ldb_modules/partition.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 61b64441a7..62dd0da8a1 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -1030,7 +1030,7 @@ static int partition_wait(struct ldb_handle *handle, enum ldb_wait_type type) } } -static const struct ldb_module_ops partition_ops = { +const struct ldb_module_ops ldb_partition_module_ops = { .name = "partition", .init_context = partition_init, .search = partition_search, @@ -1045,8 +1045,3 @@ static const struct ldb_module_ops partition_ops = { .del_transaction = partition_del_trans, .wait = partition_wait }; - -int ldb_partition_init(void) -{ - return ldb_register_module(&partition_ops); -} -- cgit From 39a817d310964f8e9a63cfb096b3ad24fa03bd5e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Feb 2008 04:33:43 +0100 Subject: Fix use of some modules (needed _PUBLIC_). (This used to be commit ce332130ea77159832da23bab760fa26921719e2) --- source4/dsdb/samdb/ldb_modules/partition.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 62dd0da8a1..78b5a09f78 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -87,7 +87,7 @@ static struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, struct ldb_module *module) { struct ldb_module *current; - static const struct ldb_module_ops ops; /* zero */ +_PUBLIC_ static const struct ldb_module_ops ops; /* zero */ current = talloc_zero(mem_ctx, struct ldb_module); if (current == NULL) { return module; @@ -1030,7 +1030,7 @@ static int partition_wait(struct ldb_handle *handle, enum ldb_wait_type type) } } -const struct ldb_module_ops ldb_partition_module_ops = { +_PUBLIC_ const struct ldb_module_ops ldb_partition_module_ops = { .name = "partition", .init_context = partition_init, .search = partition_search, -- cgit From 8f8c56bfbcbfe8f80afb09eb1d481a108b252bee Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 28 Mar 2008 01:08:49 -0500 Subject: Convert some more files to GPLv3. (This used to be commit ebe5e8399422eb7e2ff4deb546338823e2718907) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 78b5a09f78..56b05691bb 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -6,7 +6,7 @@ Copyright (C) Stefan Metzmacher 2007 * NOTICE: this module is NOT released under the GNU LGPL license as - * other ldb code. This module is release under the GNU GPL v2 or + * other ldb code. This module is release under the GNU GPL v3 or * later license. This program is free software; you can redistribute it and/or modify -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 56b05691bb..7f136338be 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -87,7 +87,7 @@ static struct ldb_module *make_module_for_next_request(TALLOC_CTX *mem_ctx, struct ldb_module *module) { struct ldb_module *current; -_PUBLIC_ static const struct ldb_module_ops ops; /* zero */ + static const struct ldb_module_ops ops; /* zero */ current = talloc_zero(mem_ctx, struct ldb_module); if (current == NULL) { return module; -- cgit From c46afc8c447e3edb1dc81777700753b98aaa0f93 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 22:10:42 +1000 Subject: Simplify the contextCSN determination. We only ever have one backend partition per Samba partition. Andrew Bartlett (This used to be commit 316a9b312a2d4a4ea5a5c70946fb06b61fab1a7d) --- source4/dsdb/samdb/ldb_modules/partition.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') 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) { -- cgit From f619e08f8be7c3a20a71b679e73a7b7f57247f82 Mon Sep 17 00:00:00 2001 From: Anatoliy Atanasov Date: Wed, 23 Jul 2008 09:59:17 +0300 Subject: Handle schema reloading request. The ldif for that operation looks like this: dn: changetype: Modify add: schemaUpdateNow schemaUpdateNow: 1 It uses the rootdse's object functional attribute schemaUpdateNow. In rootdse_modify() this command is being recognized and it is send as extended operation with DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID. In the partition module its dispatched to the schema_fsmo module. The request is processed in the schema_fsmo module by schema_fsmo_extended(). (This used to be commit 39f9184ddf215f2b512319211c0a05702218ef87) --- source4/dsdb/samdb/ldb_modules/partition.c | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 22826e4f33..9285d6d0d8 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -699,6 +699,50 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru return partition_replicate(module, req, ext->partition_dn); } +static int partition_extended_schema_update_now(struct ldb_module *module, struct ldb_request *req) +{ + struct dsdb_control_current_partition *partition; + struct partition_private_data *data; + struct ldb_dn *schema_dn; + struct partition_context *ac; + struct ldb_module *backend; + int ret; + + schema_dn = talloc_get_type(req->op.extended.data, struct ldb_dn); + if (!schema_dn) { + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended: invalid extended data\n"); + return LDB_ERR_PROTOCOL_ERROR; + } + + data = talloc_get_type(module->private_data, struct partition_private_data); + if (!data) { + return LDB_ERR_OPERATIONS_ERROR; + } + + partition = find_partition( data, schema_dn ); + if (!partition) { + return ldb_next_request(module, req); + } + + ac = partition_init_handle(req, module); + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + backend = make_module_for_next_request(req, module->ldb, partition->module); + if (!backend) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_next_request(backend, req); +} + + /* extended */ static int partition_extended(struct ldb_module *module, struct ldb_request *req) { @@ -708,6 +752,11 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req return partition_extended_replicated_objects(module, req); } + /* forward schemaUpdateNow operation to schema_fsmo module*/ + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) == 0) { + return partition_extended_schema_update_now( module, req ); + } + /* * as the extended operation has no dn * we need to send it to all partitions -- cgit From 4ad97a1d0593b3401a352407009a99ead23f21f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Aug 2008 19:24:58 +1000 Subject: Don't walk past the end of ldb values. This is a partial fix towards bugs due to us walking past the end of what we think are strings in ldb. There is much more work to do in this area. Andrew Bartlett (This used to be commit 5805a9a8f35fd90fa4f718f73534817fa3bbdfd2) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules/partition.c') 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: " -- cgit