summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/db/sysdb.c366
1 files changed, 186 insertions, 180 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index c07a0744..88d60118 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -744,19 +744,26 @@ void sysdb_operation_done(struct sysdb_handle *handle)
/* =Initialization======================================================== */
+static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *domain,
+ const char *db_path,
+ bool allow_upgrade,
+ struct sysdb_ctx **_ctx);
+
static int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
+ const char *provider, const char *name,
const char *base_path, char **_ldb_file)
{
char *ldb_file;
/* special case for the local domain */
- if (strcasecmp(domain->provider, "local") == 0) {
+ if (strcasecmp(provider, "local") == 0) {
ldb_file = talloc_asprintf(mem_ctx, "%s/"LOCAL_SYSDB_FILE,
base_path);
} else {
ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE,
- base_path, domain->name);
+ base_path, name);
}
if (!ldb_file) {
return ENOMEM;
@@ -773,9 +780,10 @@ static int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
* finally stop indexing memberUid
* upgrade version to 0.2
*/
-static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
+static int sysdb_upgrade_01(TALLOC_CTX *mem_ctx,
+ struct ldb_context *ldb,
+ const char **ver)
{
- TALLOC_CTX *tmp_ctx;
struct ldb_message_element *el;
struct ldb_result *res;
struct ldb_dn *basedn;
@@ -788,17 +796,13 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
char *domain;
int ret, i, j;
- tmp_ctx = talloc_new(ctx);
- if (!tmp_ctx)
- return ENOMEM;
-
- basedn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");
+ basedn = ldb_dn_new(mem_ctx, ldb, "cn=sysdb");
if (!basedn) {
ret = EIO;
goto done;
}
- ret = ldb_search(ctx->ldb, tmp_ctx, &res,
+ ret = ldb_search(ldb, mem_ctx, &res,
basedn, LDB_SCOPE_SUBTREE,
attrs, filter);
if (ret != LDB_SUCCESS) {
@@ -806,7 +810,7 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
goto done;
}
- ret = ldb_transaction_start(ctx->ldb);
+ ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
ret = EIO;
goto done;
@@ -821,7 +825,7 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
}
/* create modification message */
- msg = ldb_msg_new(tmp_ctx);
+ msg = ldb_msg_new(mem_ctx);
if (!msg) {
ret = ENOMEM;
goto done;
@@ -842,15 +846,15 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
/* 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);
+ domain = talloc_strndup(mem_ctx, (const char *)val->data, val->length);
if (!domain) {
ret = ENOMEM;
goto done;
}
for (j = 0; j < el->num_values; j++) {
- mem_dn = sysdb_user_dn(ctx, tmp_ctx, domain,
- (const char *)el->values[j].data);
+ mem_dn = ldb_dn_new_fmt(mem_ctx, ldb, SYSDB_TMPL_USER,
+ (const char *)el->values[j].data, domain);
if (!mem_dn) {
ret = ENOMEM;
goto done;
@@ -871,7 +875,7 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
}
/* ok now we are ready to modify the entry */
- ret = ldb_modify(ctx->ldb, msg);
+ ret = ldb_modify(ldb, msg);
if (ret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(ret);
goto done;
@@ -881,12 +885,12 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
}
/* conversion done, upgrade version number */
- msg = ldb_msg_new(tmp_ctx);
+ msg = ldb_msg_new(mem_ctx);
if (!msg) {
ret = ENOMEM;
goto done;
}
- msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");
+ msg->dn = ldb_dn_new(mem_ctx, ldb, "cn=sysdb");
if (!msg->dn) {
ret = ENOMEM;
goto done;
@@ -903,93 +907,145 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
goto done;
}
- ret = ldb_modify(ctx->ldb, msg);
+ ret = ldb_modify(ldb, msg);
if (ret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(ret);
goto done;
}
- talloc_zfree(tmp_ctx);
ret = EOK;
done:
if (ret != EOK) {
- ret = ldb_transaction_cancel(ctx->ldb);
+ ldb_transaction_cancel(ldb);
} else {
- ret = ldb_transaction_commit(ctx->ldb);
- }
- if (ret != LDB_SUCCESS) {
- return EIO;
+ ret = ldb_transaction_commit(ldb);
+ if (ret != LDB_SUCCESS) {
+ return EIO;
+ }
+
+ *ver = SYSDB_VERSION_0_2;
}
- *ver = SYSDB_VERSION_0_2;
return ret;
}
-static int sysdb_upgrade_02(struct confdb_ctx *cdb,
- struct tevent_context *ev,
- struct sysdb_ctx *local,
- struct sysdb_ctx_list *list)
+static int sysdb_check_upgrade_02(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *domains,
+ const char *db_path)
{
- TALLOC_CTX *tmp_ctx;
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct ldb_context *ldb;
+ char *ldb_file;
struct sysdb_ctx *ctx;
+ struct sss_domain_info *dom;
struct ldb_message_element *el;
struct ldb_message *msg;
struct ldb_result *res;
- struct ldb_dn *basedn;
- const char *version;
- bool loc_trans = false;
+ struct ldb_dn *verdn;
+ const char *version = NULL;
+ bool do_02_upgrade = false;
bool ctx_trans = false;
- int ret, i, j;
+ int ret;
- tmp_ctx = talloc_new(list);
+ tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return ENOMEM;
}
- /* first check local has the expected version for an upgrade */
+ ret = sysdb_get_db_file(mem_ctx,
+ "local", "UPGRADE",
+ db_path, &ldb_file);
+ if (ret != EOK) {
+ goto exit;
+ }
- basedn = ldb_dn_new(tmp_ctx, local->ldb, "cn=sysdb");
- if (!basedn) {
+ ldb = ldb_init(tmp_ctx, ev);
+ if (!ldb) {
ret = EIO;
- goto done;
+ goto exit;
+ }
+
+ ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto exit;
+ }
+
+#ifdef SYSDB_TEST
+ ldb_set_modules_dir(ldb, "./.libs");
+#endif
+
+ ret = ldb_connect(ldb, ldb_file, 0, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto exit;
+ }
+
+ verdn = ldb_dn_new(tmp_ctx, ldb, "cn=sysdb");
+ if (!verdn) {
+ ret = EIO;
+ goto exit;
}
- ret = ldb_search(local->ldb, tmp_ctx, &res,
- basedn, LDB_SCOPE_BASE,
+ ret = ldb_search(ldb, tmp_ctx, &res,
+ verdn, LDB_SCOPE_BASE,
NULL, NULL);
if (ret != LDB_SUCCESS) {
ret = EIO;
- goto done;
+ goto exit;
}
- if (res->count != 1) {
+ if (res->count > 1) {
ret = EIO;
- goto done;
+ goto exit;
}
- el = ldb_msg_find_element(res->msgs[0], "version");
- if (el) {
- if (el->num_values != 1) {
- ret = EINVAL;
- goto done;
- }
- version = talloc_strndup(tmp_ctx,
- (char *)(el->values[0].data),
- el->values[0].length);
- if (!version) {
- ret = ENOMEM;
- goto done;
- }
+ 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(tmp_ctx, 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 (strcmp(version, SYSDB_VERSION_0_2) != 0) {
- DEBUG(0,("Wrong DB version [%s],"
- " expected [%s] for this upgrade!\n",
- version, SYSDB_VERSION));
- ret = EINVAL;
- goto done;
}
}
- talloc_zfree(res);
+
+ 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));
@@ -1001,49 +1057,60 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
/* == Backup and reopen ldb == */
/* close */
- talloc_zfree(local->ldb);
+ talloc_zfree(ldb);
/* backup*/
- ret = backup_file(local->ldb_file, 0);
+ ret = backup_file(ldb_file, 0);
if (ret != EOK) {
- return ret;
+ goto exit;
}
/* reopen */
- local->ldb = ldb_init(local, ev);
- if (!local->ldb) {
- return EIO;
+ ldb = ldb_init(tmp_ctx, ev);
+ if (!ldb) {
+ ret = EIO;
+ goto exit;
}
- ret = ldb_set_debug(local->ldb, ldb_debug_messages, NULL);
+ ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
if (ret != LDB_SUCCESS) {
- return EIO;
+ ret = EIO;
+ goto exit;
}
- ret = ldb_connect(local->ldb, local->ldb_file, 0, NULL);
+ ret = ldb_connect(ldb, ldb_file, 0, NULL);
if (ret != LDB_SUCCESS) {
- return EIO;
+ ret = EIO;
+ goto exit;
}
/* open a transaction */
- ret = ldb_transaction_start(local->ldb);
+ ret = ldb_transaction_start(ldb);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
- return EIO;
+ ret = EIO;
+ goto exit;
}
- loc_trans = true;
/* == Upgrade contents == */
- for (i = 0; i < list->num_dbs; i++) {
+ for (dom = domains; dom; dom = dom->next) {
struct ldb_dn *domain_dn;
struct ldb_dn *users_dn;
struct ldb_dn *groups_dn;
-
- ctx = list->dbs[i];
+ int i;
/* skip local */
- if (list->dbs[i] == local) continue;
+ if (strcasecmp(dom->provider, "local") == 0) {
+ continue;
+ }
+
+ /* create new dom db */
+ ret = sysdb_domain_init_internal(tmp_ctx, ev, dom,
+ db_path, false, &ctx);
+ if (ret != EOK) {
+ goto done;
+ }
ret = ldb_transaction_start(ctx->ldb);
if (ret != LDB_SUCCESS) {
@@ -1064,7 +1131,7 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
goto done;
}
- ret = ldb_search(local->ldb, tmp_ctx, &res,
+ ret = ldb_search(ldb, tmp_ctx, &res,
domain_dn, LDB_SCOPE_SUBTREE,
NULL, NULL);
if (ret != LDB_SUCCESS) {
@@ -1085,11 +1152,11 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
goto done;
}
- for (j = 0; j < res->count; j++) {
+ for (i = 0; i < res->count; i++) {
struct ldb_dn *orig_dn;
- msg = res->msgs[j];
+ msg = res->msgs[i];
/* skip pre-created congtainers */
if ((ldb_dn_compare(msg->dn, domain_dn) == 0) ||
@@ -1117,38 +1184,38 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
ret, ldb_errstring(ctx->ldb)));
}
- ret = ldb_delete(local->ldb, orig_dn);
+ 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(msg->dn),
- ret, ldb_errstring(local->ldb)));
+ 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(local->ldb, groups_dn);
+ 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(msg->dn),
- ret, ldb_errstring(local->ldb)));
+ ret, ldb_errstring(ldb)));
}
- ret = ldb_delete(local->ldb, users_dn);
+ 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(msg->dn),
- ret, ldb_errstring(local->ldb)));
+ ret, ldb_errstring(ldb)));
}
- ret = ldb_delete(local->ldb, domain_dn);
+ 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(msg->dn),
- ret, ldb_errstring(local->ldb)));
+ ret, ldb_errstring(ldb)));
}
ret = ldb_transaction_commit(ctx->ldb);
@@ -1171,7 +1238,7 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
ret = ENOMEM;
goto done;
}
- msg->dn = ldb_dn_new(tmp_ctx, local->ldb, "cn=sysdb");
+ msg->dn = ldb_dn_new(tmp_ctx, ldb, "cn=sysdb");
if (!msg->dn) {
ret = ENOMEM;
goto done;
@@ -1188,19 +1255,18 @@ static int sysdb_upgrade_02(struct confdb_ctx *cdb,
goto done;
}
- ret = ldb_modify(local->ldb, msg);
+ ret = ldb_modify(ldb, msg);
if (ret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(ret);
goto done;
}
- ret = ldb_transaction_commit(local->ldb);
+ ret = ldb_transaction_commit(ldb);
if (ret != LDB_SUCCESS) {
DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
ret = EIO;
- goto done;
+ goto exit;
}
- loc_trans = false;
ret = EOK;
@@ -1212,13 +1278,13 @@ done:
DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
}
}
- if (loc_trans) {
- ret = ldb_transaction_cancel(local->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;
}
@@ -1431,8 +1497,7 @@ static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *db_path,
bool allow_upgrade,
- struct sysdb_ctx **_ctx,
- bool *need_02_upgrade)
+ struct sysdb_ctx **_ctx)
{
TALLOC_CTX *tmp_ctx = NULL;
struct sysdb_ctx *ctx;
@@ -1458,7 +1523,9 @@ static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
ctx->mpg = true;
}
- ret = sysdb_get_db_file(ctx, domain, db_path, &ctx->ldb_file);
+ ret = sysdb_get_db_file(ctx, domain->provider,
+ domain->name, db_path,
+ &ctx->ldb_file);
if (ret != EOK) {
return ret;
}
@@ -1537,37 +1604,6 @@ static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
DEBUG(4, ("Upgrading DB [%s] from version: %s\n",
domain->name, version));
- if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
- /* convert database */
- ret = sysdb_upgrade_01(ctx, &version);
- if (ret != EOK) goto done;
- }
-
- if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
- /* if this is not local we have a big problem */
- if (strcasecmp(domain->provider, "local") != 0) {
- DEBUG(0, ("Fatal: providers other than 'local'"
- " shouldn't present v0.2, db corrupted?\n"));
- ret = EFAULT;
- goto done;
- }
-
- /* need to convert database to split files */
- /* this need to be done later when all domains are set up */
- if (need_02_upgrade) {
- *need_02_upgrade = true;
- } else {
- DEBUG(0, ("DB file seem to need an upgrade,"
- " but upgrade flag is not provided,"
- " db corrupted?\n"));
- ret = EFAULT;
- goto done;
- }
-
- ret = EOK;
- goto done;
- }
-
if (strcmp(version, SYSDB_VERSION_0_3) == 0) {
ret = sysdb_upgrade_03(ctx, &version);
if (ret != EOK) {
@@ -1704,8 +1740,6 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
struct sysdb_ctx_list *ctx_list;
struct sss_domain_info *domains, *dom;
struct sysdb_ctx *ctx;
- bool upgrade_02 = false;
- const char *version = NULL;
int ret;
if (!ev) return EINVAL;
@@ -1732,6 +1766,16 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
return ret;
}
+ if (allow_upgrade) {
+ /* check if we have an old sssd.ldb to upgrade */
+ ret = sysdb_check_upgrade_02(ctx_list, ev, domains,
+ ctx_list->db_path);
+ if (ret != EOK) {
+ talloc_zfree(ctx_list);
+ return ret;
+ }
+ }
+
for (dom = domains; dom; dom = dom->next) {
ctx_list->dbs = talloc_realloc(ctx_list, ctx_list->dbs,
@@ -1744,8 +1788,7 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
ret = sysdb_domain_init_internal(ctx_list, ev, dom,
ctx_list->db_path,
- allow_upgrade,
- &ctx, &upgrade_02);
+ allow_upgrade, &ctx);
if (ret != EOK) {
talloc_zfree(ctx_list);
return ret;
@@ -1760,43 +1803,6 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
return ENOENT;
}
- if (upgrade_02) {
- ret = confdb_get_domain(cdb, "local", &dom);
- if (ret != EOK) {
- talloc_zfree(ctx_list);
- return ret;
- }
- ret = sysdb_get_ctx_from_list(ctx_list, dom, &ctx);
- if (ret != EOK) {
- talloc_zfree(ctx_list);
- return ret;
- }
-
- ret = sysdb_upgrade_02(cdb, ev, ctx, ctx_list);
- if (ret != EOK) {
- DEBUG(0, ("FATAL: Upgrade from db version %s failed!\n",
- SYSDB_VERSION_0_2));
- DEBUG(0, ("You may find a backup of the database here: %s\n",
- DB_PATH));
- talloc_zfree(ctx_list);
- return ret;
- }
- ret = sysdb_upgrade_03(ctx, &version);
- if (ret != EOK) {
- DEBUG(0, ("FATAL: Upgrade from db version %s failed!\n",
- SYSDB_VERSION_0_3));
- talloc_zfree(ctx_list);
- return ret;
- };
- ret = sysdb_upgrade_04(ctx, &version);
- if (ret != EOK) {
- DEBUG(0, ("FATAL: Upgrade from db version %s failed!\n",
- SYSDB_VERSION_0_4));
- talloc_zfree(ctx_list);
- return ret;
- };
- }
-
*_ctx_list = ctx_list;
return EOK;
@@ -1809,7 +1815,7 @@ int sysdb_domain_init(TALLOC_CTX *mem_ctx,
struct sysdb_ctx **_ctx)
{
return sysdb_domain_init_internal(mem_ctx, ev, domain,
- db_path, false, _ctx, NULL);
+ db_path, false, _ctx);
}
int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list,