r14391: rdn_name -> async
authorSimo Sorce <idra@samba.org>
Tue, 14 Mar 2006 17:39:58 +0000 (17:39 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:57:18 +0000 (13:57 -0500)
(This used to be commit 0bc3caa9187e992b09bf797e7de507cca9734ab2)

source4/lib/ldb/modules/operational.c
source4/lib/ldb/modules/rdn_name.c

index fc15da4f6ecc2cd2f1f989878b13b560c197fdda..070f91e762aee1a4c6d77973b567a217853674eb 100644 (file)
@@ -395,8 +395,8 @@ struct operational_async_context {
        const char * const *attrs;
 };
 
-static int operational_async_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares) {
-
+static int operational_async_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares)
+{
        struct operational_async_context *ac;
 
        if (!context || !ares) {
index 59930046cef5ed32d2c174660a16b399064a2b37..24e3430254da970772a24d463b38131911ee0ad3 100644 (file)
@@ -1,7 +1,8 @@
 /* 
    ldb database library
 
-   Copyright (C) Simo Sorce  2004
+   Copyright (C) Andrew Bartlet 2005
+   Copyright (C) Simo Sorce     2006
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
 */
 
 /*
- *  Name: ldb
+ *  Name: rdb_name
  *
- *  Component: ldb objectguid module
+ *  Component: ldb rdn name module
  *
- *  Description: add a unique objectGUID onto every new record
+ *  Description: keep a consistent name attribute on objects manpulations
  *
- *  Author: Simo Sorce
+ *  Author: Andrew Bartlet
+ *
+ *  Modifications:
+ *    - made the module async
+ *      Simo Sorce Mar 2006
  */
 
 #include "includes.h"
@@ -188,6 +193,165 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
        return ret;
 }
 
+static int rdn_name_add_async(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_request *down_req;
+       struct ldb_message *msg;
+       struct ldb_message_element *attribute;
+       struct ldb_dn_component *rdn;
+       int i, ret;
+
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n");
+
+       /* do not manipulate our control entries */
+       if (ldb_dn_is_special(req->op.add.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       down_req = talloc(module, struct ldb_request);
+       if (down_req == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       msg = ldb_msg_copy_shallow(down_req, req->op.add.message);
+       if (msg == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       rdn = ldb_dn_get_rdn(msg, msg->dn);
+       if (rdn == NULL) {
+               talloc_free(down_req);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       
+       /* Perhaps someone above us tried to set this? */
+       if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) {
+               attribute->num_values = 0;
+       }
+
+       if (ldb_msg_add_value(msg, "name", &rdn->value) != 0) {
+               talloc_free(down_req);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       attribute = rdn_name_find_attribute(msg, rdn->name);
+
+       if (!attribute) {
+               if (ldb_msg_add_value(msg, rdn->name, &rdn->value) != 0) {
+                       talloc_free(down_req);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+       } else {
+               const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn->name);
+
+               for (i = 0; i < attribute->num_values; i++) {
+                       if (handler->comparison_fn(module->ldb, msg, &rdn->value, &attribute->values[i]) == 0) {
+                               /* overwrite so it matches in case */
+                               attribute->values[i] = rdn->value;
+                               break;
+                       }
+               }
+               if (i == attribute->num_values) {
+                       ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, 
+                                     "RDN mismatch on %s: %s", 
+                                     ldb_dn_linearize(msg, msg->dn), rdn->name);
+                       talloc_free(down_req);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+       }
+
+       down_req->op.add.message = msg;
+       
+       down_req->controls = req->controls;
+       down_req->creds = req->creds;
+
+       down_req->async.context = req->async.context;
+       down_req->async.callback = req->async.callback;
+       down_req->async.timeout = req->async.timeout;
+
+       /* go on with the call chain */
+       ret = ldb_next_request(module, down_req);
+
+       /* do not free down_req as the call results may be linked to it,
+        * it will be freed when the upper level request get freed */
+       if (ret == LDB_SUCCESS) {
+               req->async.handle = down_req->async.handle;
+       }
+
+       return ret;
+}
+
+static int rdn_name_modify_async(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_request *down_req;
+       struct ldb_message *msg;
+       struct ldb_message_element *attribute;
+       struct ldb_dn_component *rdn;
+       int ret;
+
+       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_modify_record\n");
+
+       /* do not manipulate our control entries */
+       if (ldb_dn_is_special(req->op.mod.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       /* Perhaps someone above us knows better */
+       if ((attribute = rdn_name_find_attribute(req->op.mod.message, "name")) != NULL ) {
+               return ldb_next_request(module, req);
+       }
+
+       /* FIXME: are we sure we wont to change "name" on each and every modify operation ?? */
+       down_req = talloc(module, struct ldb_request);
+       if (down_req == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       msg = ldb_msg_copy_shallow(down_req, req->op.add.message);
+       if (msg == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       rdn = ldb_dn_get_rdn(msg, msg->dn);
+       if (rdn == NULL) {
+               talloc_free(down_req);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       
+       if (ldb_msg_add_value(msg, "name", &rdn->value) != 0) {
+               talloc_free(down_req);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       attribute = rdn_name_find_attribute(msg, "name");
+       if (!attribute) {
+               talloc_free(down_req);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       attribute->flags = LDB_FLAG_MOD_REPLACE;
+
+       down_req->op.add.message = msg;
+       
+       down_req->controls = req->controls;
+       down_req->creds = req->creds;
+
+       down_req->async.context = req->async.context;
+       down_req->async.callback = req->async.callback;
+       down_req->async.timeout = req->async.timeout;
+
+       /* go on with the call chain */
+       ret = ldb_next_request(module, down_req);
+
+       /* do not free down_req as the call results may be linked to it,
+        * it will be freed when the upper level request get freed */
+       if (ret == LDB_SUCCESS) {
+               req->async.handle = down_req->async.handle;
+       }
+
+       return ret;
+}
+
 static int rdn_name_request(struct ldb_module *module, struct ldb_request *req)
 {
        switch (req->operation) {
@@ -198,6 +362,11 @@ static int rdn_name_request(struct ldb_module *module, struct ldb_request *req)
        case LDB_REQ_MODIFY:
                return rdn_name_modify(module, req);
 
+       case LDB_ASYNC_ADD:
+               return rdn_name_add_async(module, req);
+
+       case LDB_ASYNC_MODIFY:
+               return rdn_name_modify_async(module, req);
 
        default:
                return ldb_next_request(module, req);