diff options
-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 }; |