]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam_systemd: honor session class provided via PAM environment
authorMichal Sekletar <msekleta@redhat.com>
Mon, 25 Aug 2025 13:09:36 +0000 (15:09 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 26 Sep 2025 19:05:51 +0000 (04:05 +0900)
Replaces #38638

Co-authored-by: Lennart Poettering <lennart@poettering.net>
man/pam_systemd.xml
src/login/pam_systemd.c

index b29bf615965a8efc940e1bfcdb10c92a8fe8adb7..5b6f2fa732f47bf162e1cf4a97314237850bb602 100644 (file)
           </tgroup>
         </table>
 
+        <para>If no session class is specified via either the PAM module option or via the
+        <varname>$XDG_SESSION_CLASS</varname> 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 <varname>$XDG_SESSION_CLASS</varname> environment variable.
+        For example, classic UNIX cronjobs support environment variable assignments (see
+        <citerefentry project='man-pages'><refentrytitle>crontab</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
+        which may be used to choose between the <constant>background</constant> and
+        <constant>background-light</constant> session class individually per cronjob, or
+        <command>run0 --setenv=XDG_SESSION_CLASS=user-light</command> may be used
+        to choose between <constant>user</constant> and <constant>user-light</constant> for invoked privileged sessions.
+        </para>
+
         <xi:include href="version-info.xml" xpointer="v197"/></listitem>
       </varlistentry>
 
index f305075a202819d178f1945a0f4ff7bb30808d94..f4e237dd2a62e97fd0a8ddc4eab6b116b7eb8246 100644 (file)
@@ -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