r17474: Allow the partitions module to load modules for specific backends.
authorAndrew Bartlett <abartlet@samba.org>
Thu, 10 Aug 2006 01:51:27 +0000 (01:51 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:15:27 +0000 (14:15 -0500)
Andrew Bartlett

source/dsdb/samdb/ldb_modules/partition.c
source/lib/ldb/common/ldb_modules.c
source/lib/ldb/include/ldb_private.h

index c94c843a8372f6994641998f44aee842e6cbc32f..af8fa475d1d980771f93e69e4b2ba5efd08e61a2 100644 (file)
@@ -502,11 +502,12 @@ static int partition_init(struct ldb_module *module)
 {
        int ret, i;
        TALLOC_CTX *mem_ctx = talloc_new(module);
-       static const char *attrs[] = { "partition", "replicateEntries", NULL };
+       static const char *attrs[] = { "partition", "replicateEntries", "modules", NULL };
        struct ldb_result *res;
        struct ldb_message *msg;
        struct ldb_message_element *partition_attributes;
        struct ldb_message_element *replicate_attributes;
+       struct ldb_message_element *modules_attributes;
 
        struct partition_private_data *data;
 
@@ -545,6 +546,7 @@ static int partition_init(struct ldb_module *module)
                ldb_set_errstring(module->ldb, 
                                  talloc_asprintf(module, "partition_init: "
                                                  "no partitions specified"));
+               talloc_free(mem_ctx);
                return LDB_ERR_CONSTRAINT_VIOLATION;
        }
        data->partitions = talloc_array(data, struct partition *, partition_attributes->num_values + 1);
@@ -559,6 +561,7 @@ static int partition_init(struct ldb_module *module)
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, "partition_init: "
                                                          "invalid form for partition record (missing ':'): %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
                p[0] = '\0';
@@ -567,6 +570,7 @@ static int partition_init(struct ldb_module *module)
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, "partition_init: "
                                                          "invalid form for partition record (missing backend database): %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
                data->partitions[i] = talloc(data->partitions, struct partition);
@@ -580,12 +584,14 @@ static int partition_init(struct ldb_module *module)
                        ldb_set_errstring(module->ldb, 
                                          talloc_asprintf(module, "partition_init: "
                                                          "invalid DN in partition record: %s", base));
+                       talloc_free(mem_ctx);
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
 
                data->partitions[i]->backend = private_path(data->partitions[i], p);
                ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module);
                if (ret != LDB_SUCCESS) {
+                       talloc_free(mem_ctx);
                        return ret;
                }
        }
@@ -600,6 +606,7 @@ static int partition_init(struct ldb_module *module)
                req = talloc_zero(mem_ctx, struct ldb_request);
                if (req == NULL) {
                        ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out of memory!\n");
+                       talloc_free(mem_ctx);
                        return LDB_ERR_OPERATIONS_ERROR;
                }
                
@@ -609,6 +616,7 @@ static int partition_init(struct ldb_module *module)
                ret = ldb_request(module->ldb, req);
                if (ret != LDB_SUCCESS) {
                        ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Unable to register partition with rootdse!\n");
+                       talloc_free(mem_ctx);
                        return LDB_ERR_OTHER;
                }
                talloc_free(req);
@@ -616,9 +624,6 @@ static int partition_init(struct ldb_module *module)
 
        replicate_attributes = ldb_msg_find_element(msg, "replicateEntries");
        if (!replicate_attributes) {
-               ldb_set_errstring(module->ldb, 
-                                 talloc_asprintf(module, "partition_init: "
-                                                 "no entries to replicate specified"));
                data->replicate = NULL;
        } else {
                data->replicate = talloc_array(data, struct ldb_dn *, replicate_attributes->num_values + 1);
@@ -634,12 +639,78 @@ static int partition_init(struct ldb_module *module)
                                                  talloc_asprintf(module, "partition_init: "
                                                                  "invalid DN in partition replicate record: %s", 
                                                                  replicate_attributes->values[i].data));
+                               talloc_free(mem_ctx);
                                return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
                }
                data->replicate[i] = NULL;
        }
 
+       modules_attributes = ldb_msg_find_element(msg, "modules");
+       if (modules_attributes) {
+               for (i=0; i < modules_attributes->num_values; i++) {
+                       struct ldb_dn *base_dn;
+                       int partition_idx;
+                       struct partition *partition = NULL;
+                       const char **modules = NULL;
+
+                       char *base = talloc_strdup(data->partitions, (char *)modules_attributes->values[i].data);
+                       char *p = strchr(base, ':');
+                       if (!p) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, "partition_init: "
+                                                                 "invalid form for partition module record (missing ':'): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+                       p[0] = '\0';
+                       p++;
+                       if (!p[0]) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, "partition_init: "
+                                                                 "invalid form for partition module record (missing backend database): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+
+                       modules = ldb_modules_list_from_string(module->ldb, mem_ctx,
+                                                              p);
+                       
+                       base_dn = ldb_dn_explode(mem_ctx, base);
+                       if (!base_dn) {
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       
+                       for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) {
+                               if (ldb_dn_compare(module->ldb, data->partitions[partition_idx]->dn, 
+                                                  base_dn) == 0) {
+                                       partition = data->partitions[partition_idx];
+                                       break;
+                               }
+                       }
+                       
+                       if (!partition) {
+                               ldb_set_errstring(module->ldb, 
+                                                 talloc_asprintf(mem_ctx, "partition_init: "
+                                                                 "invalid form for partition module record (no such partition): %s", base));
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                       }
+                       
+                       ret = ldb_load_modules_list(module->ldb, modules, partition->module, &partition->module);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+                       ret = ldb_init_module_chain(module->ldb, partition->module);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+               }
+       }
+
        module->private_data = data;
        talloc_steal(module, data);
        
index 9eb0a950a40275c90155fe3bb3adaf7289d0f7f1..d38c873c3bd6dd4f61c4b9d0fabf836c40d9e065 100644 (file)
@@ -73,7 +73,7 @@ static char *talloc_strdup_no_spaces(struct ldb_context *ldb, const char *string
 /* modules are called in inverse order on the stack.
    Lets place them as an admin would think the right order is.
    Modules order is important */
-static const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string)
+const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string)
 {
        char **modules = NULL;
        const char **m;
@@ -95,6 +95,7 @@ static const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC
        talloc_steal(modules, modstr);
 
        i = 0;
+       /* The str*r*chr walks backwards:  This is how we get the inverse order mentioned above */
        while ((p = strrchr(modstr, ',')) != NULL) {
                *p = '\0';
                p++;
@@ -236,10 +237,10 @@ int ldb_try_load_dso(struct ldb_context *ldb, const char *name)
 #endif
 }
 
-static int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
+int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
 {
        struct ldb_module *module;
-       int i, ret;
+       int i;
        
        module = backend;
 
@@ -274,7 +275,7 @@ static int ldb_load_modules_list(struct ldb_context *ldb, const char **module_li
        return LDB_SUCCESS;
 }
 
-static int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) 
+int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) 
 {
        while (module && module->ops->init_context == NULL) 
                module = module->next;
index f442202ee3bc6e1144a04602dfe6d914feefe3e9..97e2828371b2fdfff0ba4ea4888bbe410082c907 100644 (file)
@@ -137,7 +137,10 @@ int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *op
 
 /* The following definitions come from lib/ldb/common/ldb_modules.c  */
 
+const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string);
+int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out);
 int ldb_load_modules(struct ldb_context *ldb, const char *options[]);
+int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module);
 int ldb_next_request(struct ldb_module *module, struct ldb_request *request);
 int ldb_next_start_trans(struct ldb_module *module);
 int ldb_next_end_trans(struct ldb_module *module);