logind: rework the special casing we give root's sessions

Let's add an explicit session class "user-early" for this, so that
change of behaviour on logind is primarily bound to the "class"
property, and not some explicit root checks. This has the benefit that
we can be more fine grained with implying this class: only do so for tty
sessions, not others.
This commit is contained in:
Lennart Poettering
2023-11-27 18:19:50 +01:00
parent 29e1857b68
commit 59afe07c21
4 changed files with 13 additions and 2 deletions

View File

@@ -743,7 +743,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
* of STRV_IGNORE with strv_new() to skip these order constraints when needed. */
after = strv_new("systemd-logind.service",
s->user->runtime_dir_service,
!uid_is_system(s->user->user_record->uid) ? "systemd-user-sessions.service" : STRV_IGNORE,
SESSION_CLASS_IS_EARLY(s->class) ? STRV_IGNORE : "systemd-user-sessions.service",
s->user->service);
if (!after)
return log_oom();
@@ -1637,6 +1637,7 @@ DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
static const char* const session_class_table[_SESSION_CLASS_MAX] = {
[SESSION_USER] = "user",
[SESSION_USER_EARLY] = "user-early",
[SESSION_GREETER] = "greeter",
[SESSION_LOCK_SCREEN] = "lock-screen",
[SESSION_BACKGROUND] = "background",

View File

@@ -21,6 +21,7 @@ typedef enum SessionState {
typedef enum SessionClass {
SESSION_USER, /* A regular user session */
SESSION_USER_EARLY, /* A user session, that is not ordered after systemd-user-sessions.service (i.e. for root) */
SESSION_GREETER, /* A login greeter pseudo-session */
SESSION_LOCK_SCREEN, /* A lock screen */
SESSION_BACKGROUND, /* Things like cron jobs, which are non-interactive */
@@ -28,6 +29,10 @@ typedef enum SessionClass {
_SESSION_CLASS_INVALID = -EINVAL,
} SessionClass;
/* Whether we shall allow sessions of this class to run before 'systemd-user-sessions.service'. For now,
* there's only one class we allow this for. It's generally set for root sessions, but noone else. */
#define SESSION_CLASS_IS_EARLY(class) ((class) == SESSION_USER_EARLY)
typedef enum SessionType {
SESSION_UNSPECIFIED,
SESSION_TTY,

View File

@@ -782,6 +782,9 @@ static int elect_display_compare(Session *s1, Session *s2) {
if ((s1->class != SESSION_USER) != (s2->class != SESSION_USER))
return (s1->class != SESSION_USER) - (s2->class != SESSION_USER);
if ((s1->class != SESSION_USER_EARLY) != (s2->class != SESSION_USER_EARLY))
return (s1->class != SESSION_USER_EARLY) - (s2->class != SESSION_USER_EARLY);
if ((s1->type == _SESSION_TYPE_INVALID) != (s2->type == _SESSION_TYPE_INVALID))
return (s1->type == _SESSION_TYPE_INVALID) - (s2->type == _SESSION_TYPE_INVALID);

View File

@@ -1011,7 +1011,9 @@ _public_ PAM_EXTERN int pam_sm_open_session(
!isempty(tty) ? "tty" : "unspecified";
if (isempty(class))
class = streq(type, "unspecified") ? "background" : "user";
class = streq(type, "unspecified") ? "background" :
((IN_SET(user_record_disposition(ur), USER_INTRINSIC, USER_SYSTEM, USER_DYNAMIC) &&
streq(type, "tty")) ? "user-early" : "user");
remote = !isempty(remote_host) && !is_localhost(remote_host);