From b66f0e44816bf858b3085b5538e2f8f50d9e8ae7 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: May 19 2020 09:16:16 +0000 Subject: pam: add option pam_initgroups_scheme This new option should be used to tell the PAM responder to refresh the user's group memberships either with every new PAM session or always rely on cached data or refresh the data only if the user currently has no active login session. Resolves: https://pagure.io/SSSD/sssd/issue/4098 Reviewed-by: Pavel Březina --- diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index ee90250..0a55932 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -138,6 +138,7 @@ #define CONFDB_PAM_APP_SERVICES "pam_app_services" #define CONFDB_PAM_P11_ALLOWED_SERVICES "pam_p11_allowed_services" #define CONFDB_PAM_P11_URI "p11_uri" +#define CONFDB_PAM_INITGROUPS_SCHEME "pam_initgroups_scheme" /* SUDO */ #define CONFDB_SUDO_CONF_ENTRY "config/sudo" diff --git a/src/config/SSSDConfig/sssdoptions.py b/src/config/SSSDConfig/sssdoptions.py index 631b73b..734456c 100644 --- a/src/config/SSSDConfig/sssdoptions.py +++ b/src/config/SSSDConfig/sssdoptions.py @@ -100,6 +100,7 @@ class SSSDOptions(object): 'pam_p11_allowed_services': _('Allowed services for using smartcards'), 'p11_wait_for_card_timeout': _('Additional timeout to wait for a card if requested'), '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'), # [sudo] 'sudo_timed': _('Whether to evaluate the time-based attributes in sudo rules'), diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index f46619b..2ad1fc4 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -131,6 +131,7 @@ option = pam_app_services option = pam_p11_allowed_services option = p11_wait_for_card_timeout option = p11_uri +option = pam_initgroups_scheme [rule/allowed_sudo_options] validator = ini_allowed_options diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index 046721b..6e5d118 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -79,6 +79,7 @@ pam_app_services = str, None, false pam_p11_allowed_services = str, None, false p11_wait_for_card_timeout = int, None, false p11_uri = str, None, false +pam_initgroups_scheme = str, None, false [sudo] # sudo service diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 7c552be..320329a 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -1617,6 +1617,38 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2 + + pam_initgroups_scheme + + + The PAM responder can force an online lookup to get + the current group memberships of the user trying to + log in. This option controls when this should be + done and the following values are allowed: + + always + Always do an online lookup, + please note that pam_id_timeout still + applies + + no_session + Only do an online + lookup if there is no active session of the + user, i.e. if the user is currently not logged + in + + never + Never force an online lookup, + use the data from the cache as long as they are + not expired + + + + + Default: no_session + + + diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c index 4f5b9b6..2d787f6 100644 --- a/src/responder/pam/pamsrv.c +++ b/src/responder/pam/pamsrv.c @@ -54,6 +54,7 @@ #else #define DEFAULT_PAM_CERT_DB_PATH SYSCONFDIR"/sssd/pki/sssd_auth_ca_db.pem" #endif +#define DEFAULT_PAM_INITGROUPS_SCHEME "no_session" static errno_t get_trusted_uids(struct pam_ctx *pctx) { @@ -168,6 +169,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx, int ret; int id_timeout; int fd_limit; + char *tmpstr = NULL; pam_cmds = get_pam_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, @@ -307,6 +309,29 @@ static int pam_process_init(TALLOC_CTX *mem_ctx, } } + ret = confdb_get_string(pctx->rctx->cdb, pctx, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_INITGROUPS_SCHEME, + DEFAULT_PAM_INITGROUPS_SCHEME, &tmpstr); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to determine initgroups scheme.\n"); + goto done; + } + DEBUG(SSSDBG_TRACE_INTERNAL, "Found value [%s] for option [%s].\n", tmpstr, + CONFDB_PAM_INITGROUPS_SCHEME); + + if (tmpstr == NULL) { + pctx->initgroups_scheme = PAM_INITGR_NO_SESSION; + } else { + pctx->initgroups_scheme = pam_initgroups_string_to_enum(tmpstr); + if (pctx->initgroups_scheme == PAM_INITGR_INVALID) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unknown value [%s] for option %s.\n", + tmpstr, CONFDB_PAM_INITGROUPS_SCHEME); + ret = EINVAL; + 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 99c6e10..24bd976 100644 --- a/src/responder/pam/pamsrv.h +++ b/src/responder/pam/pamsrv.h @@ -32,6 +32,13 @@ struct pam_auth_req; typedef void (pam_dp_callback_t)(struct pam_auth_req *preq); +enum pam_initgroups_scheme { + PAM_INITGR_NEVER, + PAM_INITGR_NO_SESSION, + PAM_INITGR_ALWAYS, + PAM_INITGR_INVALID +}; + struct pam_ctx { struct resp_ctx *rctx; time_t id_timeout; @@ -54,6 +61,8 @@ struct pam_ctx { char **prompting_config_sections; int num_prompting_config_sections; + + enum pam_initgroups_scheme initgroups_scheme; }; struct pam_auth_req { @@ -132,4 +141,6 @@ errno_t filter_responses(struct confdb_ctx *cdb, errno_t pam_eval_prompting_config(struct pam_ctx *pctx, struct pam_data *pd); +enum pam_initgroups_scheme pam_initgroups_string_to_enum(const char *str); +const char *pam_initgroup_enum_to_string(enum pam_initgroups_scheme scheme); #endif /* __PAMSRV_H__ */ diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 4430f0f..f1d2340 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -43,6 +43,44 @@ enum pam_verbosity { #define DEFAULT_PAM_VERBOSITY PAM_VERBOSITY_IMPORTANT +struct pam_initgroup_enum_str { + enum pam_initgroups_scheme scheme; + const char *option; +}; + +struct pam_initgroup_enum_str pam_initgroup_enum_str[] = { + { PAM_INITGR_NEVER, "never" }, + { PAM_INITGR_NO_SESSION, "no_session" }, + { PAM_INITGR_ALWAYS, "always" }, + { PAM_INITGR_INVALID, NULL } +}; + +enum pam_initgroups_scheme pam_initgroups_string_to_enum(const char *str) +{ + size_t c; + + for (c = 0 ; pam_initgroup_enum_str[c].option != NULL; c++) { + if (strcasecmp(pam_initgroup_enum_str[c].option, str) == 0) { + return pam_initgroup_enum_str[c].scheme; + } + } + + return PAM_INITGR_INVALID; +} + +const char *pam_initgroup_enum_to_string(enum pam_initgroups_scheme scheme) { + size_t c; + + for (c = 0 ; pam_initgroup_enum_str[c].option != NULL; c++) { + if (pam_initgroup_enum_str[c].scheme == scheme) { + return pam_initgroup_enum_str[c].option; + } + } + + return NULL; +} + + static errno_t pam_null_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *username);