diff options
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/ldb/modules/operational.c | 4 | ||||
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 179 |
2 files changed, 176 insertions, 7 deletions
diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index fc15da4f6e..070f91e762 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -395,8 +395,8 @@ struct operational_async_context { const char * const *attrs; }; -static int operational_async_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares) { - +static int operational_async_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares) +{ struct operational_async_context *ac; if (!context || !ares) { diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index 59930046ce..24e3430254 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -1,7 +1,8 @@ /* ldb database library - Copyright (C) Simo Sorce 2004 + Copyright (C) Andrew Bartlet 2005 + Copyright (C) Simo Sorce 2006 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -23,13 +24,17 @@ */ /* - * Name: ldb + * Name: rdb_name * - * Component: ldb objectguid module + * Component: ldb rdn name module * - * Description: add a unique objectGUID onto every new record + * Description: keep a consistent name attribute on objects manpulations * - * Author: Simo Sorce + * Author: Andrew Bartlet + * + * Modifications: + * - made the module async + * Simo Sorce Mar 2006 */ #include "includes.h" @@ -188,6 +193,165 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) return ret; } +static int rdn_name_add_async(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *down_req; + struct ldb_message *msg; + struct ldb_message_element *attribute; + struct ldb_dn_component *rdn; + int i, ret; + + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n"); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.add.message->dn)) { + return ldb_next_request(module, req); + } + + down_req = talloc(module, struct ldb_request); + if (down_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = ldb_msg_copy_shallow(down_req, req->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn = ldb_dn_get_rdn(msg, msg->dn); + if (rdn == NULL) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Perhaps someone above us tried to set this? */ + if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { + attribute->num_values = 0; + } + + if (ldb_msg_add_value(msg, "name", &rdn->value) != 0) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + + attribute = rdn_name_find_attribute(msg, rdn->name); + + if (!attribute) { + if (ldb_msg_add_value(msg, rdn->name, &rdn->value) != 0) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn->name); + + for (i = 0; i < attribute->num_values; i++) { + if (handler->comparison_fn(module->ldb, msg, &rdn->value, &attribute->values[i]) == 0) { + /* overwrite so it matches in case */ + attribute->values[i] = rdn->value; + break; + } + } + if (i == attribute->num_values) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "RDN mismatch on %s: %s", + ldb_dn_linearize(msg, msg->dn), rdn->name); + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + down_req->op.add.message = msg; + + down_req->controls = req->controls; + down_req->creds = req->creds; + + down_req->async.context = req->async.context; + down_req->async.callback = req->async.callback; + down_req->async.timeout = req->async.timeout; + + /* go on with the call chain */ + ret = ldb_next_request(module, down_req); + + /* do not free down_req as the call results may be linked to it, + * it will be freed when the upper level request get freed */ + if (ret == LDB_SUCCESS) { + req->async.handle = down_req->async.handle; + } + + return ret; +} + +static int rdn_name_modify_async(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *down_req; + struct ldb_message *msg; + struct ldb_message_element *attribute; + struct ldb_dn_component *rdn; + int ret; + + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_modify_record\n"); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.mod.message->dn)) { + return ldb_next_request(module, req); + } + + /* Perhaps someone above us knows better */ + if ((attribute = rdn_name_find_attribute(req->op.mod.message, "name")) != NULL ) { + return ldb_next_request(module, req); + } + + /* FIXME: are we sure we wont to change "name" on each and every modify operation ?? */ + down_req = talloc(module, struct ldb_request); + if (down_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = ldb_msg_copy_shallow(down_req, req->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn = ldb_dn_get_rdn(msg, msg->dn); + if (rdn == NULL) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_msg_add_value(msg, "name", &rdn->value) != 0) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + + attribute = rdn_name_find_attribute(msg, "name"); + if (!attribute) { + talloc_free(down_req); + return LDB_ERR_OPERATIONS_ERROR; + } + + attribute->flags = LDB_FLAG_MOD_REPLACE; + + down_req->op.add.message = msg; + + down_req->controls = req->controls; + down_req->creds = req->creds; + + down_req->async.context = req->async.context; + down_req->async.callback = req->async.callback; + down_req->async.timeout = req->async.timeout; + + /* go on with the call chain */ + ret = ldb_next_request(module, down_req); + + /* do not free down_req as the call results may be linked to it, + * it will be freed when the upper level request get freed */ + if (ret == LDB_SUCCESS) { + req->async.handle = down_req->async.handle; + } + + return ret; +} + static int rdn_name_request(struct ldb_module *module, struct ldb_request *req) { switch (req->operation) { @@ -198,6 +362,11 @@ static int rdn_name_request(struct ldb_module *module, struct ldb_request *req) case LDB_REQ_MODIFY: return rdn_name_modify(module, req); + case LDB_ASYNC_ADD: + return rdn_name_add_async(module, req); + + case LDB_ASYNC_MODIFY: + return rdn_name_modify_async(module, req); default: return ldb_next_request(module, req); |