r15913: Error passing in the async code is not in agood shape
authorSimo Sorce <idra@samba.org>
Sun, 28 May 2006 02:10:44 +0000 (02:10 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:08:39 +0000 (14:08 -0500)
Start enhancing it and fix some problems with incorrect evalutaion of the codes

Implement rdn rename (async only)
(This used to be commit 6af1d738b9668d4f0eb6194ac0f84af9e73f8c2e)

source4/dsdb/samdb/ldb_modules/password_hash.c
source4/lib/ldb/ldb_ildap/ldb_ildap.c
source4/lib/ldb/ldb_ldap/ldb_ldap.c
source4/lib/ldb/ldb_tdb/ldb_search.c
source4/lib/ldb/ldb_tdb/ldb_tdb.c
source4/lib/ldb/modules/asq.c
source4/lib/ldb/modules/rdn_name.c

index 2885fb82a2946dfc8c4a9fe2e3cfe9052c661a38..67cb01b9d8f2df67c7d0cf371159326687e61caa 100644 (file)
@@ -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;
 }
 
index ab302dd16d505b39977e4f9af931108548540478..0fa7af25ec2c65a9df4be24fc8183492b4a20735 100644 (file)
@@ -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;
 }
 
 /*
index bbfb1de104a4d5499f73ac94e42d2766cf3ed453..c53db1f90c7885a0e04b26d119665e73ed1d10a0 100644 (file)
@@ -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;
 }
 
index 7e14a3000a9d48a16c86ed4088a652800c116b59..0ab1442c2f768af68e7bce2f24c9864817fecae9 100644 (file)
@@ -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;
 }
 
 /*
index 3a1a08aafd522fe6c0140e9a29a673c5d05b045f..e0465afb30d6ae37b1e3712b83888c476e3abf49 100644 (file)
@@ -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;
 }
 
index 1449ece975cf8b4fdb3b451a7a107f0094bee49b..c682bd6359cbbba5c51ca5e9070a82fbdbe2290b 100644 (file)
@@ -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);
index 18ad625ee21b881803620568fe3af9db1383f098..7ce6c296916391da71677d9b1c4fc4b4adc96f02 100644 (file)
@@ -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
 };