sumit-bose's pull request #17: "Improve support for gdm Smartcard support" was 
opened

PR body:
"""
Those two patches try to fix two issues related to the Smartcard handling
feature of gdm. The first fixes https://fedorahosted.org/sssd/ticket/3165 and
the second fixes an issue which was introduced by the sysdb refactoring.
"""

See the full pull-request at https://github.com/SSSD/sssd/pull/17
... or pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/17/head:pr17
git checkout pr17
From 905e3ef9a3fcd4b75e87435a3d37303d100739f5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 31 Aug 2016 14:32:31 +0200
Subject: [PATCH 1/2] p11: only set PKCS11_LOGIN_TOKEN_NAME if gdm-smartcard is
 used

Resolves https://fedorahosted.org/sssd/ticket/3165
---
 src/responder/pam/pamsrv_p11.c  | 33 +++++++++------
 src/tests/cmocka/test_pam_srv.c | 89 +++++++++++++++++++++++++++++++++++------
 2 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index a2514f6..22da330 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -505,7 +505,11 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 }
 
 /* The PKCS11_LOGIN_TOKEN_NAME environment variable is e.g. used by the Gnome
- * Settings Daemon to determine the name of the token used for login */
+ * Settings Daemon to determine the name of the token used for login but it
+ * should be only set if SSSD is called by gdm-smartcard. Otherwise desktop
+ * components might assume that gdm-smartcard PAM stack is configured
+ * correctly which might not be the case e.g. if Smartcard authentication was
+ * used when running gdm-password. */
 #define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME"
 
 errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
@@ -553,19 +557,22 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
         return ret;
     }
 
-    env = talloc_asprintf(pd, "%s=%s", PKCS11_LOGIN_TOKEN_ENV_NAME, token_name);
-    if (env == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
-        return ENOMEM;
-    }
+    if (strcmp(pd->service, "gdm-smartcard") == 0) {
+        env = talloc_asprintf(pd, "%s=%s", PKCS11_LOGIN_TOKEN_ENV_NAME,
+                              token_name);
+        if (env == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+            return ENOMEM;
+        }
 
-    ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env) + 1,
-                           (uint8_t *)env);
-    talloc_free(env);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE,
-              "pam_add_response failed to add environment variable.\n");
-        return ret;
+        ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env) + 1,
+                               (uint8_t *)env);
+        talloc_free(env);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  "pam_add_response failed to add environment variable.\n");
+            return ret;
+        }
     }
 
     return ret;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 5de092d..02199e6 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -554,7 +554,7 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
 }
 
 static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
-                                const char *pin)
+                                const char *pin, const char *service)
 {
     size_t buf_size;
     uint8_t *m_buf;
@@ -576,7 +576,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
         pi.pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN;
     }
 
-    pi.pam_service = "login";
+    pi.pam_service = service == NULL ? "login" : service;
     pi.pam_service_size = strlen(pi.pam_service) + 1;
     pi.pam_tty = "/dev/tty";
     pi.pam_tty_size = strlen(pi.pam_tty) + 1;
@@ -626,7 +626,8 @@ static int test_pam_simple_check(uint32_t status, uint8_t *body, size_t blen)
 
 #define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME"
 
-static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
+static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
+                                             size_t blen)
 {
     size_t rp = 0;
     uint32_t val;
@@ -675,6 +676,44 @@ static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
     return EOK;
 }
 
+static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
+{
+    size_t rp = 0;
+    uint32_t val;
+
+    assert_int_equal(status, 0);
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, pam_test_ctx->exp_pam_status);
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, 2);
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, SSS_PAM_DOMAIN_NAME);
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, 9);
+
+    assert_int_equal(*(body + rp + val - 1), 0);
+    assert_string_equal(body + rp, TEST_DOM_NAME);
+    rp += val;
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, SSS_PAM_CERT_INFO);
+
+    SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+    assert_int_equal(val, (sizeof("pamuser") + sizeof(TEST_TOKEN_NAME)));
+
+    assert_int_equal(*(body + rp + sizeof("pamuser") - 1), 0);
+    assert_string_equal(body + rp, "pamuser");
+    rp += sizeof("pamuser");
+
+    assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0);
+    assert_string_equal(body + rp, TEST_TOKEN_NAME);
+
+    return EOK;
+}
 
 static int test_pam_offline_chauthtok_check(uint32_t status,
                                             uint8_t *body, size_t blen)
@@ -1438,7 +1477,7 @@ void test_pam_preauth_no_logon_name(void **state)
 {
     int ret;
 
-    mock_input_pam_cert(pam_test_ctx, NULL, NULL);
+    mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1465,7 +1504,7 @@ void test_pam_preauth_cert_nocert(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
 
-    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL);
+    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1544,7 +1583,7 @@ void test_pam_preauth_cert_nomatch(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL);
+    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1566,7 +1605,7 @@ void test_pam_preauth_cert_match(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL);
+    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1583,13 +1622,37 @@ void test_pam_preauth_cert_match(void **state)
     assert_int_equal(ret, EOK);
 }
 
+/* Test if PKCS11_LOGIN_TOKEN_NAME is added for the gdm-smartcard service */
+void test_pam_preauth_cert_match_gdm_smartcard(void **state)
+{
+    int ret;
+
+    set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
+
+    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, "gdm-smartcard");
+
+    will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
+    will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+    mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb,
+                      discard_const(TEST_TOKEN_CERT));
+
+    set_cmd_cb(test_pam_cert_check_gdm_smartcard);
+    ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH,
+                          pam_test_ctx->pam_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(pam_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
 void test_pam_preauth_cert_match_wrong_user(void **state)
 {
     int ret;
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL);
+    mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1613,7 +1676,7 @@ void test_pam_preauth_cert_no_logon_name(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, NULL, NULL);
+    mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1636,7 +1699,7 @@ void test_pam_preauth_no_cert_no_logon_name(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
 
-    mock_input_pam_cert(pam_test_ctx, NULL, NULL);
+    mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1657,7 +1720,7 @@ void test_pam_preauth_cert_no_logon_name_no_match(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, NULL, NULL);
+    mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1679,7 +1742,7 @@ void test_pam_cert_auth(void **state)
 
     set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
 
-    mock_input_pam_cert(pam_test_ctx, "pamuser", "123456");
+    mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL);
 
     will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
     will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1790,6 +1853,8 @@ int main(int argc, const char *argv[])
                                         pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_preauth_cert_match,
                                         pam_test_setup, pam_test_teardown),
+        cmocka_unit_test_setup_teardown(test_pam_preauth_cert_match_gdm_smartcard,
+                                        pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_preauth_cert_match_wrong_user,
                                         pam_test_setup, pam_test_teardown),
         cmocka_unit_test_setup_teardown(test_pam_preauth_cert_no_logon_name,

From 0f1801b56e97ada0f949c4fe29afcc8bcb2713ad Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Thu, 1 Sep 2016 12:40:27 +0200
Subject: [PATCH 2/2] p11: return a fully-qualified name

Related to https://fedorahosted.org/sssd/ticket/3165
---
 src/responder/pam/pamsrv_p11.c  | 20 +++++++++-----------
 src/tests/cmocka/test_pam_srv.c | 16 ++++++++--------
 2 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 22da330..570bfe0 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -521,33 +521,31 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
     size_t msg_len;
     size_t slot_len;
     int ret;
-    char *username;
 
     if (sysdb_username == NULL || token_name == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Missing mandatory user or slot name.\n");
         return EINVAL;
     }
 
-    ret = sss_parse_internal_fqname(pd, sysdb_username, &username, NULL);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse [%s]\n", sysdb_username);
-        return ret;
-    }
-
-    user_len = strlen(username) + 1;
+    user_len = strlen(sysdb_username) + 1;
     slot_len = strlen(token_name) + 1;
     msg_len = user_len + slot_len;
 
     msg = talloc_zero_size(pd, msg_len);
     if (msg == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
-        talloc_free(username);
         return ENOMEM;
     }
 
-    memcpy(msg, username, user_len);
+    /* sysdb_username is a fully-qualified name which is used by pam_sss when
+     * prompting the user for the PIN and as login name if it wasn't set by
+     * the PAM caller but has to be determined based on the inserted
+     * Smartcard. If this type of name is irritating at the PIN prompt or the
+     * re_expression config option was set in a way that user@domain cannot be
+     * handled anymore some more logic has to be added here. But for the time
+     * being I think using sysdb_username is fine. */
+    memcpy(msg, sysdb_username, user_len);
     memcpy(msg + user_len, token_name, slot_len);
-    talloc_free(username);
 
     ret = pam_add_response(pd, SSS_PAM_CERT_INFO, msg_len, msg);
     talloc_free(msg);
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 02199e6..4b2dea4 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -664,11 +664,11 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
     assert_int_equal(val, SSS_PAM_CERT_INFO);
 
     SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
-    assert_int_equal(val, (sizeof("pamuser") + sizeof(TEST_TOKEN_NAME)));
+    assert_int_equal(val, (sizeof("pamuser@"TEST_DOM_NAME) + sizeof(TEST_TOKEN_NAME)));
 
-    assert_int_equal(*(body + rp + sizeof("pamuser") - 1), 0);
-    assert_string_equal(body + rp, "pamuser");
-    rp += sizeof("pamuser");
+    assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0);
+    assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME);
+    rp += sizeof("pamuser@"TEST_DOM_NAME);
 
     assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0);
     assert_string_equal(body + rp, TEST_TOKEN_NAME);
@@ -703,11 +703,11 @@ static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
     assert_int_equal(val, SSS_PAM_CERT_INFO);
 
     SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
-    assert_int_equal(val, (sizeof("pamuser") + sizeof(TEST_TOKEN_NAME)));
+    assert_int_equal(val, (sizeof("pamuser@"TEST_DOM_NAME) + sizeof(TEST_TOKEN_NAME)));
 
-    assert_int_equal(*(body + rp + sizeof("pamuser") - 1), 0);
-    assert_string_equal(body + rp, "pamuser");
-    rp += sizeof("pamuser");
+    assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0);
+    assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME);
+    rp += sizeof("pamuser@"TEST_DOM_NAME);
 
     assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0);
     assert_string_equal(body + rp, TEST_TOKEN_NAME);
_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org

Reply via email to