summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-10-21 22:27:22 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-10-21 22:43:57 +1100
commitd7cf71d9b6cae19b2f9a215f910b4b6e1474291d (patch)
tree4c39f6331958215886bdd4981f9c752f76480301 /source4/dsdb/samdb
parent4209cf9860b528f2ac9da175feec8783a35950f9 (diff)
downloadsamba-d7cf71d9b6cae19b2f9a215f910b4b6e1474291d.tar.gz
samba-d7cf71d9b6cae19b2f9a215f910b4b6e1474291d.tar.bz2
samba-d7cf71d9b6cae19b2f9a215f910b4b6e1474291d.zip
s4:dsdb Allow loading of old-style partition records
This should make upgrades easier
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition_init.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c
index 421169d371..c88d418783 100644
--- a/source4/dsdb/samdb/ldb_modules/partition_init.c
+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c
@@ -181,7 +181,7 @@ static const char **find_modules_for_dn(struct partition_private_data *data, str
static int new_partition_from_dn(struct ldb_context *ldb, struct partition_private_data *data,
TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn, const char *casefold_dn,
+ struct ldb_dn *dn, const char *filename_base,
struct dsdb_partition **partition) {
const char *backend_url;
struct dsdb_control_current_partition *ctrl;
@@ -210,25 +210,25 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
const char *p;
char *backend_path;
char *base64_dn = NULL;
- for (p = casefold_dn; *p; p++) {
+ for (p = filename_base; *p; p++) {
/* We have such a strict check because I don't want shell metacharacters in the file name, nor ../ */
if (!(isalnum(*p) || *p == ' ' || *p == '=' || *p == ',')) {
break;
}
}
if (*p) {
- casefold_dn = base64_dn = ldb_base64_encode(data, casefold_dn, strlen(casefold_dn));
+ filename_base = base64_dn = ldb_base64_encode(data, filename_base, strlen(filename_base));
}
backend_path = samdb_relative_path(ldb,
*partition,
- casefold_dn);
+ filename_base);
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);
+ "partition_init: unable to determine an relative path for partition: %s", filename_base);
talloc_free(*partition);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -254,6 +254,11 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
modules = find_modules_for_dn(data, dn);
+ if (!modules) {
+ DEBUG(0, ("Unable to load partition modules for new DN %s, perhaps you need to reprovision? See partition-upgrade.txt for instructions\n", ldb_dn_get_linearized(dn)));
+ talloc_free(*partition);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
ret = ldb_load_modules_list(ldb, modules, backend_module, &(*partition)->module);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(ldb,
@@ -385,6 +390,7 @@ int partition_reload_if_required(struct ldb_module *module,
for (i=0; partition_attributes && i < partition_attributes->num_values; i++) {
int j;
bool new_partition = true;
+ const char *filename_base = NULL;
DATA_BLOB dn_blob;
struct ldb_dn *dn;
struct dsdb_partition *partition;
@@ -401,6 +407,26 @@ int partition_reload_if_required(struct ldb_module *module,
dn_blob = partition_attributes->values[i];
+ if (dn_blob.length > 4 &&
+ (strncmp((const char *)&dn_blob.data[dn_blob.length-4], ".ldb", 4) == 0)) {
+
+ /* Look for DN:filename.ldb */
+ char *p = strchr((const char *)dn_blob.data, ':');
+ if (!p) {
+ ldb_asprintf_errstring(ldb,
+ "partition_init: invalid DN in attempting to parse old-style partition record: %s", (const char *)dn_blob.data);
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ filename_base = p+1;
+
+ /* Trim off the .ldb */
+ dn_blob.data[dn_blob.length-4] = '\0';
+
+ /* Now trim off the filename */
+ dn_blob.length = ((uint8_t *)p - dn_blob.data);
+ }
+
dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &dn_blob);
if (!dn) {
ldb_asprintf_errstring(ldb,
@@ -408,26 +434,17 @@ int partition_reload_if_required(struct ldb_module *module,
talloc_free(mem_ctx);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
-
- if (dn_blob.length > 4 &&
- (strncmp((const char *)&dn_blob.data[dn_blob.length-4], ".ldb", 4) == 0) &&
- (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 *)dn_blob.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 *)dn_blob.data));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
+
+ if (!filename_base) {
+ filename_base = ldb_dn_get_linearized(dn);
}
-
+
/* 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),
+ filename_base,
&partition);
if (ret != LDB_SUCCESS) {
talloc_free(mem_ctx);