summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2006-05-28 02:10:44 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:39 -0500
commit90a5e19e03842b77fd7811965fb2603e552261bc (patch)
tree211bda772b224b6cfdc54e5b3fc1857fc539d9dd /source4/lib
parent53107aed4a45f28aa1a159019ff4c3b45fbc8f02 (diff)
downloadsamba-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')
-rw-r--r--source4/lib/ldb/ldb_ildap/ldb_ildap.c2
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c77
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c14
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c153
-rw-r--r--source4/lib/ldb/modules/asq.c3
-rw-r--r--source4/lib/ldb/modules/rdn_name.c205
6 files changed, 323 insertions, 131 deletions
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
};