138 lines
4.7 KiB
Diff
138 lines
4.7 KiB
Diff
|
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
|
||
|
|