ehlo, patches are attached.
LS
>From 6cd4f20386a6f831f07753650b09ca0358c15bb6 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Sat, 23 May 2015 17:02:30 +0200 Subject: [PATCH 1/8] mmap_cache: remove dead increment --- src/responder/nss/nsssrv_mmap_cache.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 2d159eb11add2014612c21d2061942cb1afa553c..18f83e1666953d146a80d2dee48d65e0ca41ed6a 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -740,7 +740,6 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, memcpy(&data->strs[pos], homedir->str, homedir->len); pos += homedir->len; memcpy(&data->strs[pos], shell->str, shell->len); - pos += shell->len; MC_LOWER_BARRIER(rec); @@ -879,7 +878,6 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, memcpy(&data->strs[pos], pw->str, pw->len); pos += pw->len; memcpy(&data->strs[pos], membuf, memsize); - pos += memsize; MC_LOWER_BARRIER(rec); -- 2.4.3
>From 2d4c4b710063019b2796f50b38e725e11e693a2f Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Tue, 30 Jun 2015 13:50:51 +0200 Subject: [PATCH 2/8] nss: Store entries in responder to initgr mmap cache Resolves: https://fedorahosted.org/sssd/ticket/2485 --- src/responder/nss/nsssrv.c | 16 +++++++++ src/responder/nss/nsssrv.h | 1 + src/responder/nss/nsssrv_cmd.c | 30 +++++++++++++--- src/responder/nss/nsssrv_mmap_cache.c | 64 +++++++++++++++++++++++++++++++++++ src/responder/nss/nsssrv_mmap_cache.h | 9 +++++ src/util/mmap_cache.h | 8 +++++ 6 files changed, 124 insertions(+), 4 deletions(-) diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c index 48fb19408cc10e99b79308debb7ef6c3e6bc0127..2b3bca892a5b9c483d1f6f099fd4a6493e9afcab 100644 --- a/src/responder/nss/nsssrv.c +++ b/src/responder/nss/nsssrv.c @@ -124,6 +124,15 @@ static int nss_clear_memcache(struct sbus_request *dbus_req, void *data) return ret; } + ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS, + (time_t)memcache_timeout, + &nctx->initgr_mc_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "initgroups mmap cache invalidation failed\n"); + return ret; + } + done: return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } @@ -517,6 +526,13 @@ int nss_process_init(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n"); } + ret = sss_mmap_cache_init(nctx, "initgroups", SSS_MC_INITGROUPS, + SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, + &nctx->initgr_mc_ctx); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, "inigroups mmap cache is DISABLED\n"); + } + /* Set up file descriptor limits */ ret = confdb_get_int(nctx->rctx->cdb, CONFDB_NSS_CONF_ENTRY, diff --git a/src/responder/nss/nsssrv.h b/src/responder/nss/nsssrv.h index 784eba2e0c6b15b106a2323bba1de5523e2937c1..e293e3b4d03582abf6abf07cce61d3b6fdebfcae 100644 --- a/src/responder/nss/nsssrv.h +++ b/src/responder/nss/nsssrv.h @@ -72,6 +72,7 @@ struct nss_ctx { struct sss_mc_ctx *pwd_mc_ctx; struct sss_mc_ctx *grp_mc_ctx; + struct sss_mc_ctx *initgr_mc_ctx; struct sss_idmap_ctx *idmap_ctx; struct sss_names_ctx *global_names; diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 012c4e701a4ee211e8e3bb66713d7edc43a48717..ccb8e733419c6c199d89f9a02bd1de93bb4b667c 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -3909,17 +3909,23 @@ done: /* FIXME: what about mpg, should we return the user's GID ? */ /* FIXME: should we filter out GIDs ? */ -static int fill_initgr(struct sss_packet *packet, struct sss_domain_info *dom, - struct ldb_result *res) +static int fill_initgr(struct sss_packet *packet, + struct sss_domain_info *dom, + struct ldb_result *res, + struct nss_ctx *nctx, + const char *name) { uint8_t *body; size_t blen; gid_t gid; - int ret, i, num; + int ret, i; + uint32_t num; size_t bindex; int skipped = 0; const char *posix; gid_t orig_primary_gid; + struct sized_string rawname; + uint8_t *gids; if (res->count == 0) { return ENOENT; @@ -3952,6 +3958,7 @@ static int fill_initgr(struct sss_packet *packet, struct sss_domain_info *dom, /* 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) */ bindex = 2 * sizeof(uint32_t); + gids = body + bindex; /* skip first entry, it's the user entry */ for (i = 0; i < num; i++) { @@ -3993,6 +4000,17 @@ static int fill_initgr(struct sss_packet *packet, struct sss_domain_info *dom, return ret; } + if (nctx->initgr_mc_ctx) { + to_sized_string(&rawname, name); + ret = sss_mmap_cache_initgr_store(&nctx->initgr_mc_ctx, &rawname, + num - skipped, gids); + if (ret != EOK && ret != ENOMEM) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to store user %s(%s) in mmap cache!\n", + rawname.str, dom->name); + } + } + return EOK; } @@ -4000,8 +4018,11 @@ static int nss_cmd_initgr_send_reply(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; + struct nss_ctx *nctx; int ret; + nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); + ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); @@ -4009,7 +4030,8 @@ static int nss_cmd_initgr_send_reply(struct nss_dom_ctx *dctx) return EFAULT; } - ret = fill_initgr(cctx->creq->out, dctx->domain, dctx->res); + ret = fill_initgr(cctx->creq->out, dctx->domain, dctx->res, nctx, + dctx->rawname); if (ret) { return ret; } diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 18f83e1666953d146a80d2dee48d65e0ca41ed6a..b139c92c13ed80dc05a35f15963e733d46e2949a 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -31,6 +31,8 @@ #define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4) /* short group name and no gids (private user group */ #define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3) +/* average place for 40 supplementary groups */ +#define SSS_AVG_INITGROUP_PAYLOAD (MC_SLOT_SIZE * 4) #define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000) @@ -953,6 +955,65 @@ done: return ret; } +errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, + struct sized_string *name, + uint32_t memnum, + uint8_t *membuf) +{ + struct sss_mc_ctx *mcc = *_mcc; + struct sss_mc_rec *rec; + struct sss_mc_initgr_data *data; + size_t data_len; + size_t rec_len; + int ret; + + if (mcc == NULL) { + /* cache not initialized ? */ + return EINVAL; + } + + /* memnum + reserved + array of members + name*/ + data_len = (2 + memnum) * sizeof(uint32_t) + name->len; + rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_initgr_data) + + data_len; + if (rec_len > mcc->dt_size) { + return ENOMEM; + } + + ret = sss_mc_get_record(_mcc, rec_len, name, &rec); + if (ret != EOK) { + return ret; + } + + data = (struct sss_mc_initgr_data *)rec->data; + + MC_RAISE_BARRIER(rec); + + /* We cannot use two keys for searching in intgroups cache. + * Use the first key twice. + */ + sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot, + name->str, name->len, name->str, name->len); + + /* initgroups struct */ + data->members = memnum; + memcpy(data->gids, membuf, memnum * sizeof(uint32_t)); + memcpy(&data->gids[memnum], name->str, name->len); + data->name = MC_PTR_DIFF(&data->gids[memnum], data); + + MC_LOWER_BARRIER(rec); + + /* finally chain the rec in the hash table */ + sss_mmap_chain_in_rec(mcc, rec); + + return EOK; +} + +errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, + struct sized_string *name) +{ + return sss_mmap_cache_invalidate(mcc, name); +} /*************************************************************************** * initialization @@ -1143,6 +1204,9 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name, case SSS_MC_GROUP: payload = SSS_AVG_GROUP_PAYLOAD; break; + case SSS_MC_INITGROUPS: + payload = SSS_AVG_INITGROUP_PAYLOAD; + break; default: return EINVAL; } diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h index fdeaa09126858b04958f4e3eee17b8a92cf61350..3a6764dd36bf3346d789bb287b3a94df120f36ee 100644 --- a/src/responder/nss/nsssrv_mmap_cache.h +++ b/src/responder/nss/nsssrv_mmap_cache.h @@ -30,6 +30,7 @@ enum sss_mc_type { SSS_MC_NONE = 0, SSS_MC_PASSWD, SSS_MC_GROUP, + SSS_MC_INITGROUPS, }; errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name, @@ -50,6 +51,11 @@ errno_t sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, gid_t gid, size_t memnum, char *membuf, size_t memsize); +errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, + struct sized_string *name, + uint32_t memnum, + uint8_t *membuf); + errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name); @@ -60,6 +66,9 @@ errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc, errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid); +errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, + struct sized_string *name); + errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem, time_t timeout, struct sss_mc_ctx **mc_ctx); diff --git a/src/util/mmap_cache.h b/src/util/mmap_cache.h index 81269fe7e03f586059aab789336ebe3903026d0a..438e28a3d217041278fc1bb60aa553d098516035 100644 --- a/src/util/mmap_cache.h +++ b/src/util/mmap_cache.h @@ -136,6 +136,14 @@ struct sss_mc_grp_data { * string is zero terminated ordered as follows: * name, passwd, member1, member2, ... */ }; + +struct sss_mc_initgr_data { + rel_ptr_t name; /* ptr to name string, rel. to struct base addr */ + uint32_t members; /* number of members in groups */ + uint32_t gids[0]; /* array of all groups + * string with name is stored after gids */ +}; + #pragma pack() -- 2.4.3
>From 28d7087c0ee2c39db7d78c5bad6bed16162843cf Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Tue, 30 Jun 2015 14:16:47 +0200 Subject: [PATCH 3/8] mmap_cache: Invalidate entry in right memory cache If group was not found in nss_cmd_getgrnam_search then we tied to invalidate entry in memory cache. But function delete_entry_from_memory cache only invalidated in passwd memory cache. --- src/responder/nss/nsssrv_cmd.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index ccb8e733419c6c199d89f9a02bd1de93bb4b667c..b163d6d57b77d39999085d5d20b6c483e6b99448 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -753,7 +753,8 @@ static void nsssrv_dp_send_acct_req_done(struct tevent_req *req) } static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, - struct sss_mc_ctx *mc_ctx) + struct sss_mc_ctx *mc_ctx, + enum sss_mc_type type) { TALLOC_CTX *tmp_ctx = NULL; struct sized_string delete_name; @@ -778,11 +779,27 @@ static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, to_sized_string(&delete_name, name); } - ret = sss_mmap_cache_pw_invalidate(mc_ctx, &delete_name); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Internal failure in memory cache code: %d [%s]\n", - ret, strerror(ret)); + switch (type) { + case SSS_MC_PASSWD: + ret = sss_mmap_cache_pw_invalidate(mc_ctx, &delete_name); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret)); + goto done; + } + break; + case SSS_MC_GROUP: + ret = sss_mmap_cache_gr_invalidate(mc_ctx, &delete_name); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret)); + goto done; + } + break; + default: + ret = EINVAL; goto done; } @@ -944,7 +961,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) /* User not found in ldb -> delete user from memory cache. */ ret = delete_entry_from_memcache(dctx->domain, name, - nctx->pwd_mc_ctx); + nctx->pwd_mc_ctx, SSS_MC_PASSWD); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting user from memcache failed.\n"); @@ -3064,7 +3081,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) /* Group not found in ldb -> delete group from memory cache. */ ret = delete_entry_from_memcache(dctx->domain, name, - nctx->grp_mc_ctx); + nctx->grp_mc_ctx, SSS_MC_GROUP); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting group from memcache failed.\n"); -- 2.4.3
>From b3d1e4ca0da29271f8dedc32b0afaa6e3ed34855 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Tue, 30 Jun 2015 14:26:12 +0200 Subject: [PATCH 4/8] nss: Invalidate entry in initgr mmap cache If user is removed from sysdb cache then it should be also removed from initgroups memory cache. Resolves: https://fedorahosted.org/sssd/ticket/2485 --- src/responder/nss/nsssrv_cmd.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index b163d6d57b77d39999085d5d20b6c483e6b99448..412cd1c17ebfe43189c4685a5ad351f9844821e6 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -168,6 +168,13 @@ void nss_update_pw_memcache(struct nss_ctx *nctx) "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } + + ret = sss_mmap_cache_pw_invalidate(nctx->initgr_mc_ctx, &key); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret)); + } } talloc_zfree(res); @@ -797,6 +804,14 @@ static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, ret, strerror(ret)); goto done; } + case SSS_MC_INITGROUPS: + ret = sss_mmap_cache_initgr_invalidate(mc_ctx, &delete_name); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret)); + goto done; + } break; default: ret = EINVAL; @@ -967,6 +982,14 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) "Deleting user from memcache failed.\n"); } + ret = delete_entry_from_memcache(dctx->domain, name, + nctx->initgr_mc_ctx, + SSS_MC_INITGROUPS); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Deleting user from memcache failed.\n"); + } + return ENOENT; } @@ -3871,6 +3894,14 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, ret, strerror(ret)); } + ret = sss_mmap_cache_initgr_invalidate(nctx->initgr_mc_ctx, + &delete_name); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret)); + } + /* Also invalidate his groups */ changed = true; } else { -- 2.4.3
>From e63ec2b0e2ff4078ba1c36aa6e5466d87906440e Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Tue, 30 Jun 2015 16:36:03 +0200 Subject: [PATCH 5/8] sss_client: Use initgr mmap cache in client code Resolves: https://fedorahosted.org/sssd/ticket/2485 --- Makefile.am | 1 + src/sss_client/nss_group.c | 29 +++++++- src/sss_client/nss_mc.h | 5 ++ src/sss_client/nss_mc_initgr.c | 159 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/sss_client/nss_mc_initgr.c diff --git a/Makefile.am b/Makefile.am index 93a32dbdb932fe18c6d8f9361d7f97b0e05d0c17..6294a74f93a2d08f9374720a1ce9bc5f6a84f4c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2597,6 +2597,7 @@ libnss_sss_la_SOURCES = \ src/util/murmurhash3.c \ src/sss_client/nss_mc_passwd.c \ src/sss_client/nss_mc_group.c \ + src/sss_client/nss_mc_initgr.c \ src/sss_client/nss_mc.h libnss_sss_la_LIBADD = \ $(CLIENT_LIBS) diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c index 1614c33b5388326d82f1c9c1baaeee472a676cb9..b614fcf7f493345f793d3d4a28df998534ca546b 100644 --- a/src/sss_client/nss_group.c +++ b/src/sss_client/nss_group.c @@ -281,10 +281,37 @@ enum nss_status _nss_sss_initgroups_dyn(const char *user, gid_t group, size_t replen; enum nss_status nret; size_t buf_index = 0; + size_t user_len; uint32_t num_ret; long int l, max_ret; + int ret; - rd.len = strlen(user) +1; + ret = sss_strnlen(user, SSS_NAME_MAX, &user_len); + if (ret != 0) { + *errnop = EINVAL; + return NSS_STATUS_NOTFOUND; + } + + ret = sss_nss_mc_initgroups_dyn(user, user_len, group, start, size, + groups, limit); + switch (ret) { + case 0: + *errnop = 0; + return NSS_STATUS_SUCCESS; + case ERANGE: + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + case ENOENT: + /* fall through, we need to actively ask the parent + * if no entry is found */ + break; + default: + /* if using the mmaped cache failed, + * fall back to socket based comms */ + break; + } + + rd.len = user_len + 1; rd.data = user; sss_nss_lock(); diff --git a/src/sss_client/nss_mc.h b/src/sss_client/nss_mc.h index 050bd4100dec091cb096a7d97bfe6615b12654da..a39d45f143d2f2a6eb006ffc4b45fda097dad4f2 100644 --- a/src/sss_client/nss_mc.h +++ b/src/sss_client/nss_mc.h @@ -85,4 +85,9 @@ errno_t sss_nss_mc_getgrgid(gid_t gid, struct group *result, char *buffer, size_t buflen); +/* initgroups db */ +errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, + gid_t group, long int *start, long int *size, + gid_t **groups, long int limit); + #endif /* _NSS_MC_H_ */ diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c new file mode 100644 index 0000000000000000000000000000000000000000..bfb09d6550c310fbab254dc9b3ab7b306b7d3f06 --- /dev/null +++ b/src/sss_client/nss_mc_initgr.c @@ -0,0 +1,159 @@ +/* + * System Security Services Daemon. NSS client interface + * + * Authors: + * Lukas Slebodnik <[email protected]> + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* INITGROUPs database NSS interface using mmap cache */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <sys/mman.h> +#include <time.h> +#include "nss_mc.h" +#include "util/util_safealign.h" + +struct sss_cli_mc_ctx initgr_mc_ctx = { UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, + NULL, 0, 0 }; + +static errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec, + long int *start, long int *size, + gid_t **groups, long int limit) +{ + struct sss_mc_initgr_data *data; + time_t expire; + long int i; + uint32_t gid_count; + long int max_ret; + + /* additional checks before filling result*/ + expire = rec->expire; + if (expire < time(NULL)) { + /* entry is now invalid */ + return EINVAL; + } + + data = (struct sss_mc_initgr_data *)rec->data; + gid_count = data->members; + max_ret = gid_count; + + /* check we have enough space in the buffer */ + if ((*size - *start) < gid_count) { + long int newsize; + gid_t *newgroups; + + newsize = *size + gid_count; + if ((limit > 0) && (newsize > limit)) { + newsize = limit; + max_ret = newsize - *start; + } + + newgroups = (gid_t *)realloc((*groups), newsize * sizeof(**groups)); + if (!newgroups) { + return ENOMEM; + } + *groups = newgroups; + *size = newsize; + } + + for (i = 0; i < max_ret; i++) { + SAFEALIGN_COPY_UINT32(&(*groups)[*start], data->gids + i, NULL); + *start += 1; + } + + return 0; +} + +errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, + gid_t group, long int *start, long int *size, + gid_t **groups, long int limit) +{ + struct sss_mc_rec *rec = NULL; + struct sss_mc_initgr_data *data; + char *rec_name; + uint32_t hash; + uint32_t slot; + int ret; + uint8_t *max_addr; + + ret = sss_nss_mc_get_ctx("initgroups", &initgr_mc_ctx); + if (ret) { + return ret; + } + + /* Get max address of data table. */ + max_addr = initgr_mc_ctx.data_table + initgr_mc_ctx.dt_size; + + /* hashes are calculated including the NULL terminator */ + hash = sss_nss_mc_hash(&initgr_mc_ctx, name, name_len + 1); + slot = initgr_mc_ctx.hash_table[hash]; + + /* If slot is not within the bounds of mmaped region and + * it's value is not MC_INVALID_VAL, then the cache is + * probbably corrupted. */ + while (MC_SLOT_WITHIN_BOUNDS(slot, initgr_mc_ctx.dt_size)) { + /* free record from previous iteration */ + free(rec); + rec = NULL; + + ret = sss_nss_mc_get_record(&initgr_mc_ctx, slot, &rec); + if (ret) { + goto done; + } + + /* check record matches what we are searching for */ + if (hash != rec->hash1) { + /* if name hash does not match we can skip this immediately */ + slot = sss_nss_mc_next_slot_with_hash(rec, hash); + continue; + } + + data = (struct sss_mc_initgr_data *)rec->data; + /* Integrity check + * - array with gids must be within data_table + * - string must be within data_table */ + if ((uint8_t *)data->gids > max_addr + || (uint8_t *)data + data->name + name_len > max_addr) { + ret = ENOENT; + goto done; + } + + rec_name = (char *)data + data->name; + if (strcmp(name, rec_name) == 0) { + break; + } + + slot = sss_nss_mc_next_slot_with_hash(rec, hash); + } + + if (!MC_SLOT_WITHIN_BOUNDS(slot, initgr_mc_ctx.dt_size)) { + ret = ENOENT; + goto done; + } + + ret = sss_nss_mc_parse_result(rec, start, size, groups, limit); + +done: + free(rec); + __sync_sub_and_fetch(&initgr_mc_ctx.active_threads, 1); + return ret; +} -- 2.4.3
>From e921a1ec890087ac0d493879610893532813d0de Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik <[email protected]> Date: Tue, 30 Jun 2015 17:43:34 +0200 Subject: [PATCH 6/8] sss_cache: Clear also initgroups fast cache --- src/tools/tools_mc_util.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tools/tools_mc_util.c b/src/tools/tools_mc_util.c index 9634b86e248a1937f68939c5a8d8a6301780a566..c1b5c616d0e6d50147ecd81308aaa1e69304af92 100644 --- a/src/tools/tools_mc_util.c +++ b/src/tools/tools_mc_util.c @@ -147,6 +147,16 @@ static int clear_fastcache(bool *sssd_nss_is_off) } } + ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/initgroups"); + if (ret != EOK) { + if (ret == EACCES) { + *sssd_nss_is_off = false; + return EOK; + } else { + return ret; + } + } + *sssd_nss_is_off = true; return EOK; } -- 2.4.3
_______________________________________________ sssd-devel mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
