From: Lennart Poettering Date: Mon, 27 Nov 2023 17:19:50 +0000 (+0100) Subject: logind: rework the special casing we give root's sessions X-Git-Tag: v256-rc1~1281^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F30731%2Fhead;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 979e506897e..ed19129300e 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 a947c8541a2..f018cb30f90 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 4e6b20eb11e..2675fa7e93d 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 20ec5530d9a..297689203b0 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);