From c2352a73f52f600d95966ebe0b0819649ba923fa Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Wed, 5 Oct 2011 13:57:24 -0400 Subject: SYSDB: New source file for sysdb upgrade routines --- src/db/sysdb_upgrade.c | 896 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 896 insertions(+) create mode 100644 src/db/sysdb_upgrade.c (limited to 'src/db/sysdb_upgrade.c') diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c new file mode 100644 index 00000000..c8933223 --- /dev/null +++ b/src/db/sysdb_upgrade.c @@ -0,0 +1,896 @@ +/* + SSSD + + Authors: + Simo Sorce + Stephen Gallagher + + Copyright (C) 2008-2011 Simo Sorce + Copyright (C) 2008-2011 Stephen Gallagher + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "util/util.h" +#include "db/sysdb_private.h" + +static int finish_upgrade(int result, struct ldb_context *ldb, + const char *next_ver, const char **ver) +{ + int ret = result; + + if (ret == EOK) { + ret = ldb_transaction_commit(ldb); + ret = sysdb_error_to_errno(ret); + if (ret == EOK) { + *ver = next_ver; + } + } + + if (ret != EOK) { + ret = ldb_transaction_cancel(ldb); + ret = sysdb_error_to_errno(ret); + } + + return ret; +} + +/* serach all groups that have a memberUid attribute. + * change it into a member attribute for a user of same domain. + * remove the memberUid attribute + * add the new member attribute + * finally stop indexing memberUid + * upgrade version to 0.2 + */ +int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver) +{ + struct ldb_message_element *el; + struct ldb_result *res; + struct ldb_dn *basedn; + struct ldb_dn *mem_dn; + struct ldb_message *msg; + const struct ldb_val *val; + const char *filter = "(&(memberUid=*)(objectclass=group))"; + const char *attrs[] = { "memberUid", NULL }; + const char *mdn; + char *domain; + int ret, i, j; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + ret = ENOMEM; + goto done; + } + + basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); + if (!basedn) { + ret = EIO; + goto done; + } + + ret = ldb_search(ldb, tmp_ctx, &res, + basedn, LDB_SCOPE_SUBTREE, + attrs, filter); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + for (i = 0; i < res->count; i++) { + el = ldb_msg_find_element(res->msgs[i], "memberUid"); + if (!el) { + DEBUG(1, ("memberUid is missing from message [%s], skipping\n", + ldb_dn_get_linearized(res->msgs[i]->dn))); + continue; + } + + /* create modification message */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = res->msgs[i]->dn; + + ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* get domain name component value */ + val = ldb_dn_get_component_val(res->msgs[i]->dn, 2); + domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length); + if (!domain) { + ret = ENOMEM; + goto done; + } + + for (j = 0; j < el->num_values; j++) { + mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER, + (const char *)el->values[j].data, domain); + if (!mem_dn) { + ret = ENOMEM; + goto done; + } + + mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn)); + if (!mdn) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + talloc_zfree(mem_dn); + } + + /* ok now we are ready to modify the entry */ + ret = ldb_modify(ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + talloc_zfree(msg); + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_2); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = EOK; + +done: + ret = finish_upgrade(ret, ldb, SYSDB_VERSION_0_2, ver); + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_check_upgrade_02(struct sss_domain_info *domains, + const char *db_path) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_context *ldb; + char *ldb_file; + struct sysdb_ctx *sysdb; + struct sss_domain_info *dom; + struct ldb_message_element *el; + struct ldb_message *msg; + struct ldb_result *res; + struct ldb_dn *verdn; + const char *version = NULL; + bool do_02_upgrade = false; + bool ctx_trans = false; + int ret; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + ret = sysdb_get_db_file(tmp_ctx, + "local", "UPGRADE", + db_path, &ldb_file); + if (ret != EOK) { + goto exit; + } + + ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); + if (ret != EOK) { + DEBUG(1, ("sysdb_ldb_connect failed.\n")); + return ret; + } + + verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); + if (!verdn) { + ret = EIO; + goto exit; + } + + ret = ldb_search(ldb, tmp_ctx, &res, + verdn, LDB_SCOPE_BASE, + NULL, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto exit; + } + if (res->count > 1) { + ret = EIO; + goto exit; + } + + if (res->count == 1) { + el = ldb_msg_find_element(res->msgs[0], "version"); + if (el) { + if (el->num_values != 1) { + ret = EINVAL; + goto exit; + } + version = talloc_strndup(tmp_ctx, + (char *)(el->values[0].data), + el->values[0].length); + if (!version) { + ret = ENOMEM; + goto exit; + } + + if (strcmp(version, SYSDB_VERSION) == 0) { + /* all fine, return */ + ret = EOK; + goto exit; + } + + DEBUG(4, ("Upgrading DB from version: %s\n", version)); + + if (strcmp(version, SYSDB_VERSION_0_1) == 0) { + /* convert database */ + ret = sysdb_upgrade_01(ldb, &version); + if (ret != EOK) goto exit; + } + + if (strcmp(version, SYSDB_VERSION_0_2) == 0) { + /* need to convert database to split files */ + do_02_upgrade = true; + } + + } + } + + if (!do_02_upgrade) { + /* not a v2 upgrade, return and let the normal code take over any + * further upgrade */ + ret = EOK; + goto exit; + } + + /* == V2->V3 UPGRADE == */ + + DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3)); + + /* ldb uses posix locks, + * posix is stupid and kills all locks when you close *any* file + * descriptor associated to the same file. + * Therefore we must close and reopen the ldb file here */ + + /* == Backup and reopen ldb == */ + + /* close */ + talloc_zfree(ldb); + + /* backup*/ + ret = backup_file(ldb_file, 0); + if (ret != EOK) { + goto exit; + } + + /* reopen */ + ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); + if (ret != EOK) { + DEBUG(1, ("sysdb_ldb_connect failed.\n")); + return ret; + } + + /* open a transaction */ + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret)); + ret = EIO; + goto exit; + } + + /* == Upgrade contents == */ + + for (dom = domains; dom; dom = dom->next) { + struct ldb_dn *domain_dn; + struct ldb_dn *users_dn; + struct ldb_dn *groups_dn; + int i; + + /* skip local */ + if (strcasecmp(dom->provider, "local") == 0) { + continue; + } + + /* create new dom db */ + ret = sysdb_domain_init_internal(tmp_ctx, dom, + db_path, false, &sysdb); + if (ret != EOK) { + goto done; + } + + ret = ldb_transaction_start(sysdb->ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret)); + ret = EIO; + goto done; + } + ctx_trans = true; + + /* search all entries for this domain in local, + * copy them all in the new database, + * then remove them from local */ + + domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_DOM_BASE, sysdb->domain->name); + if (!domain_dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_search(ldb, tmp_ctx, &res, + domain_dn, LDB_SCOPE_SUBTREE, + NULL, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + users_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_TMPL_USER_BASE, sysdb->domain->name); + if (!users_dn) { + ret = ENOMEM; + goto done; + } + groups_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_TMPL_GROUP_BASE, sysdb->domain->name); + if (!groups_dn) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < res->count; i++) { + + struct ldb_dn *orig_dn; + + msg = res->msgs[i]; + + /* skip pre-created congtainers */ + if ((ldb_dn_compare(msg->dn, domain_dn) == 0) || + (ldb_dn_compare(msg->dn, users_dn) == 0) || + (ldb_dn_compare(msg->dn, groups_dn) == 0)) { + continue; + } + + /* regenerate the DN against the new ldb as it may have different + * casefolding rules (example: name changing from case insensitive + * to case sensitive) */ + orig_dn = msg->dn; + msg->dn = ldb_dn_new(msg, sysdb->ldb, + ldb_dn_get_linearized(orig_dn)); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_add(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("WARNING: Could not add entry %s," + " to new ldb file! (%d [%s])\n", + ldb_dn_get_linearized(msg->dn), + ret, ldb_errstring(sysdb->ldb))); + } + + ret = ldb_delete(ldb, orig_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("WARNING: Could not remove entry %s," + " from old ldb file! (%d [%s])\n", + ldb_dn_get_linearized(orig_dn), + ret, ldb_errstring(ldb))); + } + } + + /* now remove the basic containers from local */ + /* these were optional so debug at level 9 in case + * of failure just for tracing */ + ret = ldb_delete(ldb, groups_dn); + if (ret != LDB_SUCCESS) { + DEBUG(9, ("WARNING: Could not remove entry %s," + " from old ldb file! (%d [%s])\n", + ldb_dn_get_linearized(groups_dn), + ret, ldb_errstring(ldb))); + } + ret = ldb_delete(ldb, users_dn); + if (ret != LDB_SUCCESS) { + DEBUG(9, ("WARNING: Could not remove entry %s," + " from old ldb file! (%d [%s])\n", + ldb_dn_get_linearized(users_dn), + ret, ldb_errstring(ldb))); + } + ret = ldb_delete(ldb, domain_dn); + if (ret != LDB_SUCCESS) { + DEBUG(9, ("WARNING: Could not remove entry %s," + " from old ldb file! (%d [%s])\n", + ldb_dn_get_linearized(domain_dn), + ret, ldb_errstring(ldb))); + } + + ret = ldb_transaction_commit(sysdb->ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret)); + ret = EIO; + goto done; + } + ctx_trans = false; + + talloc_zfree(domain_dn); + talloc_zfree(groups_dn); + talloc_zfree(users_dn); + talloc_zfree(res); + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret)); + ret = EIO; + goto exit; + } + + ret = EOK; + +done: + if (ret != EOK) { + if (ctx_trans) { + ret = ldb_transaction_cancel(sysdb->ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret)); + } + } + ret = ldb_transaction_cancel(ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret)); + } + } + +exit: + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_4)); + + ret = ldb_transaction_start(sysdb->ldb); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + /* Make this database case-sensitive */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_4); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = EOK; + +done: + ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_4, ver); + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_5)); + + ret = ldb_transaction_start(sysdb->ldb); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + /* Add new index */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* Rebuild memberuid and memberoif attributes */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_add(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_5); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = EOK; + +done: + ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_5, ver); + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_6)); + + ret = ldb_transaction_start(sysdb->ldb); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + /* Add new indexes */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + /* Add Index for dataExpireTimestamp */ + ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* Add index to speed up ONELEVEL searches */ + ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "@IDXONE", "1"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_6); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = EOK; + +done: + ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_6, ver); + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_7)); + + ret = ldb_transaction_start(sysdb->ldb); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + /* Add new indexes */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + /* Case insensitive search for originalDN */ + ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* conversion done, upgrade version number */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "cn=sysdb"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_7); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = EOK; + +done: + ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_7, ver); + talloc_free(tmp_ctx); + return ret; +} -- cgit