From 764ae4dd51dc343600415b0b8fef33f546ee4946 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 May 2020 12:38:05 +0200 Subject: [PATCH] man_systemd_home: intrdouce SYSTEMD_HOME_SUSPEND env var This variable is read by the module and can be used instead of the suspend= PAM module parameter. It is also set for the session itself to make debugging easy. --- man/pam_systemd_home.xml | 16 +++++++++++++- src/home/pam_systemd_home.c | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/man/pam_systemd_home.xml b/man/pam_systemd_home.xml index e0e24e5888..ab02f98337 100644 --- a/man/pam_systemd_home.xml +++ b/man/pam_systemd_home.xml @@ -73,7 +73,12 @@ the re-authentication must take place from a component running outside of the user's context, so that it does not require access to the user's home directory for operation. Traditionally, most desktop environments do not implement screen locking this way, and need to be updated - accordingly. + accordingly. + + This setting may also be controlled via the $SYSTEMD_HOME_SUSPEND + environment variable (see below), which pam_systemd_home reads during initialization and sets + for sessions. If both the environment variable is set and the module parameter specified the latter + takes precedence. @@ -105,6 +110,15 @@ Indicates that the user's home directory is managed by systemd-homed.service. + + $SYSTEMD_HOME_SUSPEND= + + Indicates whether the session has been registered with the suspend mechanism enabled + or disabled (see above). The variable's value is either 0 or + 1. Note that the module both reads the variable when initializing, and sets it for + sessions. + + diff --git a/src/home/pam_systemd_home.c b/src/home/pam_systemd_home.c index 72ce062f54..baa3586bf7 100644 --- a/src/home/pam_systemd_home.c +++ b/src/home/pam_systemd_home.c @@ -60,6 +60,35 @@ static int parse_argv( return 0; } +static int parse_env( + pam_handle_t *handle, + bool *please_suspend) { + + const char *v; + int r; + + /* Let's read the suspend setting from an env var in addition to the PAM command line. That makes it + * easy to declare the features of a display manager in code rather than configuration, and this is + * really a feature of code */ + + v = pam_getenv(handle, "SYSTEMD_HOME_SUSPEND"); + if (!v) { + /* Also check the process env block, so that people can control this via an env var from the + * outside of our process. */ + v = secure_getenv("SYSTEMD_HOME_SUSPEND"); + if (!v) + return 0; + } + + r = parse_boolean(v); + if (r < 0) + pam_syslog(handle, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v); + else if (please_suspend) + *please_suspend = r; + + return 0; +} + static int acquire_user_record( pam_handle_t *handle, const char *username, @@ -636,6 +665,9 @@ _public_ PAM_EXTERN int pam_sm_authenticate( bool debug = false, suspend_please = false; + if (parse_env(handle, &suspend_please) < 0) + return PAM_AUTH_ERR; + if (parse_argv(handle, argc, argv, &suspend_please, @@ -660,6 +692,9 @@ _public_ PAM_EXTERN int pam_sm_open_session( bool debug = false, suspend_please = false; int r; + if (parse_env(handle, &suspend_please) < 0) + return PAM_SESSION_ERR; + if (parse_argv(handle, argc, argv, &suspend_please, @@ -681,6 +716,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( return r; } + r = pam_putenv(handle, suspend_please ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0"); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set PAM environment variable $SYSTEMD_HOME_SUSPEND: %s", pam_strerror(handle, r)); + return r; + } + /* Let's release the D-Bus connection, after all the session might live quite a long time, and we are * not going to process the bus connection in that time, so let's better close before the daemon * kicks us off because we are not processing anything. */ @@ -764,6 +805,9 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt( usec_t t; int r; + if (parse_env(handle, &please_suspend) < 0) + return PAM_AUTH_ERR; + if (parse_argv(handle, argc, argv, &please_suspend,