diff options
author | Simo Sorce <idra@samba.org> | 2006-05-28 02:10:44 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:08:39 -0500 |
commit | 90a5e19e03842b77fd7811965fb2603e552261bc (patch) | |
tree | 211bda772b224b6cfdc54e5b3fc1857fc539d9dd /source4/lib/ldb/modules | |
parent | 53107aed4a45f28aa1a159019ff4c3b45fbc8f02 (diff) | |
download | samba-90a5e19e03842b77fd7811965fb2603e552261bc.tar.gz samba-90a5e19e03842b77fd7811965fb2603e552261bc.tar.bz2 samba-90a5e19e03842b77fd7811965fb2603e552261bc.zip |
r15913: Error passing in the async code is not in agood shape
Start enhancing it and fix some problems with incorrect evalutaion of the codes
Implement rdn rename (async only)
(This used to be commit 6af1d738b9668d4f0eb6194ac0f84af9e73f8c2e)
Diffstat (limited to 'source4/lib/ldb/modules')
-rw-r--r-- | source4/lib/ldb/modules/asq.c | 3 | ||||
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 205 |
2 files changed, 202 insertions, 6 deletions
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c index 1449ece975..c682bd6359 100644 --- a/source4/lib/ldb/modules/asq.c +++ b/source4/lib/ldb/modules/asq.c @@ -481,9 +481,12 @@ static int asq_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_t } handle->state = LDB_ASYNC_PENDING; + handle->status = LDB_SUCCESS; ac = talloc_get_type(handle->private_data, struct asq_async_context); +/* TODO: make this like password_hash */ + if (type == LDB_WAIT_ALL) { while (ac->base_req->async.handle->state != LDB_ASYNC_DONE) { ret = ldb_async_wait(ac->base_req->async.handle, type); diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index 18ad625ee2..7ce6c29691 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -53,7 +53,7 @@ static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_mess return NULL; } -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) +static int rdn_name_add_sync(struct ldb_module *module, struct ldb_request *req) { const struct ldb_message *msg = req->op.add.message; struct ldb_message *msg2; @@ -132,7 +132,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) return ret; } -static int rdn_name_add_async(struct ldb_module *module, struct ldb_request *req) +static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_request *down_req; struct ldb_message *msg; @@ -147,7 +147,7 @@ static int rdn_name_add_async(struct ldb_module *module, struct ldb_request *req return ldb_next_request(module, req); } - down_req = talloc(module, struct ldb_request); + down_req = talloc(req, struct ldb_request); if (down_req == NULL) { return LDB_ERR_OPERATIONS_ERROR; } @@ -213,15 +213,207 @@ static int rdn_name_add_async(struct ldb_module *module, struct ldb_request *req return ret; } +struct rename_async_context { + + enum {RENAME_RENAME, RENAME_MODIFY} step; + struct ldb_request *orig_req; + struct ldb_request *down_req; + struct ldb_request *mod_req; +}; + +static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_async_handle *h; + struct rename_async_context *ac; + + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n"); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.rename.newdn)) { + return ldb_next_request(module, req); + } + + h = talloc_zero(req, struct ldb_async_handle); + if (h == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + h->module = module; + + ac = talloc_zero(h, struct rename_async_context); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + h->private_data = (void *)ac; + + h->state = LDB_ASYNC_INIT; + h->status = LDB_SUCCESS; + + ac->orig_req = req; + ac->down_req = talloc(req, struct ldb_request); + if (ac->down_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + *(ac->down_req) = *req; + + ac->step = RENAME_RENAME; + + req->async.handle = h; + + /* rename first, modify "name" if rename is ok */ + return ldb_next_request(module, ac->down_req); +} + +static int rdn_name_rename_do_mod(struct ldb_async_handle *h) { + + struct rename_async_context *ac; + struct ldb_dn_component *rdn; + struct ldb_message *msg; + + ac = talloc_get_type(h->private_data, struct rename_async_context); + + rdn = ldb_dn_get_rdn(ac, ac->orig_req->op.rename.newdn); + if (rdn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->mod_req = talloc_zero(ac, struct ldb_request); + + ac->mod_req->operation = LDB_ASYNC_MODIFY; + ac->mod_req->op.mod.message = msg = ldb_msg_new(ac->mod_req); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->dn = ldb_dn_copy(msg, ac->orig_req->op.rename.newdn); + if (msg->dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_msg_add_empty(msg, rdn->name, LDB_FLAG_MOD_REPLACE) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (ldb_msg_add_value(msg, rdn->name, &rdn->value) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (ldb_msg_add_value(msg, "name", &rdn->value) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->mod_req->async.timeout = ac->orig_req->async.timeout; + + ac->step = RENAME_MODIFY; + + /* do the mod call */ + return ldb_next_request(h->module, ac->mod_req); +} + +static int rename_async_wait(struct ldb_async_handle *handle) +{ + struct rename_async_context *ac; + int ret; + + 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 rename_async_context); + + switch(ac->step) { + case RENAME_RENAME: + ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE); + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->down_req->async.handle->status != LDB_SUCCESS) { + handle->status = ac->down_req->async.handle->status; + goto done; + } + + if (ac->down_req->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; + } + + /* rename operation done */ + return rdn_name_rename_do_mod(handle); + + case RENAME_MODIFY: + ret = ldb_async_wait(ac->mod_req->async.handle, LDB_WAIT_NONE); + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->mod_req->async.handle->status != LDB_SUCCESS) { + handle->status = ac->mod_req->async.handle->status; + goto done; + } + + if (ac->mod_req->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; + } + + break; + + default: + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + ret = LDB_SUCCESS; + +done: + handle->state = LDB_ASYNC_DONE; + return ret; +} + +static int rename_async_wait_all(struct ldb_async_handle *handle) { + + int ret; + + while (handle->state != LDB_ASYNC_DONE) { + ret = rename_async_wait(handle); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return handle->status; +} + +static int rdn_name_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type) +{ + if (type == LDB_WAIT_ALL) { + return rename_async_wait_all(handle); + } else { + return rename_async_wait(handle); + } +} + static int rdn_name_request(struct ldb_module *module, struct ldb_request *req) { switch (req->operation) { case LDB_REQ_ADD: - return rdn_name_add(module, req); + return rdn_name_add_sync(module, req); case LDB_ASYNC_ADD: - return rdn_name_add_async(module, req); + return rdn_name_add(module, req); + + case LDB_ASYNC_RENAME: + return rdn_name_rename(module, req); default: return ldb_next_request(module, req); @@ -231,7 +423,8 @@ static int rdn_name_request(struct ldb_module *module, struct ldb_request *req) static const struct ldb_module_ops rdn_name_ops = { .name = "rdn_name", - .request = rdn_name_request + .request = rdn_name_request, + .async_wait = rdn_name_async_wait }; |