Blame SOURCES/0135-pam-properly-support-UPN-logon-names.patch

ecf709
From b6ba8bc43a0b5a448e4cd30bc406bd08c389e365 Mon Sep 17 00:00:00 2001
ecf709
From: Sumit Bose <sbose@redhat.com>
ecf709
Date: Fri, 12 May 2017 10:40:21 +0200
ecf709
Subject: [PATCH 135/135] pam: properly support UPN logon names
ecf709
MIME-Version: 1.0
ecf709
Content-Type: text/plain; charset=UTF-8
ecf709
Content-Transfer-Encoding: 8bit
ecf709
ecf709
Many logon applications like /bin/login or sshd canonicalize the user
ecf709
name before they call pam_start() and hence the UPN is not seen by
ecf709
SSSD's pam responder. But some like e.g. gdm don't and authentication
ecf709
might fail if a UPN is used.
ecf709
ecf709
The reason is that currently the already parsed short name of the user
ecf709
was used in the cache_req and hence the cache_req was not able to fall
ecf709
back to the UPN lookup code. This patch uses the name originally
ecf709
provided by the user as input to allow the fallback to the UPN lookup.
ecf709
ecf709
Resolves https://pagure.io/SSSD/sssd/issue/3240
ecf709
ecf709
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
ecf709
(cherry picked from commit 29d063505c07127f7747405b1a61d8f782673645)
ecf709
---
ecf709
 src/responder/pam/pamsrv_cmd.c  |  4 +--
ecf709
 src/tests/cmocka/test_pam_srv.c | 79 ++++++++++++++++++++++++++++++++++++++++-
ecf709
 2 files changed, 80 insertions(+), 3 deletions(-)
ecf709
ecf709
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
ecf709
index 10a178f839ec011c09a6da4575efbb026f3f7700..36dba37964b71153435b4df5d5328de4361926e6 100644
ecf709
--- a/src/responder/pam/pamsrv_cmd.c
ecf709
+++ b/src/responder/pam/pamsrv_cmd.c
ecf709
@@ -1560,7 +1560,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
ecf709
 
ecf709
     data = cache_req_data_name(preq,
ecf709
                                CACHE_REQ_INITGROUPS,
ecf709
-                               preq->pd->user);
ecf709
+                               preq->pd->logon_name);
ecf709
     if (data == NULL) {
ecf709
         return ENOMEM;
ecf709
     }
ecf709
@@ -1589,7 +1589,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
ecf709
                            preq->cctx->rctx->ncache,
ecf709
                            0,
ecf709
                            preq->req_dom_type,
ecf709
-                           preq->pd->domain,
ecf709
+                           NULL,
ecf709
                            data);
ecf709
     if (!dpreq) {
ecf709
         DEBUG(SSSDBG_CRIT_FAILURE,
ecf709
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
ecf709
index d249b8f1ea48f1c17b461c3add9e8c63774e5f88..4d351a3707d2a49604595b728fff7705560c871a 100644
ecf709
--- a/src/tests/cmocka/test_pam_srv.c
ecf709
+++ b/src/tests/cmocka/test_pam_srv.c
ecf709
@@ -518,6 +518,8 @@ static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
ecf709
     int ret;
ecf709
     size_t needed_size;
ecf709
     uint8_t *authtok;
ecf709
+    char *s_name;
ecf709
+    char *dom;
ecf709
 
ecf709
     if (name != NULL) {
ecf709
         pi.pam_user = name;
ecf709
@@ -574,7 +576,13 @@ static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
ecf709
     will_return(__wrap_sss_packet_get_body, buf);
ecf709
     will_return(__wrap_sss_packet_get_body, buf_size);
ecf709
 
ecf709
-    mock_parse_inp(name, NULL, EOK);
ecf709
+    if (strrchr(name, '@') == NULL) {
ecf709
+        mock_parse_inp(name, NULL, EOK);
ecf709
+    } else {
ecf709
+        ret = sss_parse_internal_fqname(mem_ctx, name, &s_name, &dom;;
ecf709
+        mock_parse_inp(s_name, dom, EOK);
ecf709
+    }
ecf709
+
ecf709
     if (contact_dp) {
ecf709
         mock_account_recv_simple();
ecf709
     }
ecf709
@@ -1582,6 +1590,71 @@ void test_pam_preauth_no_logon_name(void **state)
ecf709
     assert_int_equal(ret, EOK);
ecf709
 }
ecf709
 
ecf709
+void test_pam_auth_no_upn_logon_name(void **state)
ecf709
+{
ecf709
+    int ret;
ecf709
+
ecf709
+    ret = sysdb_cache_password(pam_test_ctx->tctx->dom,
ecf709
+                               pam_test_ctx->pam_user_fqdn,
ecf709
+                               "12345");
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+
ecf709
+    mock_input_pam_ex(pam_test_ctx, "upn@"TEST_DOM_NAME, "12345", NULL, NULL,
ecf709
+                      true);
ecf709
+    mock_account_recv_simple();
ecf709
+
ecf709
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
ecf709
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
ecf709
+
ecf709
+    pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
ecf709
+    set_cmd_cb(test_pam_simple_check);
ecf709
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
ecf709
+                          pam_test_ctx->pam_cmds);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+
ecf709
+    /* Wait until the test finishes with EOK */
ecf709
+    ret = test_ev_loop(pam_test_ctx->tctx);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+}
ecf709
+
ecf709
+void test_pam_auth_upn_logon_name(void **state)
ecf709
+{
ecf709
+    int ret;
ecf709
+    struct sysdb_attrs *attrs;
ecf709
+
ecf709
+    ret = sysdb_cache_password(pam_test_ctx->tctx->dom,
ecf709
+                               pam_test_ctx->pam_user_fqdn,
ecf709
+                               "12345");
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+    attrs = sysdb_new_attrs(pam_test_ctx);
ecf709
+    assert_non_null(attrs);
ecf709
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upn@"TEST_DOM_NAME);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+
ecf709
+    ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom,
ecf709
+                              pam_test_ctx->pam_user_fqdn,
ecf709
+                              attrs,
ecf709
+                              LDB_FLAG_MOD_ADD);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+
ecf709
+    mock_input_pam_ex(pam_test_ctx, "upn@"TEST_DOM_NAME, "12345", NULL, NULL,
ecf709
+                      true);
ecf709
+    mock_account_recv_simple();
ecf709
+
ecf709
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
ecf709
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
ecf709
+
ecf709
+    set_cmd_cb(test_pam_successful_offline_auth_check);
ecf709
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
ecf709
+                          pam_test_ctx->pam_cmds);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+
ecf709
+    /* Wait until the test finishes with EOK */
ecf709
+    ret = test_ev_loop(pam_test_ctx->tctx);
ecf709
+    assert_int_equal(ret, EOK);
ecf709
+}
ecf709
+
ecf709
+
ecf709
 static void set_cert_auth_param(struct pam_ctx *pctx, const char *dbpath)
ecf709
 {
ecf709
     pam_test_ctx->pctx->cert_auth = true;
ecf709
@@ -2312,6 +2385,10 @@ int main(int argc, const char *argv[])
ecf709
                                         pam_test_setup, pam_test_teardown),
ecf709
         cmocka_unit_test_setup_teardown(test_pam_preauth_no_logon_name,
ecf709
                                         pam_test_setup, pam_test_teardown),
ecf709
+        cmocka_unit_test_setup_teardown(test_pam_auth_no_upn_logon_name,
ecf709
+                                        pam_test_setup, pam_test_teardown),
ecf709
+        cmocka_unit_test_setup_teardown(test_pam_auth_upn_logon_name,
ecf709
+                                        pam_test_setup, pam_test_teardown),
ecf709
         cmocka_unit_test_setup_teardown(test_pam_cached_auth_success,
ecf709
                                         pam_cached_test_setup,
ecf709
                                         pam_test_teardown),
ecf709
-- 
ecf709
2.9.3
ecf709