summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 27cbedcbe..2ad9194c5 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);
@@ -2185,7 +2185,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 d3852c67d..7149ca805 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"));
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,