268 lines
10 KiB
Diff
268 lines
10 KiB
Diff
From 8173003ed876f1cc0831a838e20332b274b39c4f Mon Sep 17 00:00:00 2001
|
|
From: Sumit Bose <sbose@redhat.com>
|
|
Date: Wed, 31 Aug 2016 14:32:31 +0200
|
|
Subject: [PATCH 61/79] p11: only set PKCS11_LOGIN_TOKEN_NAME if gdm-smartcard
|
|
is used
|
|
|
|
Resolves https://fedorahosted.org/sssd/ticket/3165
|
|
|
|
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
(cherry picked from commit 71cd9f98150577224559bdc12c53c01ce6f2c3d9)
|
|
---
|
|
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 a2514f6a1d699de3a245063f49db1b7e51a2b10b..22da33067d5c479153376927855dcd6b43322d8b 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 5de092d0f19318d1d6c773355dbb38e345600133..02199e6f121cab0784389256cdaac38baf9d73e3 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,
|
|
--
|
|
2.9.3
|
|
|