summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-10-20 09:12:26 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-10-21 22:43:55 +1100
commit154747759e24903106549a341a3fd86624abe6b5 (patch)
tree37b570b30d8a801e215fe1b4f6eb6d57158b9717 /source4/dsdb
parent4c36cac5ad7890d437e15561794c19a3ebd4406b (diff)
downloadsamba-154747759e24903106549a341a3fd86624abe6b5.tar.gz
samba-154747759e24903106549a341a3fd86624abe6b5.tar.bz2
samba-154747759e24903106549a341a3fd86624abe6b5.zip
s4:dsdb Allow creation of new partitions
This is a collection of fixes to allow the creation of new partitions, as well as adding debugging that may be useful in chasing down future failures. Andrew Bartlett
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.h1
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition_init.c170
2 files changed, 101 insertions, 70 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/partition.h b/source4/dsdb/samdb/ldb_modules/partition.h
index 9bab2dbcbc..3572f17109 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.h
+++ b/source4/dsdb/samdb/ldb_modules/partition.h
@@ -29,6 +29,7 @@
struct dsdb_partition {
struct ldb_module *module;
struct dsdb_control_current_partition *ctrl;
+ const char *backend_url;
};
struct partition_module {
diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c
index a5e83e734d..d8733a44c5 100644
--- a/source4/dsdb/samdb/ldb_modules/partition_init.c
+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c
@@ -120,6 +120,7 @@ static int partition_load_modules(struct ldb_context *ldb,
}
}
}
+ data->modules[i] = NULL;
return LDB_SUCCESS;
}
@@ -182,10 +183,9 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
TALLOC_CTX *mem_ctx,
struct ldb_dn *dn, const char *casefold_dn,
struct dsdb_partition **partition) {
- const char *backend_name;
- const char *full_backend;
+ const char *backend_url;
struct dsdb_control_current_partition *ctrl;
- struct ldb_module *module;
+ struct ldb_module *backend_module;
const char **modules;
int ret;
@@ -203,11 +203,12 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
/* See if an LDAP backend has been specified */
if (data->ldapBackend) {
- backend_name = data->ldapBackend;
+ backend_url = data->ldapBackend;
} else {
/* the backend LDB is the DN (base64 encoded if not 'plain') followed by .ldb */
const char *p;
+ char *backend_path;
char *base64_dn = NULL;
for (p = casefold_dn; *p; p++) {
/* We have such a strict check because I don't want shell metacharacters in the file name, nor ../ */
@@ -219,33 +220,40 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
casefold_dn = base64_dn = ldb_base64_encode(data, casefold_dn, strlen(casefold_dn));
}
- backend_name = talloc_asprintf(data, "%s.ldb", casefold_dn);
+ backend_path = samdb_relative_path(ldb,
+ *partition,
+ casefold_dn);
if (base64_dn) {
talloc_free(base64_dn);
}
+ if (!backend_path) {
+ ldb_asprintf_errstring(ldb,
+ "partition_init: unable to determine an relative path for partition: %s", casefold_dn);
+ talloc_free(*partition);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ backend_url = talloc_asprintf(*partition, "tdb://%s.ldb",
+ backend_path);
+ talloc_free(backend_path);
+ if (!backend_url) {
+ ldb_oom(ldb);
+ talloc_free(*partition);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
+ (*partition)->backend_url = backend_url;
ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
ctrl->dn = talloc_steal(ctrl, dn);
- full_backend = samdb_relative_path(ldb,
- *partition,
- backend_name);
- if (!full_backend) {
- ldb_asprintf_errstring(ldb_module_get_ctx(module),
- "partition_init: unable to determine an relative path for partition: %s", backend_name);
- talloc_free(*partition);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = ldb_connect_backend(ldb, full_backend, NULL, &module);
+ ret = ldb_connect_backend(ldb, backend_url, NULL, &backend_module);
if (ret != LDB_SUCCESS) {
return ret;
}
modules = find_modules_for_dn(data, dn);
- ret = ldb_load_modules_list(ldb, modules, module, &(*partition)->module);
+ ret = ldb_load_modules_list(ldb, modules, backend_module, &(*partition)->module);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb,
"partition_init: "
@@ -342,6 +350,8 @@ int partition_reload_if_required(struct ldb_module *module,
uint64_t seq;
int ret, i;
struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct ldb_message *msg;
+ struct ldb_message_element *partition_attributes;
TALLOC_CTX *mem_ctx = talloc_new(data);
if (!data) {
/* Not initilised yet */
@@ -356,59 +366,75 @@ int partition_reload_if_required(struct ldb_module *module,
talloc_free(mem_ctx);
return ret;
}
- if (seq != data->metadata_seq) {
- struct ldb_message *msg;
- struct ldb_message_element *partition_attributes;
- ret = partition_reload_metadata(module, data, mem_ctx, &msg);
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
- }
+ if (seq == data->metadata_seq) {
+ talloc_free(mem_ctx);
+ return LDB_SUCCESS;
+ }
- data->metadata_seq = seq;
+ ret = partition_reload_metadata(module, data, mem_ctx, &msg);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
- partition_attributes = ldb_msg_find_element(msg, "partition");
+ data->metadata_seq = seq;
- for (i=0; partition_attributes && i < partition_attributes->num_values; i++) {
- bool new_partition = true;
- struct dsdb_partition *partition;
- struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &partition_attributes->values[i]);
- if (!dn) {
- ldb_asprintf_errstring(ldb,
- "partition_init: invalid DN in partition record: %s", (const char *)partition_attributes->values[i].data);
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- for (i=0; data->partitions && data->partitions[i]; i++) {
- if (ldb_dn_compare(data->partitions[i]->ctrl->dn, dn) == 0) {
- new_partition = false;
- break;
- }
- }
- if (new_partition == false) {
- continue;
+ partition_attributes = ldb_msg_find_element(msg, "partition");
+
+ for (i=0; partition_attributes && i < partition_attributes->num_values; i++) {
+ int j;
+ bool new_partition = true;
+ struct ldb_dn *dn;
+ struct dsdb_partition *partition;
+ for (j=0; data->partitions && data->partitions[j]; j++) {
+ DATA_BLOB casefold = data_blob_string_const(ldb_dn_get_casefold(data->partitions[j]->ctrl->dn));
+ if (data_blob_cmp(&casefold, &partition_attributes->values[i]) == 0) {
+ new_partition = false;
+ break;
}
+ }
+ if (new_partition == false) {
+ continue;
+ }
- /* We call ldb_dn_get_linearized() because the DN in
- * partition_attributes is already casefolded
- * correctly. We don't want to mess that up as the
- * schema isn't loaded yet */
- ret = new_partition_from_dn(ldb, data, data->partitions, dn,
- ldb_dn_get_linearized(dn),
- &partition);
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
- }
+ dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &partition_attributes->values[i]);
+ if (!dn) {
+ ldb_asprintf_errstring(ldb,
+ "partition_init: invalid DN in partition record: %s", (const char *)partition_attributes->values[i].data);
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
- ret = add_partition_to_data(ldb, data, partition);
- if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
- }
+ if (ldb_dn_compare_base(ldb_get_default_basedn(ldb), dn) != 0) {
+ ldb_asprintf_errstring(ldb,
+ "partition_init: invalid DN in partition record: %s is not under %s. Perhaps an old " DSDB_PARTITION_DN " format?",
+ (const char *)partition_attributes->values[i].data,
+ ldb_dn_get_linearized(ldb_get_default_basedn(ldb)));
+ DEBUG(0, ("Unable to load partitions, invalid DN %s found, perhaps you need to reprovision? See partition-upgrade.txt for instructions\n",
+ (const char *)partition_attributes->values[i].data));
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ /* We call ldb_dn_get_linearized() because the DN in
+ * partition_attributes is already casefolded
+ * correctly. We don't want to mess that up as the
+ * schema isn't loaded yet */
+ ret = new_partition_from_dn(ldb, data, data->partitions, dn,
+ ldb_dn_get_linearized(dn),
+ &partition);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ ret = add_partition_to_data(ldb, data, partition);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
}
}
+
talloc_free(mem_ctx);
return LDB_SUCCESS;
}
@@ -434,8 +460,9 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb,
"Failed to search for %s from " DSDB_PARTITION_DN
- " replicateEntries for new partition at %s: %s",
+ " replicateEntries for new partition at %s on %s: %s",
ldb_dn_get_linearized(data->replicate[i]),
+ partition->backend_url,
ldb_dn_get_linearized(partition->ctrl->dn),
ldb_errstring(ldb));
return ret;
@@ -451,7 +478,7 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
return ret;
}
/* do request */
- ret = ldb_next_request(partition->module, add_req);
+ ret = partition_request(partition->module, add_req);
/* wait */
if (ret == LDB_SUCCESS) {
ret = ldb_wait(add_req->handle, LDB_WAIT_ALL);
@@ -478,7 +505,7 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
return ret;
}
/* do request */
- ret = ldb_next_request(partition->module, del_req);
+ ret = partition_request(partition->module, del_req);
/* wait */
if (ret == LDB_SUCCESS) {
@@ -487,8 +514,9 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb,
"Failed to delete (for re-add) %s from " DSDB_PARTITION_DN
- " replicateEntries in new partition at %s: %s",
+ " replicateEntries in new partition at %s on %s: %s",
ldb_dn_get_linearized(data->replicate[i]),
+ partition->backend_url,
ldb_dn_get_linearized(partition->ctrl->dn),
ldb_errstring(ldb));
return ret;
@@ -504,7 +532,7 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
}
/* do the add again */
- ret = ldb_next_request(partition->module, add_req);
+ ret = partition_request(partition->module, add_req);
/* wait */
if (ret == LDB_SUCCESS) {
@@ -514,8 +542,9 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb,
"Failed to add (after delete) %s from " DSDB_PARTITION_DN
- " replicateEntries to new partition at %s: %s",
+ " replicateEntries to new partition at %s on %s: %s",
ldb_dn_get_linearized(data->replicate[i]),
+ partition->backend_url,
ldb_dn_get_linearized(partition->ctrl->dn),
ldb_errstring(ldb));
return ret;
@@ -526,8 +555,9 @@ static int new_partition_set_replicated_metadata(struct ldb_context *ldb,
{
ldb_asprintf_errstring(ldb,
"Failed to add %s from " DSDB_PARTITION_DN
- " replicateEntries to new partition at %s: %s",
+ " replicateEntries to new partition at %s on %s: %s",
ldb_dn_get_linearized(data->replicate[i]),
+ partition->backend_url,
ldb_dn_get_linearized(partition->ctrl->dn),
ldb_errstring(ldb));
return ret;
@@ -601,7 +631,7 @@ int partition_create(struct ldb_module *module, struct ldb_request *req)
last_req = mod_req;
- ret = ldb_next_request(module, mod_req);
+ ret = partition_request(module, mod_req);
if (ret == LDB_SUCCESS) {
ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
}