summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2017-05-12 10:40:21 +0200
committerJakub Hrozek <jhrozek@redhat.com>2017-05-23 11:30:38 +0200
commit29d063505c07127f7747405b1a61d8f782673645 (patch)
tree40d96dbeb53d5a06dd2e1281a9c6fe28970fdac6
parentec9ac22d699a17d590b1d4ba9ba3750eb719f340 (diff)
downloadsssd-29d063505c07127f7747405b1a61d8f782673645.tar.gz
sssd-29d063505c07127f7747405b1a61d8f782673645.tar.xz
sssd-29d063505c07127f7747405b1a61d8f782673645.zip
pam: properly support UPN logon names
Many logon applications like /bin/login or sshd canonicalize the user name before they call pam_start() and hence the UPN is not seen by SSSD's pam responder. But some like e.g. gdm don't and authentication might fail if a UPN is used. The reason is that currently the already parsed short name of the user was used in the cache_req and hence the cache_req was not able to fall back to the UPN lookup code. This patch uses the name originally provided by the user as input to allow the fallback to the UPN lookup. Resolves https://pagure.io/SSSD/sssd/issue/3240 Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
-rw-r--r--src/responder/pam/pamsrv_cmd.c4
-rw-r--r--src/tests/cmocka/test_pam_srv.c79
2 files changed, 80 insertions, 3 deletions
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 10a178f83..36dba3796 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1560,7 +1560,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
data = cache_req_data_name(preq,
CACHE_REQ_INITGROUPS,
- preq->pd->user);
+ preq->pd->logon_name);
if (data == NULL) {
return ENOMEM;
}
@@ -1589,7 +1589,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
preq->cctx->rctx->ncache,
0,
preq->req_dom_type,
- preq->pd->domain,
+ NULL,
data);
if (!dpreq) {
DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index d249b8f1e..4d351a370 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -518,6 +518,8 @@ static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
int ret;
size_t needed_size;
uint8_t *authtok;
+ char *s_name;
+ char *dom;
if (name != NULL) {
pi.pam_user = name;
@@ -574,7 +576,13 @@ static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
will_return(__wrap_sss_packet_get_body, buf);
will_return(__wrap_sss_packet_get_body, buf_size);
- mock_parse_inp(name, NULL, EOK);
+ if (strrchr(name, '@') == NULL) {
+ mock_parse_inp(name, NULL, EOK);
+ } else {
+ ret = sss_parse_internal_fqname(mem_ctx, name, &s_name, &dom);
+ mock_parse_inp(s_name, dom, EOK);
+ }
+
if (contact_dp) {
mock_account_recv_simple();
}
@@ -1582,6 +1590,71 @@ void test_pam_preauth_no_logon_name(void **state)
assert_int_equal(ret, EOK);
}
+void test_pam_auth_no_upn_logon_name(void **state)
+{
+ int ret;
+
+ ret = sysdb_cache_password(pam_test_ctx->tctx->dom,
+ pam_test_ctx->pam_user_fqdn,
+ "12345");
+ assert_int_equal(ret, EOK);
+
+ mock_input_pam_ex(pam_test_ctx, "upn@"TEST_DOM_NAME, "12345", NULL, NULL,
+ true);
+ mock_account_recv_simple();
+
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
+ set_cmd_cb(test_pam_simple_check);
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+ 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_auth_upn_logon_name(void **state)
+{
+ int ret;
+ struct sysdb_attrs *attrs;
+
+ ret = sysdb_cache_password(pam_test_ctx->tctx->dom,
+ pam_test_ctx->pam_user_fqdn,
+ "12345");
+ assert_int_equal(ret, EOK);
+ attrs = sysdb_new_attrs(pam_test_ctx);
+ assert_non_null(attrs);
+ ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upn@"TEST_DOM_NAME);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom,
+ pam_test_ctx->pam_user_fqdn,
+ attrs,
+ LDB_FLAG_MOD_ADD);
+ assert_int_equal(ret, EOK);
+
+ mock_input_pam_ex(pam_test_ctx, "upn@"TEST_DOM_NAME, "12345", NULL, NULL,
+ true);
+ mock_account_recv_simple();
+
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ set_cmd_cb(test_pam_successful_offline_auth_check);
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+ 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);
+}
+
+
static void set_cert_auth_param(struct pam_ctx *pctx, const char *dbpath)
{
pam_test_ctx->pctx->cert_auth = true;
@@ -2312,6 +2385,10 @@ int main(int argc, const char *argv[])
pam_test_setup, pam_test_teardown),
cmocka_unit_test_setup_teardown(test_pam_preauth_no_logon_name,
pam_test_setup, pam_test_teardown),
+ cmocka_unit_test_setup_teardown(test_pam_auth_no_upn_logon_name,
+ pam_test_setup, pam_test_teardown),
+ cmocka_unit_test_setup_teardown(test_pam_auth_upn_logon_name,
+ pam_test_setup, pam_test_teardown),
cmocka_unit_test_setup_teardown(test_pam_cached_auth_success,
pam_cached_test_setup,
pam_test_teardown),