From: Michal Sekletar Date: Mon, 25 Aug 2025 13:09:36 +0000 (+0200) Subject: pam_systemd: honor session class provided via PAM environment X-Git-Tag: v259-rc1~415 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf2630acaa87ded5ad99ea30ed4bd895e71ca503;p=thirdparty%2Fsystemd.git pam_systemd: honor session class provided via PAM environment Replaces #38638 Co-authored-by: Lennart Poettering --- diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index b29bf615965..5b6f2fa732f 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -159,6 +159,19 @@ + If no session class is specified via either the PAM module option or via the + $XDG_SESSION_CLASS environment variable, the class is automatically chosen, depending on + various session parameters, such as the session type (if known), whether the session has a TTY or X11 + display, and the user disposition. Note that various tools allow setting the session class for newly + allocated PAM sessions explicitly by means of the $XDG_SESSION_CLASS environment variable. + For example, classic UNIX cronjobs support environment variable assignments (see + crontab5), + which may be used to choose between the background and + background-light session class individually per cronjob, or + run0 --setenv=XDG_SESSION_CLASS=user-light may be used + to choose between user and user-light for invoked privileged sessions. + + diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index f305075a202..f4e237dd2a6 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -921,11 +921,13 @@ static void session_context_mangle( assert(c); assert(ur); + /* The session class can be overridden via the PAM environment, and we try to honor that selection. */ if (streq_ptr(c->service, "systemd-user")) { /* If we detect that we are running in the "systemd-user" PAM stack, then let's patch the class to * 'manager' if not set, simply for robustness reasons. */ c->type = "unspecified"; - c->class = IN_SET(user_record_disposition(ur), USER_INTRINSIC, USER_SYSTEM, USER_DYNAMIC) ? + if (isempty(c->class)) + c->class = IN_SET(user_record_disposition(ur), USER_INTRINSIC, USER_SYSTEM, USER_DYNAMIC) ? "manager-early" : "manager"; c->tty = NULL; @@ -942,14 +944,16 @@ static void session_context_mangle( * (as they otherwise even try to update it!) — but cron doesn't actually allocate a TTY for its forked * off processes.) */ c->type = "unspecified"; - c->class = "background"; + if (isempty(c->class)) + c->class = "background"; c->tty = NULL; } else if (streq_ptr(c->tty, "ssh")) { /* ssh has been setting PAM_TTY to "ssh" (for the same reason as cron does this, see above. For further * details look for "PAM_TTY_KLUDGE" in the openssh sources). */ c->type = "tty"; - c->class = "user"; + if (isempty(c->class)) + c->class = "user"; c->tty = NULL; /* This one is particularly sad, as this means that ssh sessions — even though * usually associated with a pty — won't be tracked by their tty in * logind. This is because ssh does the PAM session registration early for new