From 6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 29 Dec 2011 02:19:11 -0500 Subject: nsssrv: add handling of memory cache passwd map --- src/responder/nss/nsssrv_cmd.c | 20 +++++++-- src/responder/nss/nsssrv_mmap_cache.c | 76 +++++++++++++++++++++++++++++++++++ src/responder/nss/nsssrv_mmap_cache.h | 8 ++++ 3 files changed, 101 insertions(+), 3 deletions(-) (limited to 'src/responder') diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 1e9927c1..cda2e563 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -24,6 +24,7 @@ #include "responder/nss/nsssrv_private.h" #include "responder/nss/nsssrv_netgroup.h" #include "responder/nss/nsssrv_services.h" +#include "responder/nss/nsssrv_mmap_cache.h" #include "responder/common/negcache.h" #include "confdb/confdb.h" #include "db/sysdb.h" @@ -294,7 +295,7 @@ static const char *get_shell_override(TALLOC_CTX *mem_ctx, static int fill_pwent(struct sss_packet *packet, struct sss_domain_info *dom, struct nss_ctx *nctx, - bool filter_users, + bool filter_users, bool pw_mmap_cache, struct ldb_message **msgs, int *count) { @@ -445,6 +446,17 @@ static int fill_pwent(struct sss_packet *packet, rp += shell.len; num++; + + if (pw_mmap_cache) { + ret = sss_mmap_cache_pw_store(nctx->pwd_mc_ctx, + &fullname, &pwfield, + uid, gid, + &gecos, &homedir, &shell); + if (ret != EOK && ret != ENOMEM) { + DEBUG(1, ("Failed to store user %s(%s) in mmap cache!", + name.str, domain)); + } + } } talloc_zfree(tmp_ctx); @@ -479,9 +491,10 @@ static int nss_cmd_getpw_send_reply(struct nss_dom_ctx *dctx, bool filter) return EFAULT; } i = dctx->res->count; + ret = fill_pwent(cctx->creq->out, dctx->domain, - nctx, filter, + nctx, filter, true, dctx->res->msgs, &i); if (ret) { return ret; @@ -1580,7 +1593,8 @@ static int nss_cmd_retpwent(struct cli_ctx *cctx, int num) msgs = &(pdom->res->msgs[cctx->pwent_cur]); - ret = fill_pwent(cctx->creq->out, pdom->domain, nctx, true, msgs, &n); + ret = fill_pwent(cctx->creq->out, pdom->domain, nctx, + true, false, msgs, &n); cctx->pwent_cur += n; } diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 2f90d826..d1f639fd 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -347,6 +347,82 @@ static struct sss_mc_rec *sss_mc_get_record(struct sss_mc_ctx *mcc, } +/*************************************************************************** + * passwd map + ***************************************************************************/ + +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, + struct sized_string *gecos, + struct sized_string *homedir, + struct sized_string *shell) +{ + struct sss_mc_rec *rec; + struct sss_mc_pwd_data *data; + struct sized_string uidkey; + char uidstr[11]; + size_t data_len; + size_t rec_len; + size_t pos; + int ret; + + ret = snprintf(uidstr, 11, "%ld", (long)uid); + if (ret > 10) { + return EINVAL; + } + to_sized_string(&uidkey, uidstr); + + data_len = name->len + pw->len + gecos->len + homedir->len + shell->len; + rec_len = sizeof(struct sss_mc_rec) + + sizeof(struct sss_mc_pwd_data) + + data_len; + if (rec_len > mcc->dt_size) { + return ENOMEM; + } + + rec = sss_mc_get_record(mcc, rec_len, name); + + data = (struct sss_mc_pwd_data *)rec->data; + pos = 0; + + MC_RAISE_BARRIER(rec); + + /* header */ + rec->len = rec_len; + rec->expire = time(NULL) + mcc->valid_time_slot; + rec->hash1 = sss_mc_hash(mcc, name->str, name->len); + rec->hash2 = sss_mc_hash(mcc, uidkey.str, uidkey.len); + + /* passwd struct */ + data->name = MC_PTR_DIFF(data->strs, data); + data->uid = uid; + data->gid = gid; + data->strs_len = data_len; + memcpy(&data->strs[pos], name->str, name->len); + pos += name->len; + memcpy(&data->strs[pos], pw->str, pw->len); + pos += pw->len; + memcpy(&data->strs[pos], gecos->str, gecos->len); + pos += gecos->len; + 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); + + /* finally chain the rec in the hash table */ + /* name hash first */ + sss_mc_add_rec_to_chain(mcc, rec, rec->hash1); + /* then uid */ + sss_mc_add_rec_to_chain(mcc, rec, rec->hash2); + + return EOK; +} + + /*************************************************************************** * initialization ***************************************************************************/ diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h index 6f49b8b7..fc99cdbb 100644 --- a/src/responder/nss/nsssrv_mmap_cache.h +++ b/src/responder/nss/nsssrv_mmap_cache.h @@ -34,4 +34,12 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name, enum sss_mc_type type, size_t n_elem, 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, + struct sized_string *gecos, + struct sized_string *homedir, + struct sized_string *shell); + #endif /* _NSSSRV_MMAP_CACHE_H_ */ -- cgit