dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0100-pam_sss-PAM_USER_UNKNOWN-if-socket-is-missing.patch

ecd8e1
From 0479c6f1598602909487c499266fe410085251a5 Mon Sep 17 00:00:00 2001
ecd8e1
From: Sumit Bose <sbose@redhat.com>
ecd8e1
Date: Mon, 25 Mar 2019 10:17:17 +0100
ecd8e1
Subject: [PATCH] pam_sss: PAM_USER_UNKNOWN if socket is missing
ecd8e1
ecd8e1
If SSSD used without explicit configuration in the files-only mode and
ecd8e1
pam_sss is also used in the PAM configuration, as e.g. in recent Fedora
ecd8e1
systems, users handled by other NSS modules might get an 'Access Denied'
ecd8e1
when trying to log in.
ecd8e1
ecd8e1
The culprit is the line like
ecd8e1
ecd8e1
    account     [default=bad success=ok user_unknown=ignore] pam_sss.so
ecd8e1
ecd8e1
in the PAM configuration which can only grant access if pam_sss.so
ecd8e1
returns PAM_SUCCESS or PAM_USER_UNKNOWN. Even PAM_IGNORE causes a
ecd8e1
rejection because of 'default=bad'.
ecd8e1
ecd8e1
Of the PAM responder is running PAM_USER_UNKNOWN is returned for users
ecd8e1
from other NSS modules. With this patch PAM_USER_UNKNOWN is returned as
ecd8e1
well during the 'account' step if the PAM responder socket is not
ecd8e1
available.
ecd8e1
ecd8e1
Related to https://pagure.io/SSSD/sssd/issue/3988
ecd8e1
ecd8e1
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
ecd8e1
---
ecd8e1
 src/man/pam_sss.8.xml    |  4 ++++
ecd8e1
 src/sss_client/common.c  | 18 ++++++++++++++++++
ecd8e1
 src/sss_client/pam_sss.c | 16 +++++++++++++---
ecd8e1
 src/sss_client/sss_cli.h |  2 ++
ecd8e1
 4 files changed, 37 insertions(+), 3 deletions(-)
ecd8e1
ecd8e1
diff --git a/src/man/pam_sss.8.xml b/src/man/pam_sss.8.xml
ecd8e1
index 86ed0fefe..834d9d268 100644
ecd8e1
--- a/src/man/pam_sss.8.xml
ecd8e1
+++ b/src/man/pam_sss.8.xml
ecd8e1
@@ -256,6 +256,10 @@ auth sufficient pam_sss.so allow_missing_name
ecd8e1
         <para>All module types (<option>account</option>, <option>auth</option>,
ecd8e1
         <option>password</option> and <option>session</option>) are provided.
ecd8e1
         </para>
ecd8e1
+        <para>If SSSD's PAM responder is not running, e.g. if the PAM responder
ecd8e1
+        socket is not available, pam_sss will return PAM_USER_UNKNOWN when
ecd8e1
+        called as <option>account</option> module to avoid issues with users
ecd8e1
+        from other sources during access control.</para>
ecd8e1
     </refsect1>
ecd8e1
 
ecd8e1
     <refsect1 id='files'>
ecd8e1
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
ecd8e1
index 224f33b55..e2d840540 100644
ecd8e1
--- a/src/sss_client/common.c
ecd8e1
+++ b/src/sss_client/common.c
ecd8e1
@@ -913,8 +913,14 @@ int sss_pam_make_request(enum sss_cli_command cmd,
ecd8e1
     /* only root shall use the privileged pipe */
ecd8e1
     if (getuid() == 0 && getgid() == 0) {
ecd8e1
         socket_name = SSS_PAM_PRIV_SOCKET_NAME;
ecd8e1
+        errno = 0;
ecd8e1
         statret = stat(socket_name, &stat_buf);
ecd8e1
         if (statret != 0) {
ecd8e1
+            if (errno == ENOENT) {
ecd8e1
+                *errnop = ESSS_NO_SOCKET;
ecd8e1
+            } else {
ecd8e1
+                *errnop = ESSS_SOCKET_STAT_ERROR;
ecd8e1
+            }
ecd8e1
             ret = PAM_SERVICE_ERR;
ecd8e1
             goto out;
ecd8e1
         }
ecd8e1
@@ -928,8 +934,14 @@ int sss_pam_make_request(enum sss_cli_command cmd,
ecd8e1
         }
ecd8e1
     } else {
ecd8e1
         socket_name = SSS_PAM_SOCKET_NAME;
ecd8e1
+        errno = 0;
ecd8e1
         statret = stat(socket_name, &stat_buf);
ecd8e1
         if (statret != 0) {
ecd8e1
+            if (errno == ENOENT) {
ecd8e1
+                *errnop = ESSS_NO_SOCKET;
ecd8e1
+            } else {
ecd8e1
+                *errnop = ESSS_SOCKET_STAT_ERROR;
ecd8e1
+            }
ecd8e1
             ret = PAM_SERVICE_ERR;
ecd8e1
             goto out;
ecd8e1
         }
ecd8e1
@@ -1075,6 +1087,12 @@ const char *ssscli_err2string(int err)
ecd8e1
         case ESSS_SERVER_NOT_TRUSTED:
ecd8e1
             return _("SSSD is not run by root.");
ecd8e1
             break;
ecd8e1
+        case ESSS_NO_SOCKET:
ecd8e1
+            return _("SSSD socket does not exist.");
ecd8e1
+            break;
ecd8e1
+        case ESSS_SOCKET_STAT_ERROR:
ecd8e1
+            return _("Cannot get stat of SSSD socket.");
ecd8e1
+            break;
ecd8e1
         default:
ecd8e1
             m = strerror(err);
ecd8e1
             if (m == NULL) {
ecd8e1
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
ecd8e1
index 69dc50dfd..9d51aefc6 100644
ecd8e1
--- a/src/sss_client/pam_sss.c
ecd8e1
+++ b/src/sss_client/pam_sss.c
ecd8e1
@@ -1304,10 +1304,20 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi,
ecd8e1
     }
ecd8e1
 
ecd8e1
     if (ret != PAM_SUCCESS) {
ecd8e1
-        if (errnop != 0) {
ecd8e1
-            logger(pamh, LOG_ERR, "Request to sssd failed. %s", ssscli_err2string(errnop));
ecd8e1
+        /* If there is no PAM responder socket during the access control step
ecd8e1
+         * we assume this is on purpose, i.e. PAM responder is not configured.
ecd8e1
+         * PAM_USER_UNKNOWN is returned to the PAM stack to avoid unexpected
ecd8e1
+         * denials. */
ecd8e1
+        if (errnop == ESSS_NO_SOCKET && task == SSS_PAM_ACCT_MGMT) {
ecd8e1
+            pam_status = PAM_USER_UNKNOWN;
ecd8e1
+        } else {
ecd8e1
+            if (errnop != 0 && errnop != ESSS_NO_SOCKET) {
ecd8e1
+                logger(pamh, LOG_ERR, "Request to sssd failed. %s",
ecd8e1
+                                      ssscli_err2string(errnop));
ecd8e1
+            }
ecd8e1
+
ecd8e1
+            pam_status = PAM_AUTHINFO_UNAVAIL;
ecd8e1
         }
ecd8e1
-        pam_status = PAM_AUTHINFO_UNAVAIL;
ecd8e1
         goto done;
ecd8e1
     }
ecd8e1
 
ecd8e1
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
ecd8e1
index af8a43916..31b4e50f7 100644
ecd8e1
--- a/src/sss_client/sss_cli.h
ecd8e1
+++ b/src/sss_client/sss_cli.h
ecd8e1
@@ -584,6 +584,8 @@ enum sss_cli_error_codes {
ecd8e1
     ESSS_BAD_PUB_SOCKET,
ecd8e1
     ESSS_BAD_CRED_MSG,
ecd8e1
     ESSS_SERVER_NOT_TRUSTED,
ecd8e1
+    ESSS_NO_SOCKET,
ecd8e1
+    ESSS_SOCKET_STAT_ERROR,
ecd8e1
 
ecd8e1
     ESS_SSS_CLI_ERROR_MAX
ecd8e1
 };
ecd8e1
-- 
ecd8e1
2.19.1
ecd8e1