summaryrefslogtreecommitdiffstats
path: root/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/db')
-rw-r--r--src/db/sysdb_init.c134
-rw-r--r--src/db/sysdb_private.h24
2 files changed, 158 insertions, 0 deletions
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index cfe6e86fb..b2b845317 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -297,6 +297,17 @@ static errno_t sysdb_cache_create_empty(struct ldb_context *ldb,
return EOK;
}
+static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ struct ldb_context *ldb,
+ struct sss_domain_info *domain,
+ const char *cur_version,
+ const char **_new_version)
+{
+ /* Currently the sysdb cache only has one version */
+ return EFAULT;
+}
+
static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
struct ldb_context *ldb,
@@ -609,6 +620,114 @@ done:
return ret;
}
+static int sysdb_timestamp_cache_connect(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ bool allow_upgrade)
+{
+ errno_t ret;
+ const char *version;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_context *ldb;
+
+ if (sysdb->ldb_ts_file == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "No timestamp cache for %s\n", domain->name);
+ return EOK;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_cache_connect(tmp_ctx, domain,
+ sysdb->ldb_ts_file, LDB_FLG_NOSYNC,
+ SYSDB_TS_VERSION, SYSDB_TS_BASE_LDIF,
+ &ldb, &version);
+ switch (ret) {
+ case ERR_SYSDB_VERSION_TOO_OLD:
+ if (allow_upgrade == false) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "DB version too old [%s], expected [%s] for domain %s!\n",
+ version, SYSDB_VERSION, domain->name);
+ break;
+ }
+
+ ret = sysdb_ts_cache_upgrade(tmp_ctx, sysdb, ldb, domain, version,
+ &version);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not upgrade the timestamp ldb file (%d) (%s)\n",
+ ret, sss_strerror(ret));
+ break;
+ }
+
+ /* The version should now match SYSDB_VERSION.
+ * If not, it means we didn't match any of the
+ * known older versions. The DB might be
+ * corrupt or generated by a newer version of
+ * SSSD.
+ */
+ ret = sysdb_version_check(SYSDB_TS_VERSION, version);
+ if (ret == EOK) {
+ /* The cache has been upgraded.
+ * We need to reopen the LDB to ensure that
+ * any changes made above take effect.
+ */
+ ret = sysdb_ldb_reconnect(tmp_ctx,
+ sysdb->ldb_ts_file,
+ LDB_FLG_NOSYNC,
+ &ldb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not reopen the timestamp ldb file (%d) (%s)\n",
+ ret, sss_strerror(ret));
+ }
+ }
+ break;
+ case ERR_SYSDB_VERSION_TOO_NEW:
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "DB version too new [%s], expected [%s] for domain %s!\n",
+ version, SYSDB_TS_VERSION, domain->name);
+ break;
+ default:
+ break;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "The timestamps cache could not be opened. "
+ "Throwing away the database and opening a new one\n");
+
+ ret = unlink(sysdb->ldb_ts_file);
+ if (ret != EOK && errno != ENOENT) {
+ ret = errno;
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not delete the timestamp ldb file (%d) (%s)\n",
+ ret, sss_strerror(ret));
+ return ret;
+ }
+
+ /* Now the connect must succeed because the previous cache doesn't
+ * exist anymore.
+ */
+ ret = sysdb_cache_connect(tmp_ctx, domain,
+ sysdb->ldb_ts_file, LDB_FLG_NOSYNC,
+ SYSDB_TS_VERSION, SYSDB_TS_BASE_LDIF,
+ &ldb, &version);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not delete the timestamp ldb file (%d) (%s)\n",
+ ret, sss_strerror(ret));
+ }
+ }
+
+ if (ret == EOK) {
+ sysdb->ldb_ts = talloc_steal(sysdb, ldb);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *db_path,
@@ -640,6 +759,21 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
"DB File for %s: %s\n", domain->name, sysdb->ldb_file);
ret = sysdb_domain_cache_connect(sysdb, domain, allow_upgrade);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Could not open the sysdb cache [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_timestamp_cache_connect(sysdb, domain, allow_upgrade);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Could not open the timestamp cache [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
done:
if (ret == EOK) {
*_ctx = talloc_steal(mem_ctx, sysdb);
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index a78a9be2f..5f7a1ed6f 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -84,11 +84,35 @@
"cn: ranges\n" \
"\n"
+/* The timestamp cache has its own versioning */
+#define SYSDB_TS_VERSION_0_1 "0.1"
+
+#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_1
+
+#define SYSDB_TS_BASE_LDIF \
+ "dn: @ATTRIBUTES\n" \
+ "dn: CASE_INSENSITIVE\n" \
+ "\n" \
+ "dn: @INDEXLIST\n" \
+ "@IDXATTR: lastUpdate\n" \
+ "@IDXATTR: dataExpireTimestamp\n" \
+ "@IDXONE: 1\n" \
+ "\n" \
+ "dn: cn=sysdb\n" \
+ "cn: sysdb\n" \
+ "version: " SYSDB_TS_VERSION "\n" \
+ "description: base object\n" \
+ "\n" \
+
#include "db/sysdb.h"
struct sysdb_ctx {
struct ldb_context *ldb;
char *ldb_file;
+
+ struct ldb_context *ldb_ts;
+ char *ldb_ts_file;
+
int transaction_nesting;
};