summaryrefslogtreecommitdiffstats
path: root/src/responder/nss
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2012-12-19 21:17:40 -0500
committerJakub Hrozek <jhrozek@redhat.com>2012-12-20 20:00:00 +0100
commit26288fe8260cfe5b3134556d0e93d88f6e48eaa0 (patch)
tree630d47cacdc67afc61465f0d6a2c95aeca02e9b8 /src/responder/nss
parent70d56634069fc0f044899e3933f4e61bccefd2c3 (diff)
downloadsssd-26288fe8260cfe5b3134556d0e93d88f6e48eaa0.tar.gz
sssd-26288fe8260cfe5b3134556d0e93d88f6e48eaa0.tar.xz
sssd-26288fe8260cfe5b3134556d0e93d88f6e48eaa0.zip
mmap cache: invalidate cache on fatal error
If a fatal EFAULT error is returned by the internal function that frees used memory invalidate the whole cache and reinit it. This way we avoid further corruption and insure clients see consistent data. Also insure we use the right context in init() and we use talloc_zfree() in reinit so that if the init() later fails we do not leave around a pointer to free memory in the callers.
Diffstat (limited to 'src/responder/nss')
-rw-r--r--src/responder/nss/nsssrv_cmd.c4
-rw-r--r--src/responder/nss/nsssrv_mmap_cache.c32
-rw-r--r--src/responder/nss/nsssrv_mmap_cache.h4
3 files changed, 30 insertions, 10 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index ae6a0966e..af1353f28 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -432,7 +432,7 @@ static int fill_pwent(struct sss_packet *packet,
num++;
if (pw_mmap_cache && nctx->pwd_mc_ctx) {
- ret = sss_mmap_cache_pw_store(nctx->pwd_mc_ctx,
+ ret = sss_mmap_cache_pw_store(&nctx->pwd_mc_ctx,
&fullname, &pwfield,
uid, gid,
&gecos, &homedir, &shell);
@@ -2182,7 +2182,7 @@ static int fill_grent(struct sss_packet *packet,
/* body was reallocated, so fullname might be pointing to
* where body used to be, not where it is */
to_sized_string(&fullname, (const char *)&body[rzero+STRS_ROFFSET]);
- ret = sss_mmap_cache_gr_store(nctx->grp_mc_ctx,
+ ret = sss_mmap_cache_gr_store(&nctx->grp_mc_ctx,
&fullname, &pwfield, gid, memnum,
(char *)&body[rzero] + STRS_ROFFSET +
fullname.len + pwfield.len,
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 01721ed86..16a4bb231 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -392,11 +392,12 @@ static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc,
return rec;
}
-static errno_t sss_mc_get_record(struct sss_mc_ctx *mcc,
+static errno_t sss_mc_get_record(struct sss_mc_ctx **_mcc,
size_t rec_len,
struct sized_string *key,
struct sss_mc_rec **_rec)
{
+ struct sss_mc_ctx *mcc = *_mcc;
struct sss_mc_rec *old_rec = NULL;
struct sss_mc_rec *rec;
int old_slots;
@@ -424,6 +425,11 @@ static errno_t sss_mc_get_record(struct sss_mc_ctx *mcc,
/* we are going to use more space, find enough free slots */
ret = sss_mc_find_free_slots(mcc, num_slots, &base_slot);
if (ret != EOK) {
+ if (ret == EFAULT) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Fatal internal mmap cache error, invalidating cache!\n"));
+ (void)sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, _mcc);
+ }
return ret;
}
@@ -474,7 +480,7 @@ static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc,
* passwd map
***************************************************************************/
-errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
struct sized_string *name,
struct sized_string *pw,
uid_t uid, gid_t gid,
@@ -482,6 +488,7 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
struct sized_string *homedir,
struct sized_string *shell)
{
+ struct sss_mc_ctx *mcc = *_mcc;
struct sss_mc_rec *rec;
struct sss_mc_pwd_data *data;
struct sized_string uidkey;
@@ -510,7 +517,7 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
return ENOMEM;
}
- ret = sss_mc_get_record(mcc, rec_len, name, &rec);
+ ret = sss_mc_get_record(_mcc, rec_len, name, &rec);
if (ret != EOK) {
return ret;
}
@@ -615,12 +622,13 @@ done:
* group map
***************************************************************************/
-int sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
+int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
struct sized_string *name,
struct sized_string *pw,
gid_t gid, size_t memnum,
char *membuf, size_t memsize)
{
+ struct sss_mc_ctx *mcc = *_mcc;
struct sss_mc_rec *rec;
struct sss_mc_grp_data *data;
struct sized_string gidkey;
@@ -649,7 +657,7 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
return ENOMEM;
}
- ret = sss_mc_get_record(mcc, rec_len, name, &rec);
+ ret = sss_mc_get_record(_mcc, rec_len, name, &rec);
if (ret != EOK) {
return ret;
}
@@ -906,7 +914,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
}
mc_ctx->fd = -1;
- mc_ctx->name = talloc_strdup(mem_ctx, name);
+ mc_ctx->name = talloc_strdup(mc_ctx, name);
if (!mc_ctx->name) {
ret = ENOMEM;
goto done;
@@ -1033,6 +1041,15 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
}
type = (*mc_ctx)->type;
+
+ if (n_elem == (size_t)-1) {
+ n_elem = (*mc_ctx)->ft_size * 8;
+ }
+
+ if (timeout == (time_t)-1) {
+ timeout = (*mc_ctx)->valid_time_slot;
+ }
+
ret = talloc_free(*mc_ctx);
if (ret != 0) {
/* This can happen only if destructor is associated with this
@@ -1041,6 +1058,9 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
" context failed.\n"));
}
+ /* make sure we do not leave a potentially freed pointer around */
+ *mc_ctx = NULL;
+
ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to re-initialize mmap cache.\n"));
diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
index 0da637970..25cec40cc 100644
--- a/src/responder/nss/nsssrv_mmap_cache.h
+++ b/src/responder/nss/nsssrv_mmap_cache.h
@@ -36,7 +36,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
enum sss_mc_type type, size_t n_elem,
time_t valid_time, struct sss_mc_ctx **mcc);
-errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
struct sized_string *name,
struct sized_string *pw,
uid_t uid, gid_t gid,
@@ -44,7 +44,7 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
struct sized_string *homedir,
struct sized_string *shell);
-errno_t sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
struct sized_string *name,
struct sized_string *pw,
gid_t gid, size_t memnum,