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