diff options
Diffstat (limited to 'src/responder/nss/nsssrv_mmap_cache.c')
-rw-r--r-- | src/responder/nss/nsssrv_mmap_cache.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index d3852c67..7149ca80 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; } @@ -494,7 +500,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, @@ -502,6 +508,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; @@ -530,7 +537,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; } @@ -630,12 +637,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; @@ -664,7 +672,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; } @@ -916,7 +924,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; @@ -1043,6 +1051,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 @@ -1051,6 +1068,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")); |