From 73120327cc136229d56d08f7f8c5e8df4129c1e3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Jan 2013 22:33:48 -0500 Subject: Upgrade DB and move ranges into top level object --- src/db/sysdb.c | 7 ++++ src/db/sysdb_private.h | 7 +++- src/db/sysdb_upgrade.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) diff --git a/src/db/sysdb.c b/src/db/sysdb.c index 4127b912..2647c630 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -1129,6 +1129,13 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx, } } + if (strcmp(version, SYSDB_VERSION_0_14) == 0) { + ret = sysdb_upgrade_14(sysdb, &version); + if (ret != EOK) { + goto done; + } + } + /* The version should now match SYSDB_VERSION. * If not, it means we didn't match any of the * known older versions. The DB might be diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h index 4763f03f..1e361778 100644 --- a/src/db/sysdb_private.h +++ b/src/db/sysdb_private.h @@ -23,6 +23,7 @@ #ifndef __INT_SYS_DB_H__ #define __INT_SYS_DB_H__ +#define SYSDB_VERSION_0_15 "0.15" #define SYSDB_VERSION_0_14 "0.14" #define SYSDB_VERSION_0_13 "0.13" #define SYSDB_VERSION_0_12 "0.12" @@ -38,7 +39,7 @@ #define SYSDB_VERSION_0_2 "0.2" #define SYSDB_VERSION_0_1 "0.1" -#define SYSDB_VERSION SYSDB_VERSION_0_14 +#define SYSDB_VERSION SYSDB_VERSION_0_15 #define SYSDB_BASE_LDIF \ "dn: @ATTRIBUTES\n" \ @@ -74,6 +75,9 @@ "cn: sysdb\n" \ "version: " SYSDB_VERSION "\n" \ "description: base object\n" \ + "\n" \ + "dn: cn=ranges,cn=sysdb\n" \ + "cn: ranges\n" \ "\n" #include "db/sysdb.h" @@ -113,6 +117,7 @@ int sysdb_upgrade_10(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_11(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver); +int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver); int add_string(struct ldb_message *msg, int flags, const char *attr, const char *value); diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c index fc9b2c96..42a048d1 100644 --- a/src/db/sysdb_upgrade.c +++ b/src/db/sysdb_upgrade.c @@ -1369,6 +1369,117 @@ done: return ret; } +int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver) +{ + struct upgrade_ctx *ctx; + struct ldb_message *msg; + struct ldb_result *res; + struct ldb_dn *basedn; + struct ldb_dn *newdn; + const char *attrs[] = { SYSDB_NAME, NULL }; + const char *tmp_str; + errno_t ret; + int i; + + ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_15, &ctx); + if (ret) { + return ret; + } + + basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE); + if (!basedn) { + DEBUG(SSSDBG_OP_FAILURE, ("Failed to build base dn\n")); + ret = EIO; + goto done; + } + + /* create base ranges container */ + msg = ldb_msg_new(ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_RANGE_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "cn", "ranges"); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + /* do a synchronous add */ + ret = ldb_add(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(SSSDBG_FATAL_FAILURE, + ("Failed to upgrade DB (%d, [%s])!\n", + ret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + talloc_zfree(msg); + + ret = ldb_search(sysdb->ldb, ctx, &res, + basedn, LDB_SCOPE_SUBTREE, attrs, + "objectclass=%s", SYSDB_ID_RANGE_CLASS); + if (ret != LDB_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("Failed to search range objects\n")); + ret = EIO; + goto done; + } + + /* Failure to convert any range is not fatal. As long as there are no + * left-over objects we can fail to move them around, as they will be + * recreated on the next online access */ + for (i = 0; i < res->count; i++) { + tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); + if (tmp_str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + ("The object [%s] doesn't have a name\n", + ldb_dn_get_linearized(res->msgs[i]->dn))); + ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, + ("Failed to delete %s\n", res->msgs[i]->dn)); + ret = EIO; + goto done; + } + continue; + } + + newdn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_TMPL_RANGE, tmp_str); + if (!newdn) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to create new DN to move [%s]\n", + ldb_dn_get_linearized(res->msgs[i]->dn))); + ret = ENOMEM; + goto done; + } + ret = ldb_rename(sysdb->ldb, res->msgs[i]->dn, newdn); + if (ret != LDB_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to move [%s] to [%s]\n", + ldb_dn_get_linearized(res->msgs[i]->dn), + ldb_dn_get_linearized(newdn))); + ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, + ("Failed to delete %s\n", res->msgs[i]->dn)); + ret = EIO; + goto done; + } + } + talloc_zfree(newdn); + } + + /* conversion done, update version number */ + ret = update_version(ctx); + +done: + ret = finish_upgrade(ret, &ctx, ver); + return ret; +} /* * Example template for future upgrades. -- cgit