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 | |
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')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 110 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_ildap/ldb_ildap.c | 2 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_ldap/ldb_ldap.c | 77 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_search.c | 14 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 153 | ||||
-rw-r--r-- | source4/lib/ldb/modules/asq.c | 3 | ||||
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 205 |
7 files changed, 396 insertions, 168 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 2885fb82a2..67cb01b9d8 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1680,82 +1680,119 @@ static int ph_async_wait(struct ldb_async_handle *handle) { } handle->state = LDB_ASYNC_PENDING; + handle->status = LDB_SUCCESS; ac = talloc_get_type(handle->private_data, struct ph_async_context); switch (ac->step) { case PH_ADD_SEARCH_DOM: - if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->dom_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->dom_req->async.handle, LDB_WAIT_NONE); - if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->dom_req->async.handle->status != LDB_SUCCESS) { + handle->status = ac->dom_req->async.handle->status; + goto done; + } + + if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; } /* domain search done, go on */ return password_hash_add_async_do_add(handle); case PH_ADD_DO_ADD: - if (ac->down_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE); - if (ac->down_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + 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; } break; case PH_MOD_DO_REQ: - if (ac->down_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->down_req->async.handle, LDB_WAIT_NONE); - if (ac->down_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + 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; } /* non-password mods done, go on */ return password_hash_mod_async_search_self(handle); case PH_MOD_SEARCH_SELF: - if (ac->search_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->search_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->search_req->async.handle, LDB_WAIT_NONE); - if (ac->search_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->search_req->async.handle->status != LDB_SUCCESS) { + handle->status = ac->search_req->async.handle->status; + goto done; + } + + if (ac->search_req->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; } /* self search done, go on */ return password_hash_mod_async_search_dom(handle); case PH_MOD_SEARCH_DOM: - if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->dom_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->dom_req->async.handle, LDB_WAIT_NONE); - if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (ac->dom_req->async.handle->status != LDB_SUCCESS) { + handle->status = ac->dom_req->async.handle->status; + goto done; + } + + if (ac->dom_req->async.handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; } /* domain search done, go on */ return password_hash_mod_async_do_mod(handle); case PH_MOD_DO_MOD: - if (ac->mod_req->async.handle->state != LDB_ASYNC_DONE) { - ret = ldb_async_wait(ac->mod_req->async.handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) goto done; + ret = ldb_async_wait(ac->mod_req->async.handle, LDB_WAIT_NONE); - if (ac->mod_req->async.handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } + 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; @@ -1769,7 +1806,6 @@ static int ph_async_wait(struct ldb_async_handle *handle) { done: handle->state = LDB_ASYNC_DONE; - handle->status = ret; return ret; } diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index ab302dd16d..0fa7af25ec 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -951,7 +951,7 @@ static int ildb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_ return LDB_ERR_OPERATIONS_ERROR; } - return handle->status; + return LDB_SUCCESS; } /* diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index bbfb1de104..c53db1f90c 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -718,7 +718,7 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul char *errmsgp = NULL; char **referralsp = NULL; LDAPControl **serverctrlsp = NULL; - int ret; + int ret = LDB_SUCCESS; type = ldap_msgtype(result); @@ -732,24 +732,24 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul ares = talloc_zero(ac, struct ldb_async_result); if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->message = ldb_msg_new(ares); if (!ares->message) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } dn = ldap_get_dn(lldb->ldap, msg); if (!dn) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->message->dn = ldb_dn_explode_or_special(ares->message, dn); if (ares->message->dn == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ldap_memfree(dn); @@ -774,11 +774,7 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul ares->type = LDB_REPLY_ENTRY; - handle->state = LDB_ASYNC_PENDING; ret = ac->callback(ac->module->ldb, ac->context, ares); - if (ret != LDB_SUCCESS) { - handle->status = ret; - } } else { handle->status = LDB_ERR_PROTOCOL_ERROR; handle->state = LDB_ASYNC_DONE; @@ -789,7 +785,7 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul if (ldap_parse_result(lldb->ldap, result, &handle->status, &matcheddnp, &errmsgp, &referralsp, &serverctrlsp, 1) != LDAP_SUCCESS) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } if (referralsp == NULL) { @@ -799,17 +795,13 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul ares = talloc_zero(ac, struct ldb_async_result); if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } ares->referral = talloc_strdup(ares, *referralsp); ares->type = LDB_REPLY_REFERRAL; - handle->state = LDB_ASYNC_PENDING; ret = ac->callback(ac->module->ldb, ac->context, ares); - if (ret != LDB_SUCCESS) { - handle->status = ret; - } break; @@ -823,7 +815,7 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul ares = talloc_zero(ac, struct ldb_async_result); if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; + ret = LDB_ERR_OPERATIONS_ERROR; goto error; } @@ -835,9 +827,6 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul ares->type = LDB_REPLY_DONE; handle->state = LDB_ASYNC_DONE; ret = ac->callback(ac->module->ldb, ac->context, ares); - if (ret != LDB_SUCCESS) { - handle->status = ret; - } break; @@ -853,13 +842,13 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul } if (ac->callback && handle->status == LDB_SUCCESS) { ares = NULL; /* FIXME: build a corresponding ares to pass on */ - handle->status = ac->callback(ac->module->ldb, ac->context, ares); + ret = ac->callback(ac->module->ldb, ac->context, ares); } handle->state = LDB_ASYNC_DONE; break; default: - handle->status = LDB_ERR_PROTOCOL_ERROR; + ret = LDB_ERR_PROTOCOL_ERROR; goto error; } @@ -872,12 +861,12 @@ static int lldb_parse_result(struct ldb_async_handle *handle, LDAPMessage *resul if (serverctrlsp) ldap_controls_free(serverctrlsp); ldap_msgfree(result); - return handle->status; + return ret; error: handle->state = LDB_ASYNC_DONE; ldap_msgfree(result); - return handle->status; + return ret; } static int lldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type) @@ -886,7 +875,7 @@ static int lldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_ struct lldb_private *lldb = talloc_get_type(handle->module->private_data, struct lldb_private); struct timeval timeout; LDAPMessage *result; - int ret = LDB_ERR_OPERATIONS_ERROR; + int ret, lret; if (handle->state == LDB_ASYNC_DONE) { return handle->status; @@ -896,40 +885,54 @@ static int lldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_ return LDB_ERR_OPERATIONS_ERROR; } + handle->state = LDB_ASYNC_PENDING; handle->status = LDB_SUCCESS; switch(type) { case LDB_WAIT_NONE: timeout.tv_sec = 0; timeout.tv_usec = 0; - ret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); - if (ret == -1) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; + + lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); + if (lret == -1) { + return LDB_ERR_OPERATIONS_ERROR; } - if (ret == 0) { - handle->status = LDB_SUCCESS; - return handle->status; + if (lret == 0) { + ret = LDB_SUCCESS; + goto done; } - ret = lldb_parse_result(handle, result); - break; + + return lldb_parse_result(handle, result); + case LDB_WAIT_ALL: timeout.tv_sec = ac->timeout; timeout.tv_usec = 0; + ret = LDB_ERR_OPERATIONS_ERROR; + while (handle->status == LDB_SUCCESS && handle->state != LDB_ASYNC_DONE) { - ret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); - if (ret == -1 || ret == 0) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; + + lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); + if (lret == -1) { + return LDB_ERR_OPERATIONS_ERROR; } + if (lret == 0) { + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + ret = lldb_parse_result(handle, result); if (ret != LDB_SUCCESS) { return ret; } } + break; + + default: + handle->state = LDB_ASYNC_DONE; + ret = LDB_ERR_OPERATIONS_ERROR; } +done: return ret; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 7e14a3000a..0ab1442c2f 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -462,15 +462,12 @@ static int ltdb_search_full(struct ldb_async_handle *handle) ret = tdb_traverse_read(ltdb->tdb, search_func, handle); - handle->state = LDB_ASYNC_DONE; - if (ret == -1) { handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; } - handle->status = LDB_SUCCESS; - return handle->status; + handle->state = LDB_ASYNC_DONE; + return LDB_SUCCESS; } static int ltdb_search_sync_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares) @@ -548,7 +545,6 @@ int ltdb_search_async(struct ldb_module *module, const struct ldb_dn *base, *handle = init_ltdb_handle(ltdb, module, context, callback); if (*handle == NULL) { - talloc_free(*handle); ltdb_unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } @@ -566,13 +562,13 @@ int ltdb_search_async(struct ldb_module *module, const struct ldb_dn *base, } if (ret != LDB_SUCCESS) { ldb_set_errstring(module->ldb, talloc_strdup(module->ldb, "Indexed and full searches both failed!\n")); - talloc_free(*handle); - *handle = NULL; + (*handle)->state = LDB_ASYNC_DONE; + (*handle)->status = ret; } ltdb_unlock_read(module); - return ret; + return LDB_SUCCESS; } /* diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 3a1a08aafd..e0465afb30 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -266,40 +266,41 @@ static int ltdb_add_async(struct ldb_module *module, const struct ldb_message *m { struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); struct ltdb_async_context *ltdb_ac; - int ret = LDB_ERR_OPERATIONS_ERROR; + int tret, ret = LDB_SUCCESS; *handle = init_ltdb_handle(ltdb, module, context, callback); if (*handle == NULL) { - return ret; + return LDB_ERR_OPERATIONS_ERROR; } ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context); - (*handle)->state = LDB_ASYNC_DONE; - (*handle)->status = LDB_SUCCESS; - ret = ltdb_check_special_dn(module, msg); - if (ret != LDB_SUCCESS) { - talloc_free(*handle); - return ret; + tret = ltdb_check_special_dn(module, msg); + if (tret != LDB_SUCCESS) { + (*handle)->status = tret; + goto done; } if (ltdb_cache_load(module) != 0) { - talloc_free(*handle); - return LDB_ERR_OTHER; + ret = LDB_ERR_OTHER; + goto done; } - ret = ltdb_store(module, msg, TDB_INSERT); + tret = ltdb_store(module, msg, TDB_INSERT); - if (ret != LDB_SUCCESS) { - (*handle)->status = ret; - return LDB_SUCCESS; + if (tret != LDB_SUCCESS) { + (*handle)->status = tret; + goto done; } ltdb_modified(module, msg->dn); - if (ltdb_ac->callback) - (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - - return LDB_SUCCESS; + if (ltdb_ac->callback) { + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + } + +done: + (*handle)->state = LDB_ASYNC_DONE; + return ret; } static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg) @@ -354,55 +355,54 @@ static int ltdb_delete_async(struct ldb_module *module, const struct ldb_dn *dn, struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); struct ltdb_async_context *ltdb_ac; struct ldb_message *msg; - int ret = LDB_ERR_OPERATIONS_ERROR; + int tret, ret = LDB_SUCCESS; *handle = NULL; if (ltdb_cache_load(module) != 0) { - goto failed; + return LDB_ERR_OPERATIONS_ERROR; } *handle = init_ltdb_handle(ltdb, module, context, callback); if (*handle == NULL) { - goto failed; + return LDB_ERR_OPERATIONS_ERROR; } ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context); - (*handle)->state = LDB_ASYNC_DONE; - (*handle)->status = LDB_SUCCESS; msg = talloc(ltdb_ac, struct ldb_message); if (msg == NULL) { - goto failed; + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; } /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, dn, msg); - if (ret != 1) { + tret = ltdb_search_dn1(module, dn, msg); + if (tret != 1) { /* not finding the old record is an error */ (*handle)->status = LDB_ERR_NO_SUCH_OBJECT; - return LDB_SUCCESS; + goto done; } - ret = ltdb_delete_noindex(module, dn); - if (ret != LDB_SUCCESS) { - goto failed; + tret = ltdb_delete_noindex(module, dn); + if (tret != LDB_SUCCESS) { + (*handle)->status = LDB_ERR_NO_SUCH_OBJECT; + goto done; } /* remove any indexed attributes */ - ret = ltdb_index_del(module, msg); - if (ret) { - goto failed; + tret = ltdb_index_del(module, msg); + if (tret != LDB_SUCCESS) { + (*handle)->status = LDB_ERR_NO_SUCH_OBJECT; + goto done; } ltdb_modified(module, dn); if (ltdb_ac->callback) - (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - - return LDB_SUCCESS; + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); -failed: - talloc_free(*handle); +done: + (*handle)->state = LDB_ASYNC_DONE; return ret; } @@ -741,42 +741,42 @@ static int ltdb_modify_async(struct ldb_module *module, const struct ldb_message { struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); struct ltdb_async_context *ltdb_ac; - int ret = LDB_ERR_OPERATIONS_ERROR; + int tret, ret = LDB_SUCCESS; *handle = NULL; *handle = init_ltdb_handle(ltdb, module, context, callback); if (*handle == NULL) { - return ret; + return LDB_ERR_OPERATIONS_ERROR; } ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context); - (*handle)->state = LDB_ASYNC_DONE; - (*handle)->status = LDB_SUCCESS; - ret = ltdb_check_special_dn(module, msg); - if (ret != LDB_SUCCESS) { - talloc_free(*handle); - return ret; + tret = ltdb_check_special_dn(module, msg); + if (tret != LDB_SUCCESS) { + (*handle)->status = tret; + goto done; } if (ltdb_cache_load(module) != 0) { - talloc_free(*handle); - return LDB_ERR_OTHER; + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; } - ret = ltdb_modify_internal(module, msg); + tret = ltdb_modify_internal(module, msg); - if (ret != LDB_SUCCESS) { - (*handle)->status = ret; - return LDB_SUCCESS; + if (tret != LDB_SUCCESS) { + (*handle)->status = tret; + goto done; } ltdb_modified(module, msg->dn); if (ltdb_ac->callback) - (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - - return LDB_SUCCESS; + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + +done: + (*handle)->state = LDB_ASYNC_DONE; + return ret; } static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg) @@ -806,62 +806,59 @@ static int ltdb_rename_async(struct ldb_module *module, const struct ldb_dn *old struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); struct ltdb_async_context *ltdb_ac; struct ldb_message *msg; - int ret = LDB_ERR_OPERATIONS_ERROR; + int tret, ret = LDB_SUCCESS; *handle = NULL; if (ltdb_cache_load(module) != 0) { - return ret; + return LDB_ERR_OPERATIONS_ERROR; } *handle = init_ltdb_handle(ltdb, module, context, callback); if (*handle == NULL) { - goto failed; + return LDB_ERR_OPERATIONS_ERROR; } ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context); - (*handle)->state = LDB_ASYNC_DONE; - (*handle)->status = LDB_SUCCESS; msg = talloc(ltdb_ac, struct ldb_message); if (msg == NULL) { - goto failed; + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; } /* in case any attribute of the message was indexed, we need to fetch the old record */ - ret = ltdb_search_dn1(module, olddn, msg); - if (ret != 1) { + tret = ltdb_search_dn1(module, olddn, msg); + if (tret != 1) { /* not finding the old record is an error */ (*handle)->status = LDB_ERR_NO_SUCH_OBJECT; - return LDB_SUCCESS; + goto done; } msg->dn = ldb_dn_copy(msg, newdn); if (!msg->dn) { ret = LDB_ERR_OPERATIONS_ERROR; - goto failed; + goto done; } - ret = ltdb_add(module, msg); - if (ret != LDB_SUCCESS) { - (*handle)->status = LDB_ERR_OPERATIONS_ERROR; - return LDB_SUCCESS; + tret = ltdb_add(module, msg); + if (tret != LDB_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; } - ret = ltdb_delete(module, olddn); - if (ret != LDB_SUCCESS) { + tret = ltdb_delete(module, olddn); + if (tret != LDB_SUCCESS) { ltdb_delete(module, newdn); - (*handle)->status = ret; - return LDB_SUCCESS; + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; } if (ltdb_ac->callback) - (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); + ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - return LDB_SUCCESS; - -failed: - talloc_free(*handle); +done: + (*handle)->state = LDB_ASYNC_DONE; return ret; } 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 }; |