From 224a0dfad69c2e056f19e2b4865d592f495fb944 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 13 Feb 2009 14:17:24 -0500 Subject: Always pass teh database path explicitly, so that test cases can use throw away databases Check version and init main db if empty --- server/confdb/confdb.c | 15 +--- server/confdb/confdb.h | 5 +- server/db/sysdb.c | 146 +++++++++++++++++++++++++++++------- server/db/sysdb.h | 7 +- server/db/sysdb_internal.h | 68 +++++++++++++++++ server/examples/db.ldif | 1 + server/nss/nsssrv.c | 2 +- server/providers/data_provider_be.c | 2 +- server/tests/sysdb-tests.c | 14 +++- server/util/server.c | 10 ++- 10 files changed, 223 insertions(+), 47 deletions(-) create mode 100644 server/db/sysdb_internal.h (limited to 'server') diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c index 945ac2b8..28f25176 100644 --- a/server/confdb/confdb.c +++ b/server/confdb/confdb.c @@ -26,8 +26,8 @@ #include "ldb.h" #include "ldb_errors.h" #include "util/util.h" +#include "confdb/confdb.h" #define CONFDB_VERSION "0.1" -#define CONFDB_FILE "config.ldb" #define CONFDB_DOMAIN_BASEDN "cn=domains,cn=config" #define CONFDB_DOMAIN_ATTR "cn" @@ -530,10 +530,10 @@ done: int confdb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct confdb_ctx **cdb_ctx) + struct confdb_ctx **cdb_ctx, + char *confdb_location) { struct confdb_ctx *cdb; - char *confdb_location; int ret; cdb = talloc_zero(mem_ctx, struct confdb_ctx); @@ -546,21 +546,12 @@ int confdb_init(TALLOC_CTX *mem_ctx, return EIO; } - confdb_location = talloc_asprintf(cdb,"%s/%s", DB_PATH,CONFDB_FILE); - if (confdb_location == NULL) { - talloc_free(cdb); - return ENOMEM; - } - DEBUG(3, ("CONFDB: %s\n",confdb_location)); - ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL); if (ret != LDB_SUCCESS) { talloc_free(cdb); return EIO; } - talloc_free(confdb_location); - ret = confdb_test(cdb); if (ret == ENOENT) { ret = confdb_init_db(cdb); diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h index 62ab45c7..e6dd0d47 100644 --- a/server/confdb/confdb.h +++ b/server/confdb/confdb.h @@ -19,6 +19,8 @@ along with this program. If not, see . */ +#define CONFDB_FILE "config.ldb" + struct confdb_ctx; int confdb_add_param(struct confdb_ctx *cdb, @@ -44,7 +46,8 @@ int confdb_get_int(struct confdb_ctx *cdb, TALLOC_CTX *ctx, int confdb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct confdb_ctx **cdb_ctx); + struct confdb_ctx **cdb_ctx, + char *confdb_location); int confdb_get_domains(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 86c4fa8e..db047bc3 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -21,6 +21,7 @@ #include "util/util.h" #include "db/sysdb.h" +#include "db/sysdb_internal.h" #include "confdb/confdb.h" #include @@ -667,62 +668,52 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx, return LDB_SUCCESS; } -static int sysdb_read_var(TALLOC_CTX *tmp_ctx, +static int sysdb_read_var(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, - struct sysdb_ctx *ctx, const char *name, const char *def_value, - const char **target) + char **target) { int ret; - char *t; char **values; - ret = confdb_get_param(cdb, tmp_ctx, + ret = confdb_get_param(cdb, mem_ctx, SYSDB_CONF_SECTION, name, &values); if (ret != EOK) return ret; if (values[0]) - t = talloc_steal(ctx, values[0]); + *target = values[0]; else - t = talloc_strdup(ctx, def_value); + *target = talloc_strdup(mem_ctx, def_value); - *target = t; return EOK; } -static int sysdb_read_conf(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - struct sysdb_ctx **dbctx) +static int sysdb_get_db_path(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + char **db_path) { - struct sysdb_ctx *ctx; TALLOC_CTX *tmp_ctx; char *default_ldb_path; + char *path; int ret; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; - ctx = talloc(mem_ctx, struct sysdb_ctx); - if (!ctx) { - ret = ENOMEM; - goto done; - } - default_ldb_path = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, SYSDB_FILE); if (default_ldb_path == NULL) { ret = ENOMEM; goto done; } - sysdb_read_var(tmp_ctx, cdb, ctx, "ldbFile", - default_ldb_path, &ctx->ldb_file); - DEBUG(3, ("NSS LDB Cache Path: %s\n", ctx->ldb_file)); + sysdb_read_var(tmp_ctx, cdb, "ldbFile", + default_ldb_path, &path); - *dbctx = ctx; + *db_path = talloc_steal(mem_ctx, path); ret = EOK; done: @@ -1598,19 +1589,116 @@ done: return ret; } +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; + char *version = NULL; + int ret; + + 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; + } + } + + 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; +} + int sysdb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, struct confdb_ctx *cdb, + const char *alt_db_path, struct sysdb_ctx **dbctx) { struct sysdb_ctx *ctx; int ret; - ret = sysdb_read_conf(mem_ctx, cdb, &ctx); - if (ret != EOK) - return ret; + ctx = talloc_zero(mem_ctx, struct sysdb_ctx); + if (!ctx) { + return ENOMEM; + } + + if (!alt_db_path) { + ret = sysdb_get_db_path(ctx, cdb, &ctx->ldb_file); + if (ret != EOK) { + return ret; + } + } else { + ctx->ldb_file = talloc_strdup(ctx, alt_db_path); + } + if (ctx->ldb_file == NULL) { + return ENOMEM; + } - ctx->ldb = ldb_init(mem_ctx, ev); + DEBUG(3, ("DB Path is: %s\n", ctx->ldb_file)); + + ctx->ldb = ldb_init(ctx, ev); if (!ctx->ldb) { talloc_free(ctx); return EIO; @@ -1622,6 +1710,12 @@ int sysdb_init(TALLOC_CTX *mem_ctx, return EIO; } + ret = sysdb_check_init(ctx); + if (ret != EOK) { + talloc_free(ctx); + return ret; + } + *dbctx = ctx; return EOK; diff --git a/server/db/sysdb.h b/server/db/sysdb.h index d571f676..7b285721 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -1,7 +1,7 @@ /* SSSD - System Databse Header + System Database Header Copyright (C) Simo Sorce 2008 @@ -75,7 +75,7 @@ struct sysdb_ctx { struct ldb_context *ldb; - const char *ldb_file; + char *ldb_file; }; struct confdb_ctx; @@ -85,7 +85,8 @@ typedef void (*sysdb_callback_t)(void *, int, struct ldb_result *); int sysdb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, struct confdb_ctx *cdb, - struct sysdb_ctx **nlctx); + const char *alt_db_path, + struct sysdb_ctx **dbctx); int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct event_context *ev, diff --git a/server/db/sysdb_internal.h b/server/db/sysdb_internal.h new file mode 100644 index 00000000..5757e847 --- /dev/null +++ b/server/db/sysdb_internal.h @@ -0,0 +1,68 @@ + +/* + SSSD + + Private System Database Header + + 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 + 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 . +*/ + +#ifndef __INT_SYS_DB_H__ +#define __INT_SYS_DB_H__ + +#define SYSDB_VERSION "0.1" + +#define SYSDB_BASE_LDIF \ + "dn: @ATTRIBUTES\n" \ + "userPrincipalName: CASE_INSENSITIVE\n" \ + "cn: CASE_INSENSITIVE\n" \ + "dc: CASE_INSENSITIVE\n" \ + "dn: CASE_INSENSITIVE\n" \ + "name: CASE_INSENSITIVE\n" \ + "objectclass: CASE_INSENSITIVE\n" \ + "\n" \ + "dn: @INDEXLIST\n" \ + "@IDXATTR: cn\n" \ + "@IDXATTR: objectclass\n" \ + "@IDXATTR: member\n" \ + "@IDXATTR: memberof\n" \ + "@IDXATTR: uid\n" \ + "@IDXATTR: uidNumber\n" \ + "@IDXATTR: gidNumber\n" \ + "@IDXATTR: lastUpdate\n" \ + "\n" \ + "dn: @MODULES\n" \ + "@LIST: asq,memberof\n" \ + "\n" \ + "dn: cn=sysdb\n" \ + "cn: sysdb\n" \ + "version: 0.1\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" + +#endif /* __INT_SYS_DB_H__ */ diff --git a/server/examples/db.ldif b/server/examples/db.ldif index e7d8897f..9f6a89c0 100644 --- a/server/examples/db.ldif +++ b/server/examples/db.ldif @@ -21,6 +21,7 @@ dn: @MODULES dn: cn=sysdb cn: sysdb +version: 0.1 description: base object dn: cn=local,cn=sysdb diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c index 1c42c3c5..fa43f60f 100644 --- a/server/nss/nsssrv.c +++ b/server/nss/nsssrv.c @@ -467,7 +467,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx, return ret; } - ret = sysdb_init(nctx, ev, cdb, &nctx->sysdb); + ret = sysdb_init(nctx, ev, cdb, NULL, &nctx->sysdb); if (ret != EOK) { DEBUG(0, ("fatal error initializing nss_ctx\n")); return ret; diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c index 3f81e719..ad551c23 100644 --- a/server/providers/data_provider_be.c +++ b/server/providers/data_provider_be.c @@ -436,7 +436,7 @@ int be_process_init(TALLOC_CTX *mem_ctx, return ENOMEM; } - ret = sysdb_init(ctx, ev, cdb, &ctx->sysdb); + ret = sysdb_init(ctx, ev, cdb, NULL, &ctx->sysdb); if (ret != EOK) { DEBUG(0, ("fatal error opening cache database\n")); return ret; diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index bb222fae..a24ae181 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -39,6 +39,7 @@ struct sysdb_test_ctx { static int setup_sysdb_tests(struct sysdb_test_ctx **ctx) { struct sysdb_test_ctx *test_ctx; + char *conf_db; int ret; test_ctx = talloc_zero(NULL, struct sysdb_test_ctx); @@ -57,15 +58,24 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx) return EIO; } + conf_db = talloc_asprintf(test_ctx, "tests_conf.ldb"); + if (conf_db == NULL) { + fail("Out of memory, aborting!"); + talloc_free(test_ctx); + return ENOMEM; + } + DEBUG(3, ("CONFDB: %s\n", conf_db)); + /* Connect to the conf db */ - ret = confdb_init(test_ctx, test_ctx->ev, &test_ctx->confdb); + ret = confdb_init(test_ctx, test_ctx->ev, &test_ctx->confdb, conf_db); if(ret != EOK) { fail("Could not initialize connection to the confdb"); talloc_free(test_ctx); return ret; } - ret = sysdb_init(test_ctx, test_ctx->ev, test_ctx->confdb, &test_ctx->sysdb); + ret = sysdb_init(test_ctx, test_ctx->ev, test_ctx->confdb, "tests.ldb", + &test_ctx->sysdb); if(ret != EOK) { fail("Could not initialize connection to the sysdb"); talloc_free(test_ctx); diff --git a/server/util/server.c b/server/util/server.c index be3c13cc..35e72fa0 100644 --- a/server/util/server.c +++ b/server/util/server.c @@ -240,6 +240,7 @@ int server_setup(const char *name, int flags, struct event_context *event_ctx; struct main_context *ctx; uint16_t stdin_event_flags; + char *conf_db; int ret = EOK; debug_prg_name = strdup(name); @@ -284,7 +285,14 @@ int server_setup(const char *name, int flags, ctx->event_ctx = event_ctx; - ret = confdb_init(ctx, event_ctx, &ctx->confdb_ctx); + conf_db = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); + if (conf_db == NULL) { + DEBUG(0,("Out of memory, aborting!\n")); + return ENOMEM; + } + DEBUG(3, ("CONFDB: %s\n", conf_db)); + + ret = confdb_init(ctx, event_ctx, &ctx->confdb_ctx, conf_db); if (ret != EOK) { DEBUG(0,("The confdb initialization failed\n")); return ret; -- cgit