]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam: add session class "none" to disable logind sessions
authorRonan Pigott <ronan@rjp.ie>
Thu, 14 Nov 2024 23:25:30 +0000 (16:25 -0700)
committerRonan Pigott <ronan@rjp.ie>
Fri, 3 Jan 2025 03:18:15 +0000 (20:18 -0700)
pam_systemd is used to create logind sessions and to apply extended
attributes from json user records. Not every application that creates a
pam session expects a login scope, but may be interested in the extended
attributes of json user records. Session class "none" implements this
service by disabling logind for this session altogether.

man/pam_systemd.xml
src/login/logind-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/pam_systemd.c

index 183b37d676e9850e6524847023ce77b7bcd8d151..e233d8d13fd77c96a589c9a9fbbc03bd358efca2 100644 (file)
                 <entry><constant>manager-early</constant></entry>
                 <entry>Similar to <constant>manager</constant>, but for the root user. Compare with the <constant>user</constant> vs. <constant>user-early</constant> situation. (Added in v256.)</entry>
               </row>
+              <row>
+                <entry><constant>none</constant></entry>
+                <entry>Skips registering this session with logind. No session scope will be created, and the user service manager will not be started. (Added in v258.)</entry>
+              </row>
             </tbody>
           </tgroup>
         </table>
index dce596eeb370e97a0e321648b93ed113ef5bbe4c..efac58061d37a955d71855d9e9141ac6b58fc365 100644 (file)
@@ -863,6 +863,27 @@ static int create_session(
         if (!uid_is_valid(uid))
                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID");
 
+        if (isempty(type))
+                t = _SESSION_TYPE_INVALID;
+        else {
+                t = session_type_from_string(type);
+                if (t < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Invalid session type %s", type);
+        }
+
+        if (isempty(class))
+                c = _SESSION_CLASS_INVALID;
+        else {
+                c = session_class_from_string(class);
+                if (c < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                 "Invalid session class %s", class);
+                if (c == SESSION_NONE)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+                                                "Refusing session class %s", class);
+        }
+
         if (flags != 0)
                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Flags must be zero.");
 
@@ -882,24 +903,6 @@ static int create_session(
         if (leader.pid == 1 || pidref_is_self(&leader))
                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
 
-        if (isempty(type))
-                t = _SESSION_TYPE_INVALID;
-        else {
-                t = session_type_from_string(type);
-                if (t < 0)
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
-                                                 "Invalid session type %s", type);
-        }
-
-        if (isempty(class))
-                c = _SESSION_CLASS_INVALID;
-        else {
-                c = session_class_from_string(class);
-                if (c < 0)
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
-                                                 "Invalid session class %s", class);
-        }
-
         if (isempty(desktop))
                 desktop = NULL;
         else {
index 351b64b60bba83e984355270c4677ae52cc72426..ed93fd7d9ef8a025b815ed7df0dc117e4f75fd70 100644 (file)
@@ -1678,6 +1678,7 @@ static const char* const session_class_table[_SESSION_CLASS_MAX] = {
         [SESSION_BACKGROUND_LIGHT]  = "background-light",
         [SESSION_MANAGER]           = "manager",
         [SESSION_MANAGER_EARLY]     = "manager-early",
+        [SESSION_NONE]              = "none",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
index 2d2cb189fca6bd28ae6aae325f8cba939eb9e45e..f7ee7a92b6ccd1d3e2776a4a56fe56e3fe6dc9b7 100644 (file)
@@ -29,6 +29,7 @@ typedef enum SessionClass {
         SESSION_BACKGROUND_LIGHT,   /* Like SESSION_BACKGROUND, but without the service manager */
         SESSION_MANAGER,            /* The service manager */
         SESSION_MANAGER_EARLY,      /* The service manager for root (which is allowed to run before systemd-user-sessions.service) */
+        SESSION_NONE,               /* A session not registered with logind */
         _SESSION_CLASS_MAX,
         _SESSION_CLASS_INVALID = -EINVAL,
 } SessionClass;
@@ -44,7 +45,7 @@ typedef enum SessionClass {
 #define SESSION_CLASS_WANTS_SERVICE_MANAGER(class) IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER, SESSION_LOCK_SCREEN, SESSION_BACKGROUND)
 
 /* Which session classes can pin our user tracking? */
-#define SESSION_CLASS_PIN_USER(class) (!IN_SET((class), SESSION_MANAGER, SESSION_MANAGER_EARLY))
+#define SESSION_CLASS_PIN_USER(class) (!IN_SET((class), SESSION_MANAGER, SESSION_MANAGER_EARLY, SESSION_NONE))
 
 /* Which session classes decide whether system is idle? (should only cover sessions that have input, and are not idle screens themselves)*/
 #define SESSION_CLASS_CAN_IDLE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER))
index 9d96c9153958e6fb04d3b48fde1d23a3879a2570..e0861f934c8208e5e6a48c1099ccde3fbe6d421e 100644 (file)
@@ -1043,6 +1043,12 @@ static int register_session(
         assert(ur);
         assert(ret_seat);
 
+        /* We don't register session class none with logind */
+        if (streq(c->class, "none")) {
+                pam_debug_syslog(handle, debug, "Skipping logind registration for session class none");
+                goto skip;
+        }
+
         /* Make most of this a NOP on non-logind systems */
         if (!logind_running())
                 goto skip;