diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/partition.c | 79 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_modules.c | 9 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb_private.h | 3 |
3 files changed, 83 insertions, 8 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index c94c843a83..af8fa475d1 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -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); diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 9eb0a950a4..d38c873c3b 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -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; diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index f442202ee3..97e2828371 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -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); |