>From 8629c3d464362e974aaf1c1c3f9cfe27b86ad08e Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Thu, 29 Dec 2011 02:19:11 -0500
Subject: [PATCH 11/15] 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(-)

diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index abed7a8869e09eebbaa4128d70d46df7b51a4a9d..0a1c2fad7a072fdff770c70947df5586fbe98942 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -23,6 +23,7 @@
 #include "responder/nss/nsssrv.h"
 #include "responder/nss/nsssrv_private.h"
 #include "responder/nss/nsssrv_netgroup.h"
+#include "responder/nss/nsssrv_mmap_cache.h"
 #include "responder/common/negcache.h"
 #include "confdb/confdb.h"
 #include "db/sysdb.h"
@@ -357,7 +358,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)
 {
@@ -508,6 +509,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);
 
@@ -542,9 +554,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;
@@ -1676,7 +1689,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 7d6c7c21cf939b777de53f13ca669ceb1dc6788d..97be7a31d4b5bed78fbb50f5bb15574ec5c65154 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -348,6 +348,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 6f49b8b76a576b86706da27784a01caf8b8b1beb..fc99cdbbd1814e7f564f0e59cb07ea284251affe 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_ */
-- 
1.7.7.5

