summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2016-04-21 13:48:04 +0200
committerJakub Hrozek <jhrozek@redhat.com>2016-06-23 13:40:11 +0200
commitf983b400bf4f6fb14a2174d6f58071e06e9ec832 (patch)
tree8f6a24d7408a399480f3a7596451a1daa6c31666 /src
parentf21b3cce14055e77af8ccb98dd8e0fa1ec1f7944 (diff)
downloadsssd-f983b400bf4f6fb14a2174d6f58071e06e9ec832.tar.gz
sssd-f983b400bf4f6fb14a2174d6f58071e06e9ec832.tar.xz
sssd-f983b400bf4f6fb14a2174d6f58071e06e9ec832.zip
SYSDB: Open a timestamps cache for caching domains
For all domain types, except the local domain, open a connection to a new ldb file located at /var/lib/sss/db names timestamps_$domain.ldb. Constructs the ldb file path manually in sysdb_check_upgrade_02() but that should be acceptable because nobody should be running such an old cache these days anyway. Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/db/sysdb.h3
-rw-r--r--src/db/sysdb_init.c81
-rw-r--r--src/db/sysdb_private.h7
-rw-r--r--src/db/sysdb_upgrade.c8
-rw-r--r--src/responder/common/responder_common.c3
-rw-r--r--src/tests/common_dom.c34
6 files changed, 114 insertions, 22 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 42f845033..e343de20c 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -28,6 +28,7 @@
#include <tevent.h>
#define CACHE_SYSDB_FILE "cache_%s.ldb"
+#define CACHE_TIMESTAMPS_FILE "timestamps_%s.ldb"
#define LOCAL_SYSDB_FILE "sssd.ldb"
#define SYSDB_BASE "cn=sysdb"
@@ -309,6 +310,8 @@ struct range_info {
char *range_type;
};
+/* These attributes are stored in the timestamp cache */
+extern const char *sysdb_ts_cache_attrs[];
/* values are copied in the structure, allocated on "attrs" */
int sysdb_attrs_add_val(struct sysdb_attrs *attrs,
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index b2b845317..c6e9c4ac1 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -30,6 +30,21 @@
#define LDB_MODULES_PATH "LDB_MODULES_PATH"
+/* If an entry differs only in these attributes, they are written to
+ * the timestamp cache only. In addition, objectclass is added so that
+ * we can distinguish between users and groups.
+ */
+const char *sysdb_ts_cache_attrs[] = {
+ SYSDB_OBJECTCLASS,
+ SYSDB_LAST_UPDATE,
+ SYSDB_CACHE_EXPIRE,
+ SYSDB_ORIG_MODSTAMP,
+ SYSDB_INITGR_EXPIRE,
+ SYSDB_USN,
+
+ NULL,
+};
+
errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx,
const char *filename,
int flags,
@@ -85,11 +100,43 @@ static errno_t sysdb_ldb_reconnect(TALLOC_CTX *mem_ctx,
return ret;
}
+static errno_t sysdb_chown_db_files(struct sysdb_ctx *sysdb,
+ uid_t uid, gid_t gid)
+{
+ errno_t ret;
+
+ ret = chown(sysdb->ldb_file, uid, gid);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot set sysdb ownership of %s to %"SPRIuid":%"SPRIgid"\n",
+ sysdb->ldb_file, uid, gid);
+ return ret;
+ }
+
+ if (sysdb->ldb_ts_file != NULL) {
+ ret = chown(sysdb->ldb_ts_file, uid, gid);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot set sysdb ownership of %s to %"SPRIuid":%"SPRIgid"\n",
+ sysdb->ldb_ts_file, uid, gid);
+ return ret;
+ }
+ }
+
+ return EOK;
+}
+
int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
- const char *provider, const char *name,
- const char *base_path, char **_ldb_file)
+ const char *provider,
+ const char *name,
+ const char *base_path,
+ char **_ldb_file,
+ char **_ts_file)
{
char *ldb_file;
+ char *ts_file = NULL;
/* special case for the local domain */
if (strcasecmp(provider, "local") == 0) {
@@ -98,12 +145,19 @@ int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
} else {
ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE,
base_path, name);
+ ts_file = talloc_asprintf(mem_ctx, "%s/"CACHE_TIMESTAMPS_FILE,
+ base_path, name);
+ if (ts_file == NULL) {
+ talloc_free(ldb_file);
+ return ENOMEM;
+ }
}
if (!ldb_file) {
return ENOMEM;
}
*_ldb_file = ldb_file;
+ *_ts_file = ts_file;
return EOK;
}
@@ -749,14 +803,17 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sysdb_get_db_file(sysdb, domain->provider,
- domain->name, db_path,
- &sysdb->ldb_file);
+ ret = sysdb_get_db_file(sysdb, domain->provider, domain->name, db_path,
+ &sysdb->ldb_file, &sysdb->ldb_ts_file);
if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_FUNC_DATA,
"DB File for %s: %s\n", domain->name, sysdb->ldb_file);
+ if (sysdb->ldb_ts_file) {
+ DEBUG(SSSDBG_FUNC_DATA,
+ "Timestamp file for %s: %s\n", domain->name, sysdb->ldb_ts_file);
+ }
ret = sysdb_domain_cache_connect(sysdb, domain, allow_upgrade);
if (ret != EOK) {
@@ -814,17 +871,19 @@ int sysdb_init_ext(TALLOC_CTX *mem_ctx,
ret = sysdb_domain_init_internal(mem_ctx, dom, DB_PATH,
allow_upgrade, &sysdb);
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot connect to database for %s: [%d]: %s\n",
+ dom->name, ret, sss_strerror(ret));
return ret;
}
if (chown_dbfile) {
- ret = chown(sysdb->ldb_file, uid, gid);
- if (ret != 0) {
- ret = errno;
+ ret = sysdb_chown_db_files(sysdb, uid, gid);
+ if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Cannot set sysdb ownership to %"SPRIuid":%"SPRIgid"\n",
- uid, gid);
- return ret;
+ "Cannot chown databases for %s: [%d]: %s\n",
+ dom->name, ret, sss_strerror(ret));
+ return ret;
}
}
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index 5f7a1ed6f..828863df7 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -118,8 +118,11 @@ struct sysdb_ctx {
/* Internal utility functions */
int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
- const char *provider, const char *name,
- const char *base_path, char **_ldb_file);
+ const char *provider,
+ const char *name,
+ const char *base_path,
+ char **_ldb_file,
+ char **_ts_file);
errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx,
const char *filename,
int flags,
diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c
index 873c8eede..1858111cd 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -282,10 +282,10 @@ int sysdb_check_upgrade_02(struct sss_domain_info *domains,
return ENOMEM;
}
- ret = sysdb_get_db_file(tmp_ctx,
- "local", "UPGRADE",
- db_path, &ldb_file);
- if (ret != EOK) {
+ ldb_file = talloc_asprintf(tmp_ctx, "%s/"LOCAL_SYSDB_FILE,
+ db_path);
+ if (ldb_file == NULL) {
+ ret = ENOMEM;
goto exit;
}
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 352c413be..67a7aa8f9 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -953,7 +953,8 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
ret = sysdb_init(rctx, rctx->domains, false);
if (ret != EOK) {
SYSDB_VERSION_ERROR_DAEMON(ret);
- DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resp_ctx\n");
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "fatal error initializing sysdb connection\n");
goto fail;
}
diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c
index cda1cfb0e..615b613c8 100644
--- a/src/tests/common_dom.c
+++ b/src/tests/common_dom.c
@@ -24,6 +24,8 @@
#include <errno.h>
#include <ldb_module.h>
+/* Including private header makes sure we can initialize test domains. */
+#include "db/sysdb_private.h"
#include "tests/common.h"
static errno_t
@@ -192,6 +194,10 @@ mock_domain(TALLOC_CTX *mem_ctx,
/* reset ldb error if any */
ldb_reset_err_string(sysdb_ctx_get_ldb(domain->sysdb));
+ if (domain->sysdb->ldb_ts != NULL) {
+ ldb_reset_err_string(domain->sysdb->ldb_ts);
+ }
+
/* init with an AD-style regex to be able to test flat name */
ret = sss_names_init_from_args(domain,
"(((?P<domain>[^\\\\]+)\\\\(?P<name>.+$))|" \
@@ -303,6 +309,7 @@ void test_multidom_suite_cleanup(const char *tests_path,
TALLOC_CTX *tmp_ctx = NULL;
char *cdb_path = NULL;
char *sysdb_path = NULL;
+ char *sysdb_ts_path = NULL;
errno_t ret;
int i;
@@ -332,11 +339,20 @@ void test_multidom_suite_cleanup(const char *tests_path,
for (i = 0; domains[i] != NULL; i++) {
if (strcmp(domains[i], LOCAL_SYSDB_FILE) == 0) {
/* local domain */
- sysdb_path = talloc_asprintf(tmp_ctx, "%s/%s",
- tests_path, domains[i]);
+ ret = sysdb_get_db_file(tmp_ctx, "local", domains[i], tests_path,
+ &sysdb_path, &sysdb_ts_path);
+ if (ret != EOK) {
+ goto done;
+ }
} else {
- sysdb_path = talloc_asprintf(tmp_ctx, "%s/cache_%s.ldb",
- tests_path, domains[i]);
+ /* The mocked database doesn't really care about its provider type, just
+ * distinguishes between a local and non-local databases
+ */
+ ret = sysdb_get_db_file(tmp_ctx, "fake_nonlocal", domains[i], tests_path,
+ &sysdb_path, &sysdb_ts_path);
+ if (ret != EOK) {
+ goto done;
+ }
}
if (sysdb_path == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct sysdb path\n");
@@ -351,6 +367,16 @@ void test_multidom_suite_cleanup(const char *tests_path,
"ldb file [%d]: (%s)\n", ret, sss_strerror(ret));
}
+ if (sysdb_ts_path) {
+ errno = 0;
+ ret = unlink(sysdb_ts_path);
+ if (ret != 0 && errno != ENOENT) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test domain "
+ "ldb timestamp file [%d]: (%s)\n", ret, sss_strerror(ret));
+ }
+ }
+
talloc_zfree(sysdb_path);
}
}