]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
c2f1db8f | 2 | #pragma once |
90821c93 | 3 | |
90821c93 | 4 | typedef struct Session Session; |
9444b1f2 | 5 | typedef enum KillWho KillWho; |
90821c93 LP |
6 | |
7 | #include "list.h" | |
a095315b | 8 | #include "login-util.h" |
71d35b6b | 9 | #include "logind-user.h" |
89bad70f | 10 | #include "pidref.h" |
3b92c086 | 11 | #include "string-util.h" |
90821c93 | 12 | |
0604381b | 13 | typedef enum SessionState { |
fb6becb4 | 14 | SESSION_OPENING, /* Session scope is being created */ |
0604381b LP |
15 | SESSION_ONLINE, /* Logged in */ |
16 | SESSION_ACTIVE, /* Logged in and in the fg */ | |
fb6becb4 | 17 | SESSION_CLOSING, /* Logged out, but scope is still there */ |
0604381b | 18 | _SESSION_STATE_MAX, |
2d93c20e | 19 | _SESSION_STATE_INVALID = -EINVAL, |
0604381b LP |
20 | } SessionState; |
21 | ||
55efac6c | 22 | typedef enum SessionClass { |
29e1857b | 23 | SESSION_USER, /* A regular user session */ |
59afe07c | 24 | SESSION_USER_EARLY, /* A user session, that is not ordered after systemd-user-sessions.service (i.e. for root) */ |
53ebde6d | 25 | SESSION_USER_INCOMPLETE, /* A user session that is only half-way set up and doesn't pull in the service manager, and can be upgraded to a full user session later */ |
29e1857b LP |
26 | SESSION_GREETER, /* A login greeter pseudo-session */ |
27 | SESSION_LOCK_SCREEN, /* A lock screen */ | |
28 | SESSION_BACKGROUND, /* Things like cron jobs, which are non-interactive */ | |
b5100c73 | 29 | SESSION_BACKGROUND_LIGHT, /* Like SESSION_BACKGROUND, but without the service manager */ |
5099a50d LP |
30 | SESSION_MANAGER, /* The service manager */ |
31 | SESSION_MANAGER_EARLY, /* The service manager for root (which is allowed to run before systemd-user-sessions.service) */ | |
55efac6c | 32 | _SESSION_CLASS_MAX, |
2d93c20e | 33 | _SESSION_CLASS_INVALID = -EINVAL, |
55efac6c LP |
34 | } SessionClass; |
35 | ||
5099a50d LP |
36 | /* Whether we shall allow sessions of this class to run before 'systemd-user-sessions.service'. It's |
37 | * generally set for root sessions, but no one else. */ | |
38 | #define SESSION_CLASS_IS_EARLY(class) IN_SET((class), SESSION_USER_EARLY, SESSION_MANAGER_EARLY) | |
39 | ||
40 | /* Which session classes want their own scope units? (all of them, except the manager, which comes in its own service unit already */ | |
53ebde6d | 41 | #define SESSION_CLASS_WANTS_SCOPE(class) IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_USER_INCOMPLETE, SESSION_GREETER, SESSION_LOCK_SCREEN, SESSION_BACKGROUND, SESSION_BACKGROUND_LIGHT) |
5099a50d LP |
42 | |
43 | /* Which session classes want their own per-user service manager? */ | |
44 | #define SESSION_CLASS_WANTS_SERVICE_MANAGER(class) IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER, SESSION_LOCK_SCREEN, SESSION_BACKGROUND) | |
45 | ||
46 | /* Which session classes can pin our user tracking? */ | |
47 | #define SESSION_CLASS_PIN_USER(class) (!IN_SET((class), SESSION_MANAGER, SESSION_MANAGER_EARLY)) | |
59afe07c | 48 | |
b4f01bc1 LP |
49 | /* Which session classes decide whether system is idle? (should only cover sessions that have input, and are not idle screens themselves)*/ |
50 | #define SESSION_CLASS_CAN_IDLE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER)) | |
51 | ||
52 | /* Which session classes have a lock screen concept? */ | |
53 | #define SESSION_CLASS_CAN_LOCK(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY)) | |
54 | ||
55 | /* Which sessions are candidates to become "display" sessions */ | |
56 | #define SESSION_CLASS_CAN_DISPLAY(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER)) | |
57 | ||
ad23439e LP |
58 | /* Which sessions classes should be subject to stop-in-idle */ |
59 | #define SESSION_CLASS_CAN_STOP_ON_IDLE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY)) | |
60 | ||
87dc8bbd LP |
61 | /* Which session classes can take control of devices */ |
62 | #define SESSION_CLASS_CAN_TAKE_DEVICE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER, SESSION_LOCK_SCREEN)) | |
63 | ||
68fbd9a0 LP |
64 | /* Which session classes allow changing session types */ |
65 | #define SESSION_CLASS_CAN_CHANGE_TYPE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER, SESSION_LOCK_SCREEN)) | |
66 | ||
e2acb67b LP |
67 | typedef enum SessionType { |
68 | SESSION_UNSPECIFIED, | |
69 | SESSION_TTY, | |
70 | SESSION_X11, | |
d9eb81f9 | 71 | SESSION_WAYLAND, |
9541666b | 72 | SESSION_MIR, |
e9e74f28 | 73 | SESSION_WEB, |
e2acb67b | 74 | _SESSION_TYPE_MAX, |
2d93c20e | 75 | _SESSION_TYPE_INVALID = -EINVAL, |
e2acb67b LP |
76 | } SessionType; |
77 | ||
952d3260 LP |
78 | #define SESSION_TYPE_IS_GRAPHICAL(type) IN_SET(type, SESSION_X11, SESSION_WAYLAND, SESSION_MIR) |
79 | ||
9444b1f2 | 80 | enum KillWho { |
de07ab16 LP |
81 | KILL_LEADER, |
82 | KILL_ALL, | |
83 | _KILL_WHO_MAX, | |
2d93c20e | 84 | _KILL_WHO_INVALID = -EINVAL, |
9444b1f2 | 85 | }; |
de07ab16 | 86 | |
3d0ef5c7 LP |
87 | typedef enum TTYValidity { |
88 | TTY_FROM_PAM, | |
89 | TTY_FROM_UTMP, | |
90 | TTY_UTMP_INCONSISTENT, /* may happen on ssh sessions with multiplexed TTYs */ | |
91 | _TTY_VALIDITY_MAX, | |
2d93c20e | 92 | _TTY_VALIDITY_INVALID = -EINVAL, |
3d0ef5c7 LP |
93 | } TTYValidity; |
94 | ||
90821c93 LP |
95 | struct Session { |
96 | Manager *manager; | |
97 | ||
c1f04b83 MY |
98 | char *id; |
99 | ||
14cb109d | 100 | unsigned position; |
90821c93 | 101 | SessionType type; |
db72aea4 | 102 | SessionType original_type; |
55efac6c | 103 | SessionClass class; |
90821c93 LP |
104 | |
105 | char *state_file; | |
106 | ||
107 | User *user; | |
108 | ||
109 | dual_timestamp timestamp; | |
110 | ||
90821c93 | 111 | char *display; |
3d0ef5c7 LP |
112 | char *tty; |
113 | TTYValidity tty_validity; | |
90821c93 LP |
114 | |
115 | bool remote; | |
3f49d45a | 116 | char *remote_user; |
90821c93 | 117 | char *remote_host; |
98a28fef | 118 | char *service; |
a4cd87e9 | 119 | char *desktop; |
fb6becb4 LP |
120 | |
121 | char *scope; | |
122 | char *scope_job; | |
98a28fef | 123 | |
90821c93 | 124 | Seat *seat; |
14cb109d | 125 | unsigned vtnr; |
90a18413 | 126 | int vtfd; |
90821c93 | 127 | |
89bad70f | 128 | PidRef leader; |
9d5b6901 MY |
129 | bool leader_fd_saved; /* pidfd of leader uploaded to fdstore */ |
130 | pid_t deserialized_pid; /* PID deserialized from state file (for verification when pidfd is used) */ | |
3f49d45a | 131 | uint32_t audit_id; |
90821c93 | 132 | |
932e3ee7 LP |
133 | int fifo_fd; |
134 | char *fifo_path; | |
90821c93 | 135 | |
cc377381 | 136 | sd_event_source *fifo_event_source; |
76f2191d | 137 | sd_event_source *leader_pidfd_event_source; |
cc377381 | 138 | |
6169bb19 ZJS |
139 | bool in_gc_queue; |
140 | bool started; | |
141 | bool stopping; | |
a185c5aa | 142 | |
6169bb19 | 143 | bool was_active; |
42d35e13 | 144 | |
6169bb19 | 145 | bool locked_hint; |
90821c93 | 146 | |
6169bb19 ZJS |
147 | bool idle_hint; |
148 | dual_timestamp idle_hint_timestamp; | |
aed24c4c | 149 | |
6e9bf0ad | 150 | sd_bus_message *create_message; /* The D-Bus message used to create the session, which we haven't responded to yet */ |
4931b8e4 | 151 | sd_bus_message *upgrade_message; /* The D-Bus message used to upgrade the session class user-incomplete → user, which we haven't responded to yet */ |
fb6becb4 | 152 | |
061c6607 | 153 | /* Set up when a client requested to release the session via the bus */ |
5f41d1f1 LP |
154 | sd_event_source *timer_event_source; |
155 | ||
ae5e06bd | 156 | char *controller; |
118ecf32 | 157 | Hashmap *devices; |
3cde9e8f | 158 | sd_bus_track *track; |
ae5e06bd | 159 | |
82325af3 MS |
160 | sd_event_source *stop_on_idle_event_source; |
161 | ||
90821c93 LP |
162 | LIST_FIELDS(Session, sessions_by_user); |
163 | LIST_FIELDS(Session, sessions_by_seat); | |
14c3baca LP |
164 | |
165 | LIST_FIELDS(Session, gc_queue); | |
90821c93 LP |
166 | }; |
167 | ||
2454cee3 | 168 | int session_new(Manager *m, const char *id, Session **ret); |
8c29a457 LP |
169 | Session* session_free(Session *s); |
170 | ||
2454cee3 | 171 | DEFINE_TRIVIAL_CLEANUP_FUNC(Session*, session_free); |
8c29a457 | 172 | |
9444b1f2 | 173 | void session_set_user(Session *s, User *u); |
76f2191d | 174 | int session_set_leader_consume(Session *s, PidRef _leader); |
5c093a23 | 175 | bool session_may_gc(Session *s, bool drop_not_started); |
14c3baca | 176 | void session_add_to_gc_queue(Session *s); |
90821c93 LP |
177 | int session_activate(Session *s); |
178 | bool session_is_active(Session *s); | |
a185c5aa | 179 | int session_get_idle_hint(Session *s, dual_timestamp *t); |
be2bb14f | 180 | int session_set_idle_hint(Session *s, bool b); |
42d35e13 | 181 | int session_get_locked_hint(Session *s); |
b4f01bc1 | 182 | int session_set_locked_hint(Session *s, bool b); |
db72aea4 | 183 | void session_set_type(Session *s, SessionType t); |
6e9bf0ad | 184 | void session_set_class(Session *s, SessionClass c); |
4885d749 | 185 | int session_set_display(Session *s, const char *display); |
092e6cd1 | 186 | int session_set_tty(Session *s, const char *tty); |
932e3ee7 | 187 | int session_create_fifo(Session *s); |
25a1ab4e | 188 | int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); |
9bb69af4 | 189 | int session_stop(Session *s, bool force); |
405e0255 | 190 | int session_finalize(Session *s); |
ad8780c9 | 191 | int session_release(Session *s); |
90821c93 LP |
192 | int session_save(Session *s); |
193 | int session_load(Session *s); | |
de07ab16 | 194 | int session_kill(Session *s, KillWho who, int signo); |
90821c93 | 195 | |
0604381b LP |
196 | SessionState session_get_state(Session *u); |
197 | ||
44a6b1b6 ZJS |
198 | const char* session_state_to_string(SessionState t) _const_; |
199 | SessionState session_state_from_string(const char *s) _pure_; | |
0604381b | 200 | |
44a6b1b6 ZJS |
201 | const char* session_type_to_string(SessionType t) _const_; |
202 | SessionType session_type_from_string(const char *s) _pure_; | |
90821c93 | 203 | |
44a6b1b6 ZJS |
204 | const char* session_class_to_string(SessionClass t) _const_; |
205 | SessionClass session_class_from_string(const char *s) _pure_; | |
55efac6c | 206 | |
44a6b1b6 ZJS |
207 | const char *kill_who_to_string(KillWho k) _const_; |
208 | KillWho kill_who_from_string(const char *s) _pure_; | |
ae5e06bd | 209 | |
3d0ef5c7 LP |
210 | const char* tty_validity_to_string(TTYValidity t) _const_; |
211 | TTYValidity tty_validity_from_string(const char *s) _pure_; | |
212 | ||
2ec3ff66 | 213 | void session_leave_vt(Session *s); |
90a18413 | 214 | |
ae5e06bd | 215 | bool session_is_controller(Session *s, const char *sender); |
dc6284e9 | 216 | int session_set_controller(Session *s, const char *sender, bool force, bool prepare); |
ae5e06bd | 217 | void session_drop_controller(Session *s); |
c529695e | 218 | |
3b92c086 LP |
219 | static inline bool SESSION_IS_SELF(const char *name) { |
220 | return isempty(name) || streq(name, "self"); | |
221 | } | |
222 | ||
223 | static inline bool SESSION_IS_AUTO(const char *name) { | |
224 | return streq_ptr(name, "auto"); | |
225 | } |