summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c110
-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
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
};