From 9f13f7450cb38ac099d2887ab42f588f9dd35306 Mon Sep 17 00:00:00 2001 From: Matthias Gerstner Date: Wed, 5 Dec 2018 15:03:19 +0100 Subject: [PATCH 1/3] pam_slurm_adopt: avoid running outside of the sshd PAM service context This pam module is tailored towards running in the context of remote ssh logins. When running in a different context like a local sudo call then the module could be influenced by e.g. passing environment variables like SLURM_CONF. By limiting the module to only perform its actions when running in the sshd context by default this situation can be avoided. An additional pam module argument service= allows an Administrator to control this behaviour, if different behaviour is explicitly desired. Signed-off-by: Christian Goll --- contribs/pam_slurm_adopt/README | 9 ++++++ contribs/pam_slurm_adopt/pam_slurm_adopt.c | 46 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/contribs/pam_slurm_adopt/README b/contribs/pam_slurm_adopt/README index a84480c1a6..a2d61a977b 100644 --- a/contribs/pam_slurm_adopt/README +++ b/contribs/pam_slurm_adopt/README @@ -97,6 +97,15 @@ This module has the following options (* = default): 0* = If the step the job is adopted into has X11 enabled, set the DISPLAY variable in the processes environment accordingly. + service - The pam service name for which this module should run. By default + it only runs for sshd for which it was designed for. A + different service name can be specified like "login" or "*" to + allow the module to in any service context. For local pam logins + this module could cause unexpected behaviour or even security + issues. Therefore if the service name does not match then this + module will not perform the adoption logic and returns + PAM_IGNORE immediately. + SLURM.CONF CONFIGURATION PrologFlags=contain must be set in slurm.conf. This sets up the "extern" step into which ssh-launched processes will be adopted. diff --git a/contribs/pam_slurm_adopt/pam_slurm_adopt.c b/contribs/pam_slurm_adopt/pam_slurm_adopt.c index 3f23c2ec77..da21479f61 100644 --- a/contribs/pam_slurm_adopt/pam_slurm_adopt.c +++ b/contribs/pam_slurm_adopt/pam_slurm_adopt.c @@ -94,6 +94,7 @@ static struct { log_level_t log_level; char *node_name; bool disable_x11; + char *pam_service; } opts; static void _init_opts(void) @@ -107,6 +108,7 @@ static void _init_opts(void) opts.log_level = LOG_LEVEL_INFO; opts.node_name = NULL; opts.disable_x11 = false; + opts.pam_service = NULL; } static slurm_cgroup_conf_t *slurm_cgroup_conf = NULL; @@ -576,6 +578,9 @@ static void _parse_opts(pam_handle_t *pamh, int argc, const char **argv) opts.node_name = xstrdup(v); } else if (!xstrncasecmp(*argv, "disable_x11=1", 13)) { opts.disable_x11 = true; + } else if (!xstrncasecmp(*argv, "service=", 8)) { + v = (char *)(8 + *argv); + opts.pam_service = xstrdup(v); } } @@ -601,6 +606,40 @@ static int _load_cgroup_config() return SLURM_SUCCESS; } +/* Make sure to only continue if we're running in the sshd context + * + * If this module is used locally e.g. via sudo then unexpected things might + * happen (e.g. passing environment variables interpreted by slurm code like + * SLURM_CONF or inheriting file descriptors that are used by _try_rpc()). + */ +static int check_pam_service(pam_handle_t *pamh) +{ + const char *allowed = opts.pam_service ? opts.pam_service : "sshd"; + char *service = NULL; + int rc; + + if (!strcmp(allowed, "*")) + // any service name is allowed + return PAM_SUCCESS; + + rc = pam_get_item(pamh, PAM_SERVICE, (void*)&service); + + if (rc != PAM_SUCCESS) { + pam_syslog(pamh, LOG_ERR, "failed to obtain PAM_SERVICE name"); + return rc; + } + else if (service == NULL) { + // this shouldn't actually happen + return PAM_BAD_ITEM; + } + + if (!strcmp(service, allowed)) { + return PAM_SUCCESS; + } + + pam_syslog(pamh, LOG_INFO, "Not adopting process since this is not an allowed pam service"); + return PAM_IGNORE; +} /* Parse arguments, etc then get my socket address/port information. Attempt to * adopt this process into a job in the following order: @@ -622,6 +661,12 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags _init_opts(); _parse_opts(pamh, argc, argv); + + retval = check_pam_service(pamh); + if (retval != PAM_SUCCESS) { + return retval; + } + _log_init(opts.log_level); switch (opts.action_generic_failure) { @@ -762,6 +807,7 @@ cleanup: xfree(buf); xfree(slurm_cgroup_conf); xfree(opts.node_name); + xfree(opts.pam_service); return rc; } -- 2.16.4