diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 979e506897..ed19129300 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -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", diff --git a/src/login/logind-session.h b/src/login/logind-session.h index a947c8541a..f018cb30f9 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -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, diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 4e6b20eb11..2675fa7e93 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -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); diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 20ec5530d9..297689203b 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -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);