Blame SOURCES/0116-PAM-Check-for-trusted-domain-before-sending-the-requ.patch

905b4d
From 663fb2625181ca8b80d26526a8298674ab6242a1 Mon Sep 17 00:00:00 2001
905b4d
From: Jakub Hrozek <jhrozek@redhat.com>
905b4d
Date: Sun, 23 Nov 2014 19:43:04 +0100
905b4d
Subject: [PATCH 116/117] PAM: Check for trusted domain before sending the
905b4d
 request to BE
905b4d
905b4d
https://fedorahosted.org/sssd/ticket/2501
905b4d
905b4d
Moving the checks to one place has the advantage of not duplicating
905b4d
security decisions. Previously, the checks were scattered all over the
905b4d
responder code, making testing hard.
905b4d
905b4d
The disadvantage is that we actually check for the presence of the user,
905b4d
which might trigger some back end lookups. But I think the benefits
905b4d
overweight the disadvantage.
905b4d
905b4d
Also only check the requested domains from a trusted client. An untrusted
905b4d
client should simply have no say in what domains he wants to talk to, it
905b4d
should ignore the 'domains' option.
905b4d
905b4d
Reviewed-by: Sumit Bose <sbose@redhat.com>
905b4d
---
905b4d
 src/responder/pam/pamsrv_cmd.c | 67 ++++++++++++++++--------------------------
905b4d
 1 file changed, 26 insertions(+), 41 deletions(-)
905b4d
905b4d
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
905b4d
index dd0e6e4cf54e6d98da807808ad6973dddc013413..b60ccba2d4ff669e7ed0252923a53755410851e3 100644
905b4d
--- a/src/responder/pam/pamsrv_cmd.c
905b4d
+++ b/src/responder/pam/pamsrv_cmd.c
905b4d
@@ -898,17 +898,6 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
905b4d
             goto done;
905b4d
         }
905b4d
 
905b4d
-        /* Untrusted users can access only public domains. */
905b4d
-        if (!pctx->is_uid_trusted &&
905b4d
-            !is_domain_public(pd->domain, pctx->public_domains,
905b4d
-                              pctx->public_domains_count)) {
905b4d
-            DEBUG(SSSDBG_MINOR_FAILURE,
905b4d
-                  "Untrusted user %"PRIu32" cannot access unpublic domain %s.\n",
905b4d
-                  cctx->client_euid, pd->domain);
905b4d
-            ret = EPERM;
905b4d
-            goto done;
905b4d
-        }
905b4d
-
905b4d
         ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
905b4d
                                       preq->domain, pd->user);
905b4d
         if (ncret == EEXIST) {
905b4d
@@ -916,34 +905,12 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
905b4d
             ret = ENOENT;
905b4d
             goto done;
905b4d
         }
905b4d
-
905b4d
-        /* skip this domain if not requested */
905b4d
-        if (!is_domain_requested(pd, pd->domain)) {
905b4d
-            ret = ENOENT;
905b4d
-            goto done;
905b4d
-        }
905b4d
     } else {
905b4d
         for (dom = preq->cctx->rctx->domains;
905b4d
              dom;
905b4d
              dom = get_next_domain(dom, false)) {
905b4d
             if (dom->fqnames) continue;
905b4d
 
905b4d
-            /* Untrusted users can access only public domains. */
905b4d
-            if (!pctx->is_uid_trusted &&
905b4d
-                !is_domain_public(dom->name, pctx->public_domains,
905b4d
-                                  pctx->public_domains_count)) {
905b4d
-                DEBUG(SSSDBG_MINOR_FAILURE,
905b4d
-                      "Untrusted user %"PRIu32" cannot access unpublic domain %s."
905b4d
-                      " Trying next domain.\n",
905b4d
-                      cctx->client_euid, dom->name);
905b4d
-                continue;
905b4d
-            }
905b4d
-
905b4d
-            /* skip this domain if not requested */
905b4d
-            if (!is_domain_requested(pd, dom->name)) {
905b4d
-                continue;
905b4d
-            }
905b4d
-
905b4d
             ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
905b4d
                                           dom, pd->user);
905b4d
             if (ncret == ENOENT) {
905b4d
@@ -959,7 +926,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
905b4d
                    "Trying next domain.\n", pd->user, dom->name);
905b4d
         }
905b4d
 
905b4d
-        if (!dom || !is_domain_requested(pd, dom->name)) {
905b4d
+        if (!dom) {
905b4d
             ret = ENOENT;
905b4d
             goto done;
905b4d
         }
905b4d
@@ -1055,14 +1022,9 @@ static int pam_check_user_search(struct pam_auth_req *preq)
905b4d
 
905b4d
     while (dom) {
905b4d
        /* if it is a domainless search, skip domains that require fully
905b4d
-        * qualified names instead, also untrusted users can access only
905b4d
-        * public domains */
905b4d
+        * qualified names instead */
905b4d
         while (dom && !preq->pd->domain && !preq->pd->name_is_upn
905b4d
-               && (dom->fqnames ||
905b4d
-                   (!pctx->is_uid_trusted &&
905b4d
-                    !is_domain_public(dom->name,
905b4d
-                                      pctx->public_domains,
905b4d
-                                      pctx->public_domains_count)))) {
905b4d
+               && dom->fqnames) {
905b4d
             dom = get_next_domain(dom, false);
905b4d
         }
905b4d
 
905b4d
@@ -1334,11 +1296,34 @@ done:
905b4d
 static void pam_dom_forwarder(struct pam_auth_req *preq)
905b4d
 {
905b4d
     int ret;
905b4d
+    struct pam_ctx *pctx =
905b4d
+            talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx);
905b4d
 
905b4d
     if (!preq->pd->domain) {
905b4d
         preq->pd->domain = preq->domain->name;
905b4d
     }
905b4d
 
905b4d
+    /* Untrusted users can access only public domains. */
905b4d
+    if (!pctx->is_uid_trusted &&
905b4d
+            !is_domain_public(preq->pd->domain, pctx->public_domains,
905b4d
+                            pctx->public_domains_count)) {
905b4d
+        DEBUG(SSSDBG_MINOR_FAILURE,
905b4d
+                "Untrusted user %"PRIu32" cannot access non-public domain %s.\n",
905b4d
+                preq->cctx->client_euid, preq->pd->domain);
905b4d
+        preq->pd->pam_status = PAM_PERM_DENIED;
905b4d
+        pam_reply(preq);
905b4d
+        return;
905b4d
+    }
905b4d
+
905b4d
+    /* skip this domain if not requested and the user is trusted
905b4d
+     * as untrusted users can't request a domain */
905b4d
+    if (pctx->is_uid_trusted &&
905b4d
+            !is_domain_requested(preq->pd, preq->pd->domain)) {
905b4d
+        preq->pd->pam_status = PAM_USER_UNKNOWN;
905b4d
+        pam_reply(preq);
905b4d
+        return;
905b4d
+    }
905b4d
+
905b4d
     if (!NEED_CHECK_PROVIDER(preq->domain->provider)) {
905b4d
         preq->callback = pam_reply;
905b4d
         ret = LOCAL_pam_handler(preq);
905b4d
-- 
905b4d
1.9.3
905b4d