summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.c79
-rw-r--r--source4/lib/ldb/common/ldb_modules.c9
-rw-r--r--source4/lib/ldb/include/ldb_private.h3
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);