summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db/sysdb.c36
-rw-r--r--src/db/sysdb.h30
-rw-r--r--src/monitor/monitor.c1
-rw-r--r--src/responder/common/responder_common.c1
-rw-r--r--src/tools/sss_cache.c2
-rw-r--r--src/tools/sss_seed.c1
-rw-r--r--src/tools/tools_util.c1
7 files changed, 70 insertions, 2 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 9685163b3..dda288f76 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -947,6 +947,38 @@ errno_t sysdb_add_to_domain(struct sss_domain_info *domain,
return EOK;
}
+/* Compare versions of sysdb, returns ERRNO accordingly */
+static errno_t
+sysdb_version_check(const char *expected,
+ const char *received)
+{
+ int ret;
+ unsigned int exp_major, exp_minor, recv_major, recv_minor;
+
+ ret = sscanf(expected, "%u.%u", &exp_major, &exp_minor);
+ if (ret != 2) {
+ return EINVAL;
+ }
+ ret = sscanf(received, "%u.%u", &recv_major, &recv_minor);
+ if (ret != 2) {
+ return EINVAL;
+ }
+
+ if (recv_major > exp_major) {
+ return EUCLEAN;
+ } else if (recv_major < exp_major) {
+ return EMEDIUMTYPE;
+ }
+
+ if (recv_minor > exp_minor) {
+ return EUCLEAN;
+ } else if (recv_minor < exp_minor) {
+ return EMEDIUMTYPE;
+ }
+
+ return EOK;
+}
+
int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *db_path,
@@ -1037,7 +1069,7 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
if (!allow_upgrade) {
DEBUG(0, ("Wrong DB version (got %s expected %s)\n",
version, SYSDB_VERSION));
- ret = EINVAL;
+ ret = sysdb_version_check(SYSDB_VERSION, version);
goto done;
}
@@ -1136,7 +1168,7 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
version?version:"not found", SYSDB_VERSION, domain->name));
- ret = EINVAL;
+ ret = sysdb_version_check(SYSDB_VERSION, version);
goto done;
}
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 39e0f9f52..c60f7e951 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -214,6 +214,36 @@
#define SYSDB_MOD_DEL LDB_FLAG_MOD_DELETE
#define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE
+/* sysdb version check macros */
+#define SYSDB_VERSION_ERROR_HINT \
+ ERROR("Removing cache files in "DB_PATH" should fix the issue, " \
+ "but note that removing cache files will also remove all of your " \
+ "cached credentials.\n")
+
+#define SYSDB_VERSION_LOWER_ERROR(ret) do { \
+ if (ret == EUCLEAN) { \
+ ERROR("Lower version of database is expected!\n"); \
+ SYSDB_VERSION_ERROR_HINT; \
+ } \
+} while(0)
+
+#define SYSDB_VERSION_HIGHER_ERROR(ret) do { \
+ if (ret == EMEDIUMTYPE) { \
+ ERROR("Higher version of database is expected!\n"); \
+ ERROR("In order to upgrade the database, you must run SSSD.\n"); \
+ SYSDB_VERSION_ERROR_HINT; \
+ } \
+} while(0)
+
+/* use this in daemons */
+#define SYSDB_VERSION_ERROR_DAEMON(ret) \
+ SYSDB_VERSION_LOWER_ERROR(ret)
+
+/* use this in tools */
+#define SYSDB_VERSION_ERROR(ret) \
+ SYSDB_VERSION_LOWER_ERROR(ret); \
+ SYSDB_VERSION_HIGHER_ERROR(ret)
+
struct confdb_ctx;
struct sysdb_ctx;
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 1fbbcb9ce..7f7bbd0fa 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2185,6 +2185,7 @@ int monitor_process_init(struct mt_ctx *ctx,
}
ret = sysdb_init(tmp_ctx, ctx->cdb, NULL, true, &db_list);
if (ret != EOK) {
+ SYSDB_VERSION_ERROR_DAEMON(ret);
return ret;
}
talloc_zfree(tmp_ctx);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index d9f73fe26..50705a3f2 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -839,6 +839,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
ret = sysdb_init(rctx, cdb, NULL, false, &rctx->db_list);
if (ret != EOK) {
+ SYSDB_VERSION_ERROR_DAEMON(ret);
DEBUG(0, ("fatal error initializing resp_ctx\n"));
return ret;
}
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index 267b8ac45..dfc58a7cd 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -339,6 +339,7 @@ errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain)
ret = sysdb_init_domain_and_sysdb(ctx, ctx->confdb, domain, DB_PATH,
&ctx->domains, &db_ctx);
if (ret != EOK) {
+ SYSDB_VERSION_ERROR(ret);
DEBUG(1, ("Could not initialize connection to the sysdb\n"));
goto fail;
}
@@ -350,6 +351,7 @@ errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain)
}
} else {
ret = sysdb_init(ctx, ctx->confdb, NULL, false, &ctx->sysdb_list);
+ SYSDB_VERSION_ERROR(ret);
if (ret != EOK) {
DEBUG(1, ("Could not initialize connection to the sysdb\n"));
goto fail;
diff --git a/src/tools/sss_seed.c b/src/tools/sss_seed.c
index 18d0b9d08..8eaf95936 100644
--- a/src/tools/sss_seed.c
+++ b/src/tools/sss_seed.c
@@ -631,6 +631,7 @@ static int seed_init_db(TALLOC_CTX *mem_ctx,
ret = sysdb_init_domain_and_sysdb(tmp_ctx, confdb, domain_name,
DB_PATH, &domain, &sysdb);
if (ret != EOK) {
+ SYSDB_VERSION_ERROR(ret);
DEBUG(SSSDBG_CRIT_FAILURE,
("Could not initialize connection to domain '%s' in sysdb.%s\n",
domain_name, ret == ENOENT ? " Domain not found." : ""));
diff --git a/src/tools/tools_util.c b/src/tools/tools_util.c
index 99b79f171..73e94136c 100644
--- a/src/tools/tools_util.c
+++ b/src/tools/tools_util.c
@@ -57,6 +57,7 @@ static int setup_db(struct tools_ctx *ctx)
ret = sysdb_init_domain_and_sysdb(ctx, ctx->confdb, "local", DB_PATH,
&ctx->local, &ctx->sysdb);
if (ret != EOK) {
+ SYSDB_VERSION_ERROR(ret);
DEBUG(1, ("Could not initialize connection to the sysdb\n"));
return ret;
}