Merge pull request #15882 from poettering/pam-sudo-fixes-part4

More pam_systemd fixes split out of #15742
This commit is contained in:
Lennart Poettering 2020-05-28 00:27:51 +02:00 committed by GitHub
commit 60daebdec2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -465,8 +465,17 @@ static bool validate_runtime_directory(pam_handle_t *handle, const char *path, u
assert(handle);
assert(path);
/* Just some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually set
* up properly for us. */
/* Some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually
* set up properly for us. This is supposed to provide a careful safety net for supporting su/sudo
* type transitions: in that case the UID changes, but the session and thus the user owning it
* doesn't change. Since the $XDG_RUNTIME_DIR life-cycle is bound to the session's user being logged
* in at least once we should be particularly careful when setting the environment variable, since
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
if (!path_is_absolute(path)) {
pam_syslog(handle, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
goto fail;
}
if (lstat(path, &st) < 0) {
pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror_safe(errno));
@ -622,6 +631,29 @@ static int apply_user_record_settings(pam_handle_t *handle, UserRecord *ur, bool
return PAM_SUCCESS;
}
static int configure_runtime_directory(
pam_handle_t *handle,
UserRecord *ur,
const char *rt) {
int r;
assert(handle);
assert(ur);
assert(rt);
if (!validate_runtime_directory(handle, rt, ur->uid))
return PAM_SUCCESS;
r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0);
if (r != PAM_SUCCESS) {
pam_syslog(handle, LOG_ERR, "Failed to set runtime dir: %s", pam_strerror(handle, r));
return r;
}
return export_legacy_dbus_address(handle, rt);
}
_public_ PAM_EXTERN int pam_sm_open_session(
pam_handle_t *handle,
int flags,
@ -677,15 +709,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
char rt[STRLEN("/run/user/") + DECIMAL_STR_MAX(uid_t)];
xsprintf(rt, "/run/user/"UID_FMT, ur->uid);
if (validate_runtime_directory(handle, rt, ur->uid)) {
r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0);
if (r != PAM_SUCCESS) {
pam_syslog(handle, LOG_ERR, "Failed to set runtime dir: %s", pam_strerror(handle, r));
return r;
}
}
r = export_legacy_dbus_address(handle, rt);
r = configure_runtime_directory(handle, ur, rt);
if (r != PAM_SUCCESS)
return r;
@ -875,19 +899,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
return r;
if (original_uid == ur->uid) {
/* Don't set $XDG_RUNTIME_DIR if the user we now
* authenticated for does not match the original user
* of the session. We do this in order not to result
* in privileged apps clobbering the runtime directory
* unnecessarily. */
/* Don't set $XDG_RUNTIME_DIR if the user we now authenticated for does not match the
* original user of the session. We do this in order not to result in privileged apps
* clobbering the runtime directory unnecessarily. */
if (validate_runtime_directory(handle, runtime_path, ur->uid)) {
r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
if (r != PAM_SUCCESS)
return r;
}
r = export_legacy_dbus_address(handle, runtime_path);
r = configure_runtime_directory(handle, ur, runtime_path);
if (r != PAM_SUCCESS)
return r;
}