}
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;
done:
handle->state = LDB_ASYNC_DONE;
- handle->status = ret;
return ret;
}
return LDB_ERR_OPERATIONS_ERROR;
}
- return handle->status;
+ return LDB_SUCCESS;
}
/*
char *errmsgp = NULL;
char **referralsp = NULL;
LDAPControl **serverctrlsp = NULL;
- int ret;
+ int ret = LDB_SUCCESS;
type = ldap_msgtype(result);
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);
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;
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) {
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;
ares = talloc_zero(ac, struct ldb_async_result);
if (!ares) {
- handle->status = LDB_ERR_OPERATIONS_ERROR;
+ ret = LDB_ERR_OPERATIONS_ERROR;
goto error;
}
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;
}
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;
}
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)
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;
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;
}
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)
*handle = init_ltdb_handle(ltdb, module, context, callback);
if (*handle == NULL) {
- talloc_free(*handle);
ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
}
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;
}
/*
{
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)
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;
}
{
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)
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;
}
}
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);
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;
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;
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;
}
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);
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
};