From 28d9dcbeabdf919506fe59e9d1cbed84fbd6e649 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 3 Sep 2009 19:29:41 -0400 Subject: Split database in multiple files The special persistent local database retains the original name. All other backends now have their own cache-NAME.ldb file. --- server/db/sysdb.c | 793 ++++++++++++++++++++++++++++++++++++---------- server/db/sysdb.h | 18 +- server/db/sysdb_private.h | 28 +- 3 files changed, 663 insertions(+), 176 deletions(-) (limited to 'server/db') diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 90482b52a..d4f257977 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -3,7 +3,7 @@ System Database - Copyright (C) Simo Sorce 2008 + Copyright (C) Simo Sorce 2008 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 @@ -565,145 +565,26 @@ void sysdb_operation_done(struct sysdb_handle *handle) /* =Initialization======================================================== */ -static int sysdb_read_var(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *name, - const char *def_value, - char **target) +static int sysdb_get_db_file(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *base_path, char **_ldb_file) { - int ret; - char **values; - - ret = confdb_get_param(cdb, mem_ctx, - SYSDB_CONF_SECTION, - name, &values); - if (ret != EOK) - return ret; - - if (values[0]) - *target = values[0]; - else - *target = talloc_strdup(mem_ctx, def_value); + char *ldb_file; - return EOK; -} - -static int sysdb_get_db_path(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - char **db_path) -{ - TALLOC_CTX *tmp_ctx; - char *default_ldb_path; - char *path; - int ret; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) - return ENOMEM; - - default_ldb_path = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, SYSDB_FILE); - if (default_ldb_path == NULL) { - ret = ENOMEM; - goto done; + /* special case for the local domain */ + if (strcasecmp(domain->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); } - - sysdb_read_var(tmp_ctx, cdb, "ldbFile", - default_ldb_path, &path); - - *db_path = talloc_steal(mem_ctx, path); - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver); - -static int sysdb_check_init(struct sysdb_ctx *ctx) -{ - TALLOC_CTX *tmp_ctx; - const char *base_ldif; - struct ldb_ldif *ldif; - struct ldb_message_element *el; - struct ldb_result *res; - struct ldb_dn *verdn; - const char *version = NULL; - int ret; - - tmp_ctx = talloc_new(ctx); - if (!tmp_ctx) + if (!ldb_file) { return ENOMEM; - - verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb"); - if (!verdn) { - ret = EIO; - goto done; - } - - ret = ldb_search(ctx->ldb, tmp_ctx, &res, - verdn, LDB_SCOPE_BASE, - NULL, NULL); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - if (res->count > 1) { - ret = EIO; - 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 done; - } - version = talloc_strndup(tmp_ctx, - (char *)(el->values[0].data), - el->values[0].length); - if (!version) { - ret = ENOMEM; - goto done; - } - - 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) { - /* all fine, return */ - ret = EOK; - goto done; - } - } - - DEBUG(0,("Unknown DB version [%s], expected [%s], aborting!\n", - version?version:"not found", SYSDB_VERSION)); - ret = EINVAL; - goto done; - } - - /* cn=sysdb does not exists, means db is empty, populate */ - base_ldif = SYSDB_BASE_LDIF; - while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) { - ret = ldb_add(ctx->ldb, ldif->msg); - if (ret != LDB_SUCCESS) { - DEBUG(0, ("Failed to inizialiaze DB (%d,[%s]), aborting!\n", - ret, ldb_errstring(ctx->ldb))); - ret = EIO; - goto done; - } - ldb_ldif_read_free(ctx->ldb, ldif); } - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; + *_ldb_file = ldb_file; + return EOK; } /* serach all groups that have a memberUid attribute. @@ -837,7 +718,7 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver) ret = ENOMEM; goto done; } - ret = ldb_msg_add_string(msg, "version", "0.2"); + ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_2); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; @@ -866,62 +747,654 @@ done: return ret; } -int sysdb_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct confdb_ctx *cdb, - const char *alt_db_path, - struct sysdb_ctx **_ctx) +static int sysdb_upgrade_02(struct confdb_ctx *cdb, + struct tevent_context *ev, + struct sysdb_ctx *local, + struct sysdb_ctx_list *list) { + TALLOC_CTX *tmp_ctx; struct sysdb_ctx *ctx; - int ret; - - if (!ev) return EINVAL; + struct ldb_message_element *el; + struct ldb_message *msg; + struct ldb_result *res; + struct ldb_dn *basedn; + const char *version; + bool loc_trans = false; + bool ctx_trans = false; + int ret, i, j; - ctx = talloc_zero(mem_ctx, struct sysdb_ctx); - if (!ctx) { + tmp_ctx = talloc_new(list); + if (!tmp_ctx) { return ENOMEM; } - ctx->ev = ev; - if (!alt_db_path) { - ret = sysdb_get_db_path(ctx, cdb, &ctx->ldb_file); - if (ret != EOK) { - return ret; + /* first check local has the expected version for an upgrade */ + + basedn = ldb_dn_new(tmp_ctx, local->ldb, "cn=sysdb"); + if (!basedn) { + ret = EIO; + goto done; + } + + ret = ldb_search(local->ldb, tmp_ctx, &res, + basedn, LDB_SCOPE_BASE, + NULL, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + if (res->count != 1) { + ret = EIO; + goto done; + } + + 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 (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); + + 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(local->ldb); + + /* backup*/ + ret = backup_file(local->ldb_file, 0); + if (ret != EOK) { + return ret; + } + + /* reopen */ + local->ldb = ldb_init(local, ev); + if (!local->ldb) { + return EIO; + } + + ret = ldb_set_debug(local->ldb, ldb_debug_messages, NULL); + if (ret != LDB_SUCCESS) { + return EIO; + } + + ret = ldb_connect(local->ldb, local->ldb_file, 0, NULL); + if (ret != LDB_SUCCESS) { + return EIO; + } + + /* open a transaction */ + ret = ldb_transaction_start(local->ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret)); + return EIO; + } + loc_trans = true; + + /* == Upgrade contents == */ + + for (i = 0; i < list->num_dbs; i++) { + struct ldb_dn *domain_dn; + struct ldb_dn *users_dn; + struct ldb_dn *groups_dn; + + ctx = list->dbs[i]; + + /* skip local */ + if (list->dbs[i] == local) continue; + + ret = ldb_transaction_start(ctx->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, ctx->ldb, + SYSDB_DOM_BASE, ctx->domain->name); + if (!domain_dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_search(local->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, ctx->ldb, + SYSDB_TMPL_USER_BASE, ctx->domain->name); + if (!users_dn) { + ret = ENOMEM; + goto done; + } + groups_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb, + SYSDB_TMPL_GROUP_BASE, ctx->domain->name); + if (!groups_dn) { + ret = ENOMEM; + goto done; + } + + for (j = 0; j < res->count; j++) { + + msg = res->msgs[j]; + + /* 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; + } + + ret = ldb_add(ctx->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(ctx->ldb))); + } + + ret = ldb_delete(local->ldb, msg->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))); + } + } + + /* 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); + 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_delete(local->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_delete(local->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_transaction_commit(ctx->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, local->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_3); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(local->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + ret = ldb_transaction_commit(local->ldb); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret)); + ret = EIO; + goto done; + } + loc_trans = false; + + ret = EOK; + +done: + if (ret != EOK) { + if (ctx_trans) { + ret = ldb_transaction_cancel(ctx->ldb); + if (ret != LDB_SUCCESS) { + 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)); + } } - } else { - ctx->ldb_file = talloc_strdup(ctx, alt_db_path); } - if (ctx->ldb_file == NULL) { + talloc_free(tmp_ctx); + return ret; +} + + +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, + bool *need_02_upgrade) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct sysdb_ctx *ctx; + const char *base_ldif; + struct ldb_ldif *ldif; + struct ldb_message *msg; + struct ldb_message_element *el; + struct ldb_result *res; + struct ldb_dn *verdn; + const char *version = NULL; + int ret; + + ctx = talloc_zero(mem_ctx, struct sysdb_ctx); + if (!ctx) { return ENOMEM; } + ctx->ev = ev; + ctx->domain = domain; - DEBUG(3, ("DB Path is: %s\n", ctx->ldb_file)); + ret = sysdb_get_db_file(ctx, domain, db_path, &ctx->ldb_file); + if (ret != EOK) { + return ret; + } + DEBUG(5, ("DB File for %s: %s\n", domain->name, ctx->ldb_file)); ctx->ldb = ldb_init(ctx, ev); if (!ctx->ldb) { - talloc_free(ctx); return EIO; } ret = ldb_set_debug(ctx->ldb, ldb_debug_messages, NULL); if (ret != LDB_SUCCESS) { - talloc_free(ctx); return EIO; } ret = ldb_connect(ctx->ldb, ctx->ldb_file, 0, NULL); if (ret != LDB_SUCCESS) { - talloc_free(ctx); return EIO; } - ret = sysdb_check_init(ctx); + tmp_ctx = talloc_new(ctx); + if (!tmp_ctx) { + return ENOMEM; + } + + verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb"); + if (!verdn) { + ret = EIO; + goto done; + } + + ret = ldb_search(ctx->ldb, tmp_ctx, &res, + verdn, LDB_SCOPE_BASE, + NULL, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + if (res->count > 1) { + ret = EIO; + 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 done; + } + version = talloc_strndup(tmp_ctx, + (char *)(el->values[0].data), + el->values[0].length); + if (!version) { + ret = ENOMEM; + goto done; + } + + if (strcmp(version, SYSDB_VERSION) == 0) { + /* all fine, return */ + ret = EOK; + goto done; + } + + if (!allow_upgrade) { + DEBUG(0, ("Wrong DB version (got %s expected %s)\n", + version, SYSDB_VERSION)); + ret = EINVAL; + goto done; + } + + 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; + } + + } + + DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n", + version?version:"not found", SYSDB_VERSION, domain->name)); + ret = EINVAL; + goto done; + } + + /* cn=sysdb does not exists, means db is empty, populate */ + + base_ldif = SYSDB_BASE_LDIF; + while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) { + ret = ldb_add(ctx->ldb, ldif->msg); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!", + ret, ldb_errstring(ctx->ldb), domain->name)); + ret = EIO; + goto done; + } + ldb_ldif_read_free(ctx->ldb, ldif); + } + + /* == create base domain object == */ + + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, SYSDB_DOM_BASE, domain->name); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_fmt(msg, "cn", "%s", domain->name); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + /* do a synchronous add */ + ret = ldb_add(ctx->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!", + ret, ldb_errstring(ctx->ldb), domain->name)); + ret = EIO; + goto done; + } + talloc_free(msg); + + /* == create Users tree == */ + + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, + SYSDB_TMPL_USER_BASE, domain->name); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_fmt(msg, "cn", "Users"); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + /* do a synchronous add */ + ret = ldb_add(ctx->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!", + ret, ldb_errstring(ctx->ldb), domain->name)); + ret = EIO; + goto done; + } + talloc_free(msg); + + /* == create Groups tree == */ + + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, + SYSDB_TMPL_GROUP_BASE, domain->name); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_fmt(msg, "cn", "Groups"); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + /* do a synchronous add */ + ret = ldb_add(ctx->ldb, msg); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!", + ret, ldb_errstring(ctx->ldb), domain->name)); + ret = EIO; + goto done; + } + talloc_free(msg); + + ret = EOK; + +done: + if (ret == EOK) { + *_ctx = ctx; + } + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct confdb_ctx *cdb, + const char *alt_db_path, + bool allow_upgrade, + struct sysdb_ctx_list **_ctx_list) +{ + struct sysdb_ctx_list *ctx_list; + struct sss_domain_info *domains, *dom; + struct sysdb_ctx *ctx; + bool upgrade_02 = false; + int ret; + + if (!ev) return EINVAL; + + ctx_list = talloc_zero(mem_ctx, struct sysdb_ctx_list); + if (!ctx_list) { + return ENOMEM; + } + + if (alt_db_path) { + ctx_list->db_path = talloc_strdup(ctx_list, alt_db_path); + } else { + ctx_list->db_path = talloc_strdup(ctx_list, DB_PATH); + } + if (!ctx_list->db_path) { + talloc_zfree(ctx_list); + return ENOMEM; + } + + /* open a db for each backend */ + ret = confdb_get_domains(cdb, &domains); if (ret != EOK) { - talloc_free(ctx); + talloc_zfree(ctx_list); return ret; } - *_ctx = ctx; + for (dom = domains; dom; dom = dom->next) { + + ctx_list->dbs = talloc_realloc(ctx_list, ctx_list->dbs, + struct sysdb_ctx *, + ctx_list->num_dbs + 1); + if (!ctx_list->dbs) { + talloc_zfree(ctx_list); + return ENOMEM; + } + + ret = sysdb_domain_init_internal(ctx_list, ev, dom, + ctx_list->db_path, + allow_upgrade, + &ctx, &upgrade_02); + if (ret != EOK) { + talloc_zfree(ctx_list); + return ret; + } + + ctx_list->dbs[ctx_list->num_dbs] = ctx; + ctx_list->num_dbs++; + } + if (ctx_list->num_dbs == 0) { + /* what? .. */ + talloc_zfree(ctx_list); + 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 form db version %d failed!\n", + SYSDB_VERSION_0_2)); + DEBUG(0, ("You can find a backup of the database here: %s\n", + backup_file)); + talloc_zfree(ctx_list); + return ret; + } + } + + *_ctx_list = ctx_list; return EOK; } + +int sysdb_domain_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sss_domain_info *domain, + const char *db_path, + struct sysdb_ctx **_ctx) +{ + return sysdb_domain_init_internal(mem_ctx, ev, domain, + db_path, false, _ctx, NULL); +} + +int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list, + struct sss_domain_info *domain, + struct sysdb_ctx **ctx) +{ + int i; + + for (i = 0; i < ctx_list->num_dbs; i++) { + if (ctx_list->dbs[i]->domain == domain) { + *ctx = ctx_list->dbs[i]; + return EOK; + } + if (strcasecmp(ctx_list->dbs[i]->domain->name, domain->name) == 0) { + *ctx = ctx_list->dbs[i]; + return EOK; + } + } + /* definitely not found */ + return ENOENT; +} diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 3d75f507e..2d8b3eaea 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -26,7 +26,8 @@ #include #define SYSDB_CONF_SECTION "config/sysdb" -#define SYSDB_FILE "sssd.ldb" +#define CACHE_SYSDB_FILE "cache_%s.ldb" +#define LOCAL_SYSDB_FILE "sssd.ldb" #define SYSDB_BASE "cn=sysdb" #define SYSDB_DOM_BASE "cn=%s,cn=sysdb" @@ -137,6 +138,7 @@ #define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE struct confdb_ctx; +struct sysdb_ctx_list; struct sysdb_ctx; struct sysdb_handle; @@ -215,7 +217,19 @@ int sysdb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb, const char *alt_db_path, - struct sysdb_ctx **dbctx); + bool allow_upgrade, + struct sysdb_ctx_list **_ctx_list); +/* used to initialize only one domain database. + * Do NOT use if sysdb_init has already been called */ +int sysdb_domain_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sss_domain_info *domain, + const char *db_path, + struct sysdb_ctx **_ctx); + +int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list, + struct sss_domain_info *domain, + struct sysdb_ctx **_ctx); /* FIXME: REMOVE */ typedef void (*sysdb_callback_t)(void *, int, struct ldb_result *); diff --git a/server/db/sysdb_private.h b/server/db/sysdb_private.h index d8b66cd77..e380c8278 100644 --- a/server/db/sysdb_private.h +++ b/server/db/sysdb_private.h @@ -23,7 +23,9 @@ #ifndef __INT_SYS_DB_H__ #define __INT_SYS_DB_H__ -#define SYSDB_VERSION "0.2" +#define SYSDB_VERSION "0.3" +#define SYSDB_VERSION_0_3 "0.3" +#define SYSDB_VERSION_0_2 "0.2" #define SYSDB_VERSION_0_1 "0.1" #define SYSDB_BASE_LDIF \ @@ -50,20 +52,8 @@ "\n" \ "dn: cn=sysdb\n" \ "cn: sysdb\n" \ - "version: 0.2\n" \ + "version: " SYSDB_VERSION "\n" \ "description: base object\n" \ - "\n" \ - "dn: cn=LOCAL,cn=sysdb\n" \ - "cn: local\n" \ - "description: Local system data\n" \ - "\n" \ - "dn: cn=Users,cn=LOCAL,cn=sysdb\n" \ - "cn: users\n" \ - "description: Local POSIX users\n" \ - "\n" \ - "dn: cn=Groups,cn=LOCAL,cn=sysdb\n" \ - "cn: groups\n" \ - "description: Local POSIX groups\n" \ "\n" #include "db/sysdb.h" @@ -80,12 +70,22 @@ struct sysdb_handle { struct sysdb_ctx { struct tevent_context *ev; + + struct sss_domain_info *domain; + struct ldb_context *ldb; char *ldb_file; struct sysdb_handle *queue; }; +struct sysdb_ctx_list { + struct sysdb_ctx **dbs; + size_t num_dbs; + + char *db_path; +}; + /* An operation blocks the transaction queue as well, but does not * start a transaction, normally useful only for search type calls. * do *NOT* call within a transaction you'll deadlock sysdb. -- cgit