slurm/pam_slurm_adopt-avoid-running-outside-of-the-sshd-PA.patch

138 lines
4.7 KiB
Diff
Raw Normal View History

From 9f13f7450cb38ac099d2887ab42f588f9dd35306 Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <matthias.gerstner@suse.de>
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=<service> allows an Administrator to control
this behaviour, if different behaviour is explicitly desired.
Signed-off-by: Christian Goll <cgoll@suse.de>
---
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