From 73c3801421b8898ab7fc69b92d344919f7e301da Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Thu, 17 Jun 2010 09:50:01 -0400
Subject: [PATCH 4/4] Honor filter_users in PAM

---
 src/responder/pam/pamsrv.c     |   31 ++++++++++++++++++++++++++++---
 src/responder/pam/pamsrv.h     |    2 ++
 src/responder/pam/pamsrv_cmd.c |   24 +++++++++++++++++-------
 3 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index c82f0fab1f909062c0c015800f1d29ef409f84df..61e7ce7a360daaa494e1ea23c15b8cf6016b0ab7 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -42,6 +42,7 @@
 #include "monitor/monitor_interfaces.h"
 #include "sbus/sbus_client.h"
 #include "responder/pam/pamsrv.h"
+#include "responder/common/negcache.h"
 
 #define SSS_PAM_SBUS_SERVICE_VERSION 0x0001
 #define SSS_PAM_SBUS_SERVICE_NAME "pam"
@@ -125,7 +126,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
                            "PAM", &pam_dp_interface,
                            &pctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto done;
     }
 
     pctx->rctx->pvt_ctx = pctx;
@@ -138,7 +139,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
                          CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto done;
     }
 
     for (iter = pctx->rctx->be_conns; iter; iter = iter->next) {
@@ -146,7 +147,31 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
                             pam_dp_reconnect_init, iter);
     }
 
-    return EOK;
+    /* Set up the negative cache */
+    ret = confdb_get_int(cdb, pctx, CONFDB_NSS_CONF_ENTRY,
+                         CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15,
+                         &pctx->neg_timeout);
+    if (ret != EOK) goto done;
+
+    ret = sss_ncache_init(pctx, &pctx->ncache);
+    if (ret != EOK) {
+        DEBUG(0, ("fatal error initializing negative cache\n"));
+        goto done;
+    }
+
+    ret = sss_ncache_prepopulate(pctx->ncache, cdb, pctx->rctx->names,
+                                 pctx->rctx->domains);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    ret = EOK;
+
+done:
+    if (ret != EOK) {
+        talloc_free(pctx);
+    }
+    return ret;
 }
 
 int main(int argc, const char *argv[])
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 689d78474804cd3c9ab8d9ca458ff90cc7ac4569..3ada4cfd812844656889fc9e09c453b913a87d72 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -33,6 +33,8 @@ typedef void (pam_dp_callback_t)(struct pam_auth_req *preq);
 
 struct pam_ctx {
     struct resp_ctx *rctx;
+    struct sss_nc_ctx *ncache;
+    int neg_timeout;
 };
 
 struct pam_auth_req {
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 43da44bc434a9351e88c6374031b25deb602c64f..7bfd0f249a96ecb66c31c2b611c9bdac37fa60e7 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -26,6 +26,7 @@
 #include "confdb/confdb.h"
 #include "responder/common/responder_packet.h"
 #include "responder/common/responder.h"
+#include "responder/common/negcache.h"
 #include "providers/data_provider.h"
 #include "responder/pam/pamsrv.h"
 #include "db/sysdb.h"
@@ -580,6 +581,9 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
     uint8_t *body;
     size_t blen;
     int ret;
+    errno_t ncret;
+    struct pam_ctx *pctx =
+            talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx);
     uint32_t terminator = SSS_END_OF_PAM_REQUEST;
     preq = talloc_zero(cctx, struct pam_auth_req);
     if (!preq) {
@@ -640,13 +644,19 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
         for (dom = preq->cctx->rctx->domains; dom; dom = dom->next) {
             if (dom->fqnames) continue;
 
-/* FIXME: need to support negative cache */
-#if HAVE_NEG_CACHE
-            ncret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
-                                          dom->name, cmdctx->name);
-            if (ncret == ENOENT) break;
-#endif
-            break;
+            ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
+                                          dom->name, pd->user);
+            if (ncret == ENOENT) {
+                /* User not found in the negative cache
+                 * Proceed with PAM actions
+                 */
+                break;
+            }
+
+            /* Try the next domain */
+            DEBUG(4, ("User [%s@%s] filtered out (negative cache). "
+                      "Trying next domain.\n",
+                      pd->user, dom->name));
         }
         if (!dom) {
             ret = ENOENT;
-- 
1.7.0.1

