From fffe3169bb490c4b010b168c639aa6f9b2ec0c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Thu, 10 Dec 2020 22:05:30 +0100 Subject: [PATCH] pam: add pam_gssapi_check_upn option :config: Added `pam_gssapi_check_upn` to enforce authentication only with principal that can be associated with target user. Reviewed-by: Robbie Harwood Reviewed-by: Sumit Bose --- src/confdb/confdb.c | 10 ++++++++++ src/confdb/confdb.h | 2 ++ src/config/SSSDConfig/sssdoptions.py | 1 + src/config/SSSDConfigTest.py | 6 ++++-- src/config/cfg_rules.ini | 3 +++ src/config/etc/sssd.api.conf | 2 ++ src/db/sysdb_subdomains.c | 12 ++++++++++++ src/man/sssd.conf.5.xml | 26 ++++++++++++++++++++++++++ src/responder/pam/pamsrv.c | 9 +++++++++ src/responder/pam/pamsrv.h | 1 + 10 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c index 7f1956d6d9..2881ce5da7 100644 --- a/src/confdb/confdb.c +++ b/src/confdb/confdb.c @@ -1593,6 +1593,16 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, } } + tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_PAM_GSSAPI_CHECK_UPN, + NULL); + if (tmp != NULL) { + domain->gssapi_check_upn = talloc_strdup(domain, tmp); + if (domain->gssapi_check_upn == NULL) { + ret = ENOMEM; + goto done; + } + } + domain->has_views = false; domain->view_name = NULL; diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 7a3bc8bb50..036f9ecadf 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -145,6 +145,7 @@ #define CONFDB_PAM_P11_URI "p11_uri" #define CONFDB_PAM_INITGROUPS_SCHEME "pam_initgroups_scheme" #define CONFDB_PAM_GSSAPI_SERVICES "pam_gssapi_services" +#define CONFDB_PAM_GSSAPI_CHECK_UPN "pam_gssapi_check_upn" /* SUDO */ #define CONFDB_SUDO_CONF_ENTRY "config/sudo" @@ -435,6 +436,7 @@ struct sss_domain_info { /* List of PAM services that are allowed to authenticate with GSSAPI. */ char **gssapi_services; + char *gssapi_check_upn; /* true | false | NULL */ }; /** diff --git a/src/config/SSSDConfig/sssdoptions.py b/src/config/SSSDConfig/sssdoptions.py index f59fe8d9f2..5da52a9379 100644 --- a/src/config/SSSDConfig/sssdoptions.py +++ b/src/config/SSSDConfig/sssdoptions.py @@ -105,6 +105,7 @@ def __init__(self): 'p11_uri': _('PKCS#11 URI to restrict the selection of devices for Smartcard authentication'), 'pam_initgroups_scheme' : _('When shall the PAM responder force an initgroups request'), 'pam_gssapi_services' : _('List of PAM services that are allowed to authenticate with GSSAPI.'), + 'pam_gssapi_check_upn' : _('Whether to match authenticated UPN with target user'), # [sudo] 'sudo_timed': _('Whether to evaluate the time-based attributes in sudo rules'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 21fffe1b6b..ea4e4f6c98 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -654,7 +654,8 @@ def testListOptions(self): 're_expression', 'cached_auth_timeout', 'auto_private_groups', - 'pam_gssapi_services'] + 'pam_gssapi_services', + 'pam_gssapi_check_upn'] self.assertTrue(type(options) == dict, "Options should be a dictionary") @@ -1032,7 +1033,8 @@ def testRemoveProvider(self): 're_expression', 'cached_auth_timeout', 'auto_private_groups', - 'pam_gssapi_services'] + 'pam_gssapi_services', + 'pam_gssapi_check_upn'] self.assertTrue(type(options) == dict, "Options should be a dictionary") diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index c6dfd56483..6642c63213 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -140,6 +140,7 @@ option = p11_wait_for_card_timeout option = p11_uri option = pam_initgroups_scheme option = pam_gssapi_services +option = pam_gssapi_check_upn [rule/allowed_sudo_options] validator = ini_allowed_options @@ -439,6 +440,7 @@ option = full_name_format option = re_expression option = auto_private_groups option = pam_gssapi_services +option = pam_gssapi_check_upn #Entry cache timeouts option = entry_cache_user_timeout @@ -834,6 +836,7 @@ option = ad_site option = use_fully_qualified_names option = auto_private_groups option = pam_gssapi_services +option = pam_gssapi_check_upn [rule/sssd_checks] validator = sssd_checks diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index f46f3c46d2..d3cad73809 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -81,6 +81,7 @@ p11_wait_for_card_timeout = int, None, false p11_uri = str, None, false pam_initgroups_scheme = str, None, false pam_gssapi_services = str, None, false +pam_gssapi_check_upn = bool, None, false [sudo] # sudo service @@ -201,6 +202,7 @@ full_name_format = str, None, false re_expression = str, None, false auto_private_groups = str, None, false pam_gssapi_services = str, None, false +pam_gssapi_check_upn = bool, None, false #Entry cache timeouts entry_cache_user_timeout = int, None, false diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index bfc6df0f5f..03ba121646 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -254,6 +254,18 @@ check_subdom_config_file(struct confdb_ctx *confdb, goto done; } + /* allow to set pam_gssapi_check_upn */ + ret = confdb_get_string(confdb, subdomain, sd_conf_path, + CONFDB_PAM_GSSAPI_CHECK_UPN, + subdomain->parent->gssapi_check_upn, + &subdomain->gssapi_check_upn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to get %s option for the subdomain: %s\n", + CONFDB_PAM_GSSAPI_CHECK_UPN, subdomain->name); + goto done; + } + ret = EOK; done: talloc_free(tmp_ctx); diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index db9dd46773..d637e2eaac 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -1735,6 +1735,31 @@ pam_gssapi_services = sudo, sudo-i + + pam_gssapi_check_upn + + + If True, SSSD will require that the Kerberos user + principal that successfully authenticated through + GSSAPI can be associated with the user who is being + authenticated. Authentication will fail if the check + fails. + + + If False, every user that is able to obtained + required service ticket will be authenticated. + + + Note: This option can also be set per-domain which + overwrites the value in [pam] section. It can also + be set for trusted domain which overwrites the value + in the domain section. + + + Default: True + + + @@ -3810,6 +3835,7 @@ ldap_user_extra_attrs = phone:telephoneNumber ad_site, use_fully_qualified_names pam_gssapi_services + pam_gssapi_check_upn For more details about these options see their individual description in the manual page. diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c index 0492569c7f..0db2824ff0 100644 --- a/src/responder/pam/pamsrv.c +++ b/src/responder/pam/pamsrv.c @@ -348,6 +348,15 @@ static int pam_process_init(TALLOC_CTX *mem_ctx, } } + ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_GSSAPI_CHECK_UPN, true, + &pctx->gssapi_check_upn); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read %s [%d]: %s\n", + CONFDB_PAM_GSSAPI_CHECK_UPN, ret, sss_strerror(ret)); + goto done; + } + /* The responder is initialized. Now tell it to the monitor. */ ret = sss_monitor_service_init(rctx, rctx->ev, SSS_BUS_PAM, SSS_PAM_SBUS_SERVICE_NAME, diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h index 730dee2881..bf4dd75b04 100644 --- a/src/responder/pam/pamsrv.h +++ b/src/responder/pam/pamsrv.h @@ -65,6 +65,7 @@ struct pam_ctx { /* List of PAM services that are allowed to authenticate with GSSAPI. */ char **gssapi_services; + bool gssapi_check_upn; }; struct pam_auth_req {