]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/logind-session.c
logind: Add fallback for when the PIDFDs= property is not available
[thirdparty/systemd.git] / src / login / logind-session.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
20263082
LP
2
3#include <errno.h>
90a18413 4#include <fcntl.h>
90a18413 5#include <linux/kd.h>
4f5dd394 6#include <linux/vt.h>
90a18413 7#include <signal.h>
90a18413 8#include <sys/ioctl.h>
ca78ad1d 9#include <sys/stat.h>
20263082
LP
10#include <unistd.h>
11
cc377381 12#include "sd-messages.h"
4f5dd394 13
b5efdb8a 14#include "alloc-util.h"
430f0182 15#include "audit-util.h"
cc377381 16#include "bus-error.h"
4f5dd394 17#include "bus-util.h"
9d5b6901 18#include "daemon-util.h"
7176f06c 19#include "devnum-util.h"
686d13b9 20#include "env-file.h"
4f5dd394 21#include "escape.h"
3ffd4af2 22#include "fd-util.h"
4f5dd394 23#include "fileio.h"
f97b34a6 24#include "format-util.h"
70f1280c 25#include "fs-util.h"
c004493c 26#include "io-util.h"
6ecda0fb
LP
27#include "logind-dbus.h"
28#include "logind-seat-dbus.h"
29#include "logind-session-dbus.h"
3ffd4af2 30#include "logind-session.h"
6ecda0fb 31#include "logind-user-dbus.h"
35cd0ba5 32#include "mkdir-label.h"
6bedfcbb 33#include "parse-util.h"
4f5dd394 34#include "path-util.h"
8c29a457 35#include "process-util.h"
d68c645b 36#include "serialize.h"
8b43440b 37#include "string-table.h"
25a1ab4e 38#include "strv.h"
288a74cc 39#include "terminal-util.h"
e4de7287 40#include "tmpfile-util.h"
8e1ac16b 41#include "uid-classification.h"
b1d4f8e1 42#include "user-util.h"
20263082 43
5f41d1f1
LP
44#define RELEASE_USEC (20*USEC_PER_SEC)
45
46static void session_remove_fifo(Session *s);
0212126c 47static void session_restore_vt(Session *s);
5f41d1f1 48
2454cee3 49int session_new(Manager *m, const char *id, Session **ret) {
8c29a457
LP
50 _cleanup_(session_freep) Session *s = NULL;
51 int r;
20263082
LP
52
53 assert(m);
54 assert(id);
2454cee3 55 assert(ret);
20263082 56
8c29a457
LP
57 if (!session_id_valid(id))
58 return -EINVAL;
59
60 s = new(Session, 1);
20263082 61 if (!s)
8c29a457
LP
62 return -ENOMEM;
63
64 *s = (Session) {
65 .manager = m,
c1f04b83
MY
66 .id = strdup(id),
67 .state_file = path_join("/run/systemd/sessions/", id),
254d1313
ZJS
68 .fifo_fd = -EBADF,
69 .vtfd = -EBADF,
8c29a457 70 .audit_id = AUDIT_SESSION_INVALID,
3d0ef5c7 71 .tty_validity = _TTY_VALIDITY_INVALID,
89bad70f 72 .leader = PIDREF_NULL,
8c29a457 73 };
c1f04b83 74 if (!s->id || !s->state_file)
8c29a457 75 return -ENOMEM;
118ecf32 76
8c29a457
LP
77 s->devices = hashmap_new(&devt_hash_ops);
78 if (!s->devices)
79 return -ENOMEM;
20263082 80
8c29a457
LP
81 r = hashmap_put(m->sessions, s->id, s);
82 if (r < 0)
83 return r;
20263082 84
8c29a457
LP
85 *ret = TAKE_PTR(s);
86 return 0;
20263082
LP
87}
88
0ae9073f
MY
89static int session_dispatch_leader_pidfd(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
90 Session *s = ASSERT_PTR(userdata);
91
92 assert(s->leader.fd == fd);
93 session_stop(s, /* force= */ false);
94
95 return 1;
96}
97
98static int session_watch_pidfd(Session *s) {
99 int r;
100
101 assert(s);
102 assert(s->manager);
103 assert(pidref_is_set(&s->leader));
104
105 if (s->leader.fd < 0)
106 return 0;
107
108 r = sd_event_add_io(s->manager->event, &s->leader_pidfd_event_source, s->leader.fd, EPOLLIN, session_dispatch_leader_pidfd, s);
109 if (r < 0)
110 return r;
111
112 r = sd_event_source_set_priority(s->leader_pidfd_event_source, SD_EVENT_PRIORITY_IMPORTANT);
113 if (r < 0)
114 return r;
115
116 (void) sd_event_source_set_description(s->leader_pidfd_event_source, "session-pidfd");
117
118 return 0;
119}
120
9d5b6901 121static void session_reset_leader(Session *s, bool keep_fdstore) {
8494f562
MY
122 assert(s);
123
9d5b6901
MY
124 if (!keep_fdstore) {
125 /* Clear fdstore if we're asked to, no matter if s->leader is set or not, so that when
126 * initially deserializing leader fd we clear the old fd too. */
127 (void) notify_remove_fd_warnf("session-%s-leader-fd", s->id);
128 s->leader_fd_saved = false;
129 }
130
8494f562
MY
131 if (!pidref_is_set(&s->leader))
132 return;
133
0ae9073f
MY
134 s->leader_pidfd_event_source = sd_event_source_disable_unref(s->leader_pidfd_event_source);
135
889975bb 136 (void) hashmap_remove_value(s->manager->sessions_by_leader, &s->leader, s);
8494f562
MY
137
138 return pidref_done(&s->leader);
139}
140
8c29a457 141Session* session_free(Session *s) {
118ecf32
DH
142 SessionDevice *sd;
143
8c29a457
LP
144 if (!s)
145 return NULL;
20263082 146
c1f04b83
MY
147 sd_event_source_unref(s->stop_on_idle_event_source);
148
14c3baca 149 if (s->in_gc_queue)
71fda00f 150 LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s);
14c3baca 151
c1f04b83 152 sd_event_source_unref(s->timer_event_source);
5f41d1f1 153
ae5e06bd
DH
154 session_drop_controller(s);
155
118ecf32
DH
156 while ((sd = hashmap_first(s->devices)))
157 session_device_free(sd);
158
159 hashmap_free(s->devices);
160
20263082 161 if (s->user) {
71fda00f 162 LIST_REMOVE(sessions_by_user, s->user->sessions, s);
20263082
LP
163
164 if (s->user->display == s)
165 s->user->display = NULL;
9afe9efb
LP
166
167 user_update_last_session_timer(s->user);
20263082
LP
168 }
169
9418f147
LP
170 if (s->seat) {
171 if (s->seat->active == s)
172 s->seat->active = NULL;
d7bd01b5
DH
173 if (s->seat->pending_switch == s)
174 s->seat->pending_switch = NULL;
9418f147 175
49e6fdbf 176 seat_evict_position(s->seat, s);
71fda00f 177 LIST_REMOVE(sessions_by_seat, s->seat->sessions, s);
9418f147 178 }
20263082 179
fb6becb4
LP
180 if (s->scope) {
181 hashmap_remove(s->manager->session_units, s->scope);
182 free(s->scope);
183 }
184
185 free(s->scope_job);
1713813d 186
9d5b6901 187 session_reset_leader(s, /* keep_fdstore = */ true);
8494f562 188
cc377381 189 sd_bus_message_unref(s->create_message);
6e9bf0ad 190 sd_bus_message_unref(s->upgrade_message);
20263082
LP
191
192 free(s->tty);
193 free(s->display);
194 free(s->remote_host);
3f49d45a 195 free(s->remote_user);
98a28fef 196 free(s->service);
a4cd87e9 197 free(s->desktop);
20263082
LP
198
199 hashmap_remove(s->manager->sessions, s->id);
98a28fef 200
c20b8dad
LP
201 sd_event_source_unref(s->fifo_event_source);
202 safe_close(s->fifo_fd);
203
204 /* Note that we remove neither the state file nor the fifo path here, since we want both to survive
205 * daemon restarts */
c20b8dad 206 free(s->fifo_path);
c1f04b83
MY
207 free(s->state_file);
208 free(s->id);
82325af3 209
8c29a457 210 return mfree(s);
20263082
LP
211}
212
9444b1f2
LP
213void session_set_user(Session *s, User *u) {
214 assert(s);
215 assert(!s->user);
216
217 s->user = u;
71fda00f 218 LIST_PREPEND(sessions_by_user, u->sessions, s);
9afe9efb
LP
219
220 user_update_last_session_timer(u);
9444b1f2
LP
221}
222
76f2191d
MS
223int session_set_leader_consume(Session *s, PidRef _leader) {
224 _cleanup_(pidref_done) PidRef pidref = _leader;
238794b1
LP
225 int r;
226
227 assert(s);
76f2191d 228 assert(pidref_is_set(&pidref));
238794b1 229
76f2191d 230 if (pidref_equal(&s->leader, &pidref))
238794b1
LP
231 return 0;
232
9d5b6901 233 session_reset_leader(s, /* keep_fdstore = */ false);
8494f562
MY
234
235 s->leader = TAKE_PIDREF(pidref);
236
0ae9073f
MY
237 r = session_watch_pidfd(s);
238 if (r < 0)
239 return log_error_errno(r, "Failed to watch leader pidfd for session '%s': %m", s->id);
240
8494f562 241 r = hashmap_ensure_put(&s->manager->sessions_by_leader, &pidref_hash_ops, &s->leader, s);
89bad70f
LP
242 if (r < 0)
243 return r;
8494f562 244 assert(r > 0);
89bad70f 245
9d5b6901
MY
246 if (s->leader.fd >= 0) {
247 r = notify_push_fdf(s->leader.fd, "session-%s-leader-fd", s->id);
248 if (r < 0)
249 log_warning_errno(r, "Failed to push leader pidfd for session '%s', ignoring: %m", s->id);
250 else
251 s->leader_fd_saved = true;
252 }
253
89bad70f 254 (void) audit_session_from_pid(s->leader.pid, &s->audit_id);
238794b1
LP
255
256 return 1;
257}
258
aed24c4c
FB
259static void session_save_devices(Session *s, FILE *f) {
260 SessionDevice *sd;
aed24c4c
FB
261
262 if (!hashmap_isempty(s->devices)) {
263 fprintf(f, "DEVICES=");
90e74a66 264 HASHMAP_FOREACH(sd, s->devices)
67458536 265 fprintf(f, DEVNUM_FORMAT_STR " ", DEVNUM_FORMAT_VAL(sd->dev));
aed24c4c
FB
266 fprintf(f, "\n");
267 }
268}
269
20263082 270int session_save(Session *s) {
70f1280c 271 _cleanup_(unlink_and_freep) char *temp_path = NULL;
cc377381 272 _cleanup_fclose_ FILE *f = NULL;
6d95e7d9 273 int r;
20263082
LP
274
275 assert(s);
276
9444b1f2
LP
277 if (!s->user)
278 return -ESTALE;
279
accaeded
LP
280 if (!s->started)
281 return 0;
282
37c1d5e9 283 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
20263082 284 if (r < 0)
dacd6cee 285 goto fail;
20263082 286
14c3baca
LP
287 r = fopen_temporary(s->state_file, &f, &temp_path);
288 if (r < 0)
dacd6cee 289 goto fail;
20263082 290
44176400 291 (void) fchmod(fileno(f), 0644);
14c3baca 292
20263082
LP
293 fprintf(f,
294 "# This is private data. Do not parse.\n"
90b2de37 295 "UID="UID_FMT"\n"
20263082 296 "USER=%s\n"
fdbb56dc
MY
297 "ACTIVE=%s\n"
298 "IS_DISPLAY=%s\n"
0604381b 299 "STATE=%s\n"
9d5b6901
MY
300 "REMOTE=%s\n"
301 "LEADER_FD_SAVED=%s\n",
22c902fa
LP
302 s->user->user_record->uid,
303 s->user->user_record->user_name,
fdbb56dc
MY
304 one_zero(session_is_active(s)),
305 one_zero(s->user->display == s),
0604381b 306 session_state_to_string(session_get_state(s)),
9d5b6901
MY
307 one_zero(s->remote),
308 one_zero(s->leader_fd_saved));
20263082 309
a91e4e53 310 if (s->type >= 0)
507f22bd 311 fprintf(f, "TYPE=%s\n", session_type_to_string(s->type));
a91e4e53 312
db72aea4
CH
313 if (s->original_type >= 0)
314 fprintf(f, "ORIGINAL_TYPE=%s\n", session_type_to_string(s->original_type));
315
55efac6c 316 if (s->class >= 0)
507f22bd 317 fprintf(f, "CLASS=%s\n", session_class_to_string(s->class));
55efac6c 318
fb6becb4
LP
319 if (s->scope)
320 fprintf(f, "SCOPE=%s\n", s->scope);
fb6becb4
LP
321 if (s->scope_job)
322 fprintf(f, "SCOPE_JOB=%s\n", s->scope_job);
20263082 323
932e3ee7 324 if (s->fifo_path)
507f22bd 325 fprintf(f, "FIFO=%s\n", s->fifo_path);
932e3ee7 326
20263082 327 if (s->seat)
507f22bd 328 fprintf(f, "SEAT=%s\n", s->seat->id);
20263082
LP
329
330 if (s->tty)
507f22bd 331 fprintf(f, "TTY=%s\n", s->tty);
20263082 332
3d0ef5c7
LP
333 if (s->tty_validity >= 0)
334 fprintf(f, "TTY_VALIDITY=%s\n", tty_validity_to_string(s->tty_validity));
335
20263082 336 if (s->display)
507f22bd 337 fprintf(f, "DISPLAY=%s\n", s->display);
20263082 338
558c6490 339 if (s->remote_host) {
c2b2df60 340 _cleanup_free_ char *escaped = NULL;
558c6490
LP
341
342 escaped = cescape(s->remote_host);
343 if (!escaped) {
344 r = -ENOMEM;
dacd6cee 345 goto fail;
558c6490
LP
346 }
347
348 fprintf(f, "REMOTE_HOST=%s\n", escaped);
349 }
350
351 if (s->remote_user) {
c2b2df60 352 _cleanup_free_ char *escaped = NULL;
558c6490
LP
353
354 escaped = cescape(s->remote_user);
355 if (!escaped) {
356 r = -ENOMEM;
dacd6cee 357 goto fail;
558c6490
LP
358 }
359
360 fprintf(f, "REMOTE_USER=%s\n", escaped);
361 }
362
363 if (s->service) {
c2b2df60 364 _cleanup_free_ char *escaped = NULL;
20263082 365
558c6490
LP
366 escaped = cescape(s->service);
367 if (!escaped) {
368 r = -ENOMEM;
dacd6cee 369 goto fail;
558c6490
LP
370 }
371
372 fprintf(f, "SERVICE=%s\n", escaped);
373 }
3f49d45a 374
558c6490 375 if (s->desktop) {
c2b2df60 376 _cleanup_free_ char *escaped = NULL;
98a28fef 377
558c6490
LP
378 escaped = cescape(s->desktop);
379 if (!escaped) {
380 r = -ENOMEM;
dacd6cee 381 goto fail;
558c6490
LP
382 }
383
384 fprintf(f, "DESKTOP=%s\n", escaped);
385 }
a4cd87e9 386
bf7825ae 387 if (s->seat && seat_has_vts(s->seat))
92bd5ff3 388 fprintf(f, "VTNR=%u\n", s->vtnr);
20263082 389
49e6fdbf 390 if (!s->vtnr)
e6494a07 391 fprintf(f, "POSITION=%u\n", s->position);
49e6fdbf 392
89bad70f
LP
393 if (pidref_is_set(&s->leader))
394 fprintf(f, "LEADER="PID_FMT"\n", s->leader.pid);
20263082 395
3a87a86e 396 if (audit_session_is_valid(s->audit_id))
507f22bd 397 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
20263082 398
9444b1f2
LP
399 if (dual_timestamp_is_set(&s->timestamp))
400 fprintf(f,
90b2de37
ZJS
401 "REALTIME="USEC_FMT"\n"
402 "MONOTONIC="USEC_FMT"\n",
403 s->timestamp.realtime,
404 s->timestamp.monotonic);
9444b1f2 405
aed24c4c 406 if (s->controller) {
6d33772f 407 fprintf(f, "CONTROLLER=%s\n", s->controller);
aed24c4c
FB
408 session_save_devices(s, f);
409 }
6d33772f 410
dacd6cee
LP
411 r = fflush_and_check(f);
412 if (r < 0)
413 goto fail;
14c3baca 414
dacd6cee 415 if (rename(temp_path, s->state_file) < 0) {
20263082 416 r = -errno;
dacd6cee 417 goto fail;
20263082
LP
418 }
419
70f1280c 420 temp_path = mfree(temp_path);
dacd6cee
LP
421 return 0;
422
423fail:
424 (void) unlink(s->state_file);
14c3baca 425
dacd6cee 426 return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
20263082
LP
427}
428
aed24c4c 429static int session_load_devices(Session *s, const char *devices) {
aed24c4c
FB
430 int r = 0;
431
432 assert(s);
433
e5c09aad 434 for (const char *p = devices;;) {
aed24c4c 435 _cleanup_free_ char *word = NULL;
aed24c4c
FB
436 dev_t dev;
437 int k;
438
439 k = extract_first_word(&p, &word, NULL, 0);
41935c0c
MY
440 if (k <= 0) {
441 RET_GATHER(r, k);
aed24c4c
FB
442 break;
443 }
444
7176f06c 445 k = parse_devnum(word, &dev);
aed24c4c 446 if (k < 0) {
41935c0c 447 RET_GATHER(r, k);
aed24c4c
FB
448 continue;
449 }
450
451 /* The file descriptors for loaded devices will be reattached later. */
41935c0c 452 RET_GATHER(r, session_device_new(s, dev, /* open_device = */ false, /* ret = */ NULL));
aed24c4c
FB
453 }
454
455 if (r < 0)
41935c0c 456 log_error_errno(r, "Failed to load some session devices for session '%s': %m", s->id);
aed24c4c
FB
457 return r;
458}
dacd6cee 459
20263082 460int session_load(Session *s) {
9444b1f2 461 _cleanup_free_ char *remote = NULL,
a185c5aa 462 *seat = NULL,
3d0ef5c7 463 *tty_validity = NULL,
a185c5aa 464 *vtnr = NULL,
be94d954 465 *state = NULL,
e6494a07 466 *position = NULL,
9d5b6901
MY
467 *leader_pid = NULL,
468 *leader_fd_saved = NULL,
55efac6c 469 *type = NULL,
db72aea4 470 *original_type = NULL,
9444b1f2
LP
471 *class = NULL,
472 *uid = NULL,
473 *realtime = NULL,
6d33772f 474 *monotonic = NULL,
aed24c4c
FB
475 *controller = NULL,
476 *active = NULL,
1c8280fd
LP
477 *devices = NULL,
478 *is_display = NULL;
a185c5aa
LP
479
480 int k, r;
481
20263082
LP
482 assert(s);
483
aa8fbc74 484 r = parse_env_file(NULL, s->state_file,
9d5b6901
MY
485 "REMOTE", &remote,
486 "SCOPE", &s->scope,
487 "SCOPE_JOB", &s->scope_job,
488 "FIFO", &s->fifo_path,
489 "SEAT", &seat,
490 "TTY", &s->tty,
491 "TTY_VALIDITY", &tty_validity,
492 "DISPLAY", &s->display,
493 "REMOTE_HOST", &s->remote_host,
494 "REMOTE_USER", &s->remote_user,
495 "SERVICE", &s->service,
496 "DESKTOP", &s->desktop,
497 "VTNR", &vtnr,
498 "STATE", &state,
499 "POSITION", &position,
500 "LEADER", &leader_pid,
501 "LEADER_FD_SAVED", &leader_fd_saved,
502 "TYPE", &type,
503 "ORIGINAL_TYPE", &original_type,
504 "CLASS", &class,
505 "UID", &uid,
506 "REALTIME", &realtime,
507 "MONOTONIC", &monotonic,
508 "CONTROLLER", &controller,
509 "ACTIVE", &active,
510 "DEVICES", &devices,
511 "IS_DISPLAY", &is_display);
f647962d
MS
512 if (r < 0)
513 return log_error_errno(r, "Failed to read %s: %m", s->state_file);
9444b1f2
LP
514
515 if (!s->user) {
516 uid_t u;
517 User *user;
518
baaa35ad
ZJS
519 if (!uid)
520 return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
521 "UID not specified for session %s",
522 s->id);
9444b1f2
LP
523
524 r = parse_uid(uid, &u);
525 if (r < 0) {
526 log_error("Failed to parse UID value %s for session %s.", uid, s->id);
527 return r;
528 }
529
8cb4ab00 530 user = hashmap_get(s->manager->users, UID_TO_PTR(u));
baaa35ad
ZJS
531 if (!user)
532 return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
533 "User of session %s not known.",
534 s->id);
9444b1f2
LP
535
536 session_set_user(s, user);
537 }
a185c5aa
LP
538
539 if (remote) {
540 k = parse_boolean(remote);
541 if (k >= 0)
542 s->remote = k;
543 }
544
c506027a
DH
545 if (vtnr)
546 safe_atou(vtnr, &s->vtnr);
547
9418f147 548 if (seat && !s->seat) {
a185c5aa
LP
549 Seat *o;
550
551 o = hashmap_get(s->manager->seats, seat);
552 if (o)
c506027a
DH
553 r = seat_attach_session(o, s);
554 if (!o || r < 0)
555 log_error("Cannot attach session %s to seat %s", s->id, seat);
a185c5aa
LP
556 }
557
c506027a
DH
558 if (!s->seat || !seat_has_vts(s->seat))
559 s->vtnr = 0;
a185c5aa 560
e6494a07 561 if (position && s->seat) {
14cb109d 562 unsigned npos;
49e6fdbf 563
e6494a07 564 safe_atou(position, &npos);
49e6fdbf
DH
565 seat_claim_position(s->seat, s, npos);
566 }
567
3d0ef5c7
LP
568 if (tty_validity) {
569 TTYValidity v;
570
571 v = tty_validity_from_string(tty_validity);
572 if (v < 0)
573 log_debug("Failed to parse TTY validity: %s", tty_validity);
574 else
575 s->tty_validity = v;
576 }
577
a91e4e53
LP
578 if (type) {
579 SessionType t;
580
581 t = session_type_from_string(type);
582 if (t >= 0)
583 s->type = t;
584 }
585
db72aea4
CH
586 if (original_type) {
587 SessionType ot;
588
589 ot = session_type_from_string(original_type);
590 if (ot >= 0)
591 s->original_type = ot;
592 } else
593 /* Pre-v246 compat: initialize original_type if not set in the state file */
594 s->original_type = s->type;
595
55efac6c
LP
596 if (class) {
597 SessionClass c;
598
599 c = session_class_from_string(class);
600 if (c >= 0)
601 s->class = c;
602 }
603
e5c09aad 604 if (streq_ptr(state, "closing"))
be94d954
MP
605 s->stopping = true;
606
b4f78aea
LP
607 if (s->fifo_path) {
608 int fd;
609
610 /* If we open an unopened pipe for reading we will not
611 get an EOF. to trigger an EOF we hence open it for
be94d954
MP
612 writing, but close it right away which then will
613 trigger the EOF. This will happen immediately if no
614 other process has the FIFO open for writing, i. e.
615 when the session died before logind (re)started. */
b4f78aea
LP
616
617 fd = session_create_fifo(s);
03e334a1 618 safe_close(fd);
b4f78aea
LP
619 }
620
b895a735 621 if (realtime)
d68c645b 622 (void) deserialize_usec(realtime, &s->timestamp.realtime);
b895a735 623 if (monotonic)
d68c645b 624 (void) deserialize_usec(monotonic, &s->timestamp.monotonic);
a185c5aa 625
aed24c4c
FB
626 if (active) {
627 k = parse_boolean(active);
628 if (k >= 0)
629 s->was_active = k;
630 }
631
1c8280fd
LP
632 if (is_display) {
633 /* Note that when enumerating users are loaded before sessions, hence the display session to use is
634 * something we have to store along with the session and not the user, as in that case we couldn't
635 * apply it at the time we load the user. */
636
637 k = parse_boolean(is_display);
638 if (k < 0)
639 log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m");
640 else if (k > 0)
641 s->user->display = s;
642 }
643
6d33772f 644 if (controller) {
aed24c4c 645 if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
dc6284e9 646 session_set_controller(s, controller, false, false);
aed24c4c
FB
647 session_load_devices(s, devices);
648 } else
90a18413 649 session_restore_vt(s);
6d33772f
DH
650 }
651
9d5b6901
MY
652 if (leader_pid) {
653 assert(!pidref_is_set(&s->leader));
654
655 r = parse_pid(leader_pid, &s->deserialized_pid);
656 if (r < 0)
657 return log_error_errno(r, "Failed to parse LEADER=%s: %m", leader_pid);
658
659 if (leader_fd_saved) {
660 r = parse_boolean(leader_fd_saved);
661 if (r < 0)
662 return log_error_errno(r, "Failed to parse LEADER_FD_SAVED=%s: %m", leader_fd_saved);
663 s->leader_fd_saved = r > 0;
664
665 if (s->leader_fd_saved)
666 /* The leader fd will be acquired from fdstore later */
667 return 0;
668 }
669
670 _cleanup_(pidref_done) PidRef p = PIDREF_NULL;
671
672 r = pidref_set_pid(&p, s->deserialized_pid);
673 if (r >= 0)
674 r = session_set_leader_consume(s, TAKE_PIDREF(p));
675 if (r < 0)
676 log_warning_errno(r, "Failed to set leader PID for session '%s': %m", s->id);
677 }
678
a185c5aa 679 return r;
20263082
LP
680}
681
682int session_activate(Session *s) {
14cb109d 683 unsigned num_pending;
d7bd01b5 684
20263082 685 assert(s);
9444b1f2 686 assert(s->user);
20263082 687
20263082 688 if (!s->seat)
15411c0c 689 return -EOPNOTSUPP;
20263082
LP
690
691 if (s->seat->active == s)
692 return 0;
693
d7bd01b5
DH
694 /* on seats with VTs, we let VTs manage session-switching */
695 if (seat_has_vts(s->seat)) {
709d0587 696 if (s->vtnr == 0)
15411c0c 697 return -EOPNOTSUPP;
d7bd01b5
DH
698
699 return chvt(s->vtnr);
700 }
701
702 /* On seats without VTs, we implement session-switching in logind. We
703 * try to pause all session-devices and wait until the session
704 * controller acknowledged them. Once all devices are asleep, we simply
705 * switch the active session and be done.
706 * We save the session we want to switch to in seat->pending_switch and
707 * seat_complete_switch() will perform the final switch. */
708
709 s->seat->pending_switch = s;
710
711 /* if no devices are running, immediately perform the session switch */
712 num_pending = session_device_try_pause_all(s);
713 if (!num_pending)
714 seat_complete_switch(s->seat);
20263082 715
d7bd01b5 716 return 0;
20263082
LP
717}
718
25a1ab4e 719static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_error *error) {
52bcc872
MY
720 _cleanup_free_ char *scope = NULL;
721 const char *description;
98a28fef
LP
722 int r;
723
724 assert(s);
9444b1f2 725 assert(s->user);
98a28fef 726
5099a50d
LP
727 if (!SESSION_CLASS_WANTS_SCOPE(s->class))
728 return 0;
729
52bcc872
MY
730 if (s->scope)
731 goto finish;
732
733 s->scope_job = mfree(s->scope_job);
734
735 scope = strjoin("session-", s->id, ".scope");
736 if (!scope)
737 return log_oom();
738
739 description = strjoina("Session ", s->id, " of User ", s->user->user_record->user_name);
740
741 r = manager_start_scope(
742 s->manager,
743 scope,
744 &s->leader,
8ba3efed 745 /* allow_pidfd = */ true,
52bcc872
MY
746 s->user->slice,
747 description,
748 /* These should have been pulled in explicitly in user_start(). Just to be sure. */
749 STRV_MAKE_CONST(s->user->runtime_dir_unit,
750 SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service_manager_unit : NULL),
751 /* We usually want to order session scopes after systemd-user-sessions.service
752 * since the unit is used as login session barrier for unprivileged users. However
753 * the barrier doesn't apply for root as sysadmin should always be able to log in
754 * (and without waiting for any timeout to expire) in case something goes wrong
755 * during the boot process. */
756 STRV_MAKE_CONST("systemd-logind.service",
757 SESSION_CLASS_IS_EARLY(s->class) ? NULL : "systemd-user-sessions.service"),
758 user_record_home_directory(s->user->user_record),
759 properties,
760 error,
761 &s->scope_job);
762 if (r < 0)
763 return log_error_errno(r, "Failed to start session scope %s: %s",
764 scope, bus_error_message(error, r));
fb2367ed 765
52bcc872 766 s->scope = TAKE_PTR(scope);
20263082 767
52bcc872 768finish:
124d7cb2 769 (void) hashmap_put(s->manager->session_units, s->scope, s);
20263082
LP
770 return 0;
771}
772
82325af3
MS
773static int session_dispatch_stop_on_idle(sd_event_source *source, uint64_t t, void *userdata) {
774 Session *s = userdata;
775 dual_timestamp ts;
776 int r, idle;
777
778 assert(s);
779
780 if (s->stopping)
781 return 0;
782
783 idle = session_get_idle_hint(s, &ts);
784 if (idle) {
6269ffe7 785 log_info("Session \"%s\" of user \"%s\" is idle, stopping.", s->id, s->user->user_record->user_name);
82325af3
MS
786
787 return session_stop(s, /* force */ true);
788 }
789
ab7ae746
MS
790 r = sd_event_source_set_time(
791 source,
792 usec_add(dual_timestamp_is_set(&ts) ? ts.monotonic : now(CLOCK_MONOTONIC),
793 s->manager->stop_idle_session_usec));
82325af3
MS
794 if (r < 0)
795 return log_error_errno(r, "Failed to configure stop on idle session event source: %m");
796
797 r = sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
798 if (r < 0)
799 return log_error_errno(r, "Failed to enable stop on idle session event source: %m");
800
801 return 1;
802}
803
804static int session_setup_stop_on_idle_timer(Session *s) {
805 int r;
806
807 assert(s);
808
ad23439e 809 if (s->manager->stop_idle_session_usec == USEC_INFINITY || !SESSION_CLASS_CAN_STOP_ON_IDLE(s->class))
82325af3
MS
810 return 0;
811
812 r = sd_event_add_time_relative(
813 s->manager->event,
814 &s->stop_on_idle_event_source,
815 CLOCK_MONOTONIC,
816 s->manager->stop_idle_session_usec,
817 0,
818 session_dispatch_stop_on_idle, s);
819 if (r < 0)
820 return log_error_errno(r, "Failed to add stop on idle session event source: %m");
821
822 return 0;
823}
824
25a1ab4e 825int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
20263082
LP
826 int r;
827
828 assert(s);
9444b1f2
LP
829
830 if (!s->user)
831 return -ESTALE;
20263082 832
25a1ab4e
LP
833 if (s->stopping)
834 return -EINVAL;
835
9418f147
LP
836 if (s->started)
837 return 0;
838
513cf7da 839 r = user_start(s->user);
ed18b08b
LP
840 if (r < 0)
841 return r;
842
25a1ab4e 843 r = session_start_scope(s, properties, error);
fb6becb4
LP
844 if (r < 0)
845 return r;
846
82325af3
MS
847 r = session_setup_stop_on_idle_timer(s);
848 if (r < 0)
849 return r;
850
d9eb81f9 851 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
2b044526 852 "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
877d54e9 853 "SESSION_ID=%s", s->id,
22c902fa 854 "USER_ID=%s", s->user->user_record->user_name,
89bad70f 855 "LEADER="PID_FMT, s->leader.pid,
22c902fa 856 LOG_MESSAGE("New session %s of user %s.", s->id, s->user->user_record->user_name));
98a28fef 857
9444b1f2 858 if (!dual_timestamp_is_set(&s->timestamp))
fa5a0251 859 dual_timestamp_now(&s->timestamp);
14c3baca 860
e9816c48
LP
861 if (s->seat)
862 seat_read_active_vt(s->seat);
863
9418f147
LP
864 s->started = true;
865
952d3260
LP
866 user_elect_display(s->user);
867
5f41d1f1 868 /* Save data */
5157b0d8
LP
869 (void) session_save(s);
870 (void) user_save(s->user);
5f41d1f1 871 if (s->seat)
5157b0d8 872 (void) seat_save(s->seat);
e9816c48 873
5f41d1f1 874 /* Send signals */
da119395 875 session_send_signal(s, true);
7d049e30 876 user_send_changed(s->user, "Display", NULL);
40771cf5
LP
877
878 if (s->seat && s->seat->active == s)
5157b0d8 879 (void) seat_send_changed(s->seat, "ActiveSession", NULL);
9418f147 880
20263082
LP
881 return 0;
882}
883
9bb69af4 884static int session_stop_scope(Session *s, bool force) {
4afd3348 885 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
20263082 886 int r;
20263082
LP
887
888 assert(s);
889
fb6becb4
LP
890 if (!s->scope)
891 return 0;
9b221b63 892
756ed0e2 893 /* Let's always abandon the scope first. This tells systemd that we are not interested anymore, and everything
629ff674 894 * that is left in the scope is "left-over". Informing systemd about this has the benefit that it will log
756ed0e2
LP
895 * when killing any processes left after this point. */
896 r = manager_abandon_scope(s->manager, s->scope, &error);
25a1ab4e 897 if (r < 0) {
756ed0e2 898 log_warning_errno(r, "Failed to abandon session scope, ignoring: %s", bus_error_message(&error, r));
25a1ab4e
LP
899 sd_bus_error_free(&error);
900 }
901
902 s->scope_job = mfree(s->scope_job);
756ed0e2
LP
903
904 /* Optionally, let's kill everything that's left now. */
156a3637
LP
905 if (force ||
906 (s->user->user_record->kill_processes != 0 &&
907 (s->user->user_record->kill_processes > 0 ||
908 manager_shall_kill(s->manager, s->user->user_record->user_name)))) {
801a884d 909
1a42ce09 910 r = manager_stop_unit(s->manager, s->scope, force ? "replace" : "fail", &error, &s->scope_job);
25a1ab4e
LP
911 if (r < 0) {
912 if (force)
913 return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));
20263082 914
25a1ab4e
LP
915 log_warning_errno(r, "Failed to stop session scope, ignoring: %s", bus_error_message(&error, r));
916 }
8150acb1 917 } else {
20263082 918
8150acb1
AJ
919 /* With no killing, this session is allowed to persist in "closing" state indefinitely.
920 * Therefore session stop and session removal may be two distinct events.
921 * Session stop is quite significant on its own, let's log it. */
922 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
923 "SESSION_ID=%s", s->id,
22c902fa 924 "USER_ID=%s", s->user->user_record->user_name,
89bad70f 925 "LEADER="PID_FMT, s->leader.pid,
f4cf1d66 926 LOG_MESSAGE("Session %s logged out. Waiting for processes to exit.", s->id));
8150acb1
AJ
927 }
928
9b221b63 929 return 0;
20263082
LP
930}
931
9bb69af4 932int session_stop(Session *s, bool force) {
405e0255
LP
933 int r;
934
935 assert(s);
936
25a1ab4e
LP
937 /* This is called whenever we begin with tearing down a session record. It's called in four cases: explicit API
938 * request via the bus (either directly for the session object or for the seat or user object this session
939 * belongs to; 'force' is true), or due to automatic GC (i.e. scope vanished; 'force' is false), or because the
940 * session FIFO saw an EOF ('force' is false), or because the release timer hit ('force' is false). */
941
405e0255
LP
942 if (!s->user)
943 return -ESTALE;
25a1ab4e
LP
944 if (!s->started)
945 return 0;
946 if (s->stopping)
947 return 0;
405e0255 948
5f41d1f1 949 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
76f2191d 950 s->leader_pidfd_event_source = sd_event_source_unref(s->leader_pidfd_event_source);
5f41d1f1 951
10189fd6
DH
952 if (s->seat)
953 seat_evict_position(s->seat, s);
954
5f41d1f1
LP
955 /* We are going down, don't care about FIFOs anymore */
956 session_remove_fifo(s);
957
405e0255 958 /* Kill cgroup */
9bb69af4 959 r = session_stop_scope(s, force);
405e0255 960
5f41d1f1
LP
961 s->stopping = true;
962
952d3260
LP
963 user_elect_display(s->user);
964
5157b0d8
LP
965 (void) session_save(s);
966 (void) user_save(s->user);
405e0255
LP
967
968 return r;
969}
970
971int session_finalize(Session *s) {
118ecf32 972 SessionDevice *sd;
20263082
LP
973
974 assert(s);
975
9444b1f2
LP
976 if (!s->user)
977 return -ESTALE;
978
ed18b08b 979 if (s->started)
d9eb81f9 980 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
2b044526 981 "MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
877d54e9 982 "SESSION_ID=%s", s->id,
22c902fa 983 "USER_ID=%s", s->user->user_record->user_name,
89bad70f 984 "LEADER="PID_FMT, s->leader.pid,
a1230ff9 985 LOG_MESSAGE("Removed session %s.", s->id));
98a28fef 986
5f41d1f1
LP
987 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
988
10189fd6
DH
989 if (s->seat)
990 seat_evict_position(s->seat, s);
991
118ecf32
DH
992 /* Kill session devices */
993 while ((sd = hashmap_first(s->devices)))
994 session_device_free(sd);
995
491ac9f2 996 (void) unlink(s->state_file);
d2f92cdf 997 session_add_to_gc_queue(s);
ed18b08b 998 user_add_to_gc_queue(s->user);
14c3baca 999
405e0255 1000 if (s->started) {
ed18b08b 1001 session_send_signal(s, false);
405e0255
LP
1002 s->started = false;
1003 }
50fb9793 1004
9418f147
LP
1005 if (s->seat) {
1006 if (s->seat->active == s)
1007 seat_set_active(s->seat, NULL);
1008
23bd3b62 1009 seat_save(s->seat);
9418f147
LP
1010 }
1011
9d5b6901 1012 session_reset_leader(s, /* keep_fdstore = */ false);
76f2191d 1013
5157b0d8
LP
1014 (void) user_save(s->user);
1015 (void) user_send_changed(s->user, "Display", NULL);
9418f147 1016
491ac9f2 1017 return 0;
20263082
LP
1018}
1019
5f41d1f1 1020static int release_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) {
99534007 1021 Session *s = ASSERT_PTR(userdata);
5f41d1f1
LP
1022
1023 assert(es);
5f41d1f1 1024
bda62573 1025 session_stop(s, /* force = */ false);
5f41d1f1
LP
1026 return 0;
1027}
1028
ad8780c9 1029int session_release(Session *s) {
5f41d1f1
LP
1030 assert(s);
1031
1032 if (!s->started || s->stopping)
ad8780c9
ZJS
1033 return 0;
1034
1035 if (s->timer_event_source)
1036 return 0;
1037
39cf0351
LP
1038 return sd_event_add_time_relative(
1039 s->manager->event,
1040 &s->timer_event_source,
1041 CLOCK_MONOTONIC,
1042 RELEASE_USEC, 0,
1043 release_timeout_callback, s);
5f41d1f1
LP
1044}
1045
20263082
LP
1046bool session_is_active(Session *s) {
1047 assert(s);
1048
1049 if (!s->seat)
1050 return true;
1051
1052 return s->seat->active == s;
1053}
1054
23406ce5
LP
1055static int get_tty_atime(const char *tty, usec_t *atime) {
1056 _cleanup_free_ char *p = NULL;
a185c5aa 1057 struct stat st;
23406ce5
LP
1058
1059 assert(tty);
1060 assert(atime);
1061
1062 if (!path_is_absolute(tty)) {
b910cc72 1063 p = path_join("/dev", tty);
23406ce5
LP
1064 if (!p)
1065 return -ENOMEM;
1066
1067 tty = p;
1068 } else if (!path_startswith(tty, "/dev/"))
1069 return -ENOENT;
1070
1071 if (lstat(tty, &st) < 0)
1072 return -errno;
1073
1074 *atime = timespec_load(&st.st_atim);
1075 return 0;
1076}
1077
1078static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
1079 _cleanup_free_ char *p = NULL;
1080 int r;
1081
1082 assert(pid > 0);
1083 assert(atime);
1084
1085 r = get_ctty(pid, NULL, &p);
1086 if (r < 0)
1087 return r;
1088
1089 return get_tty_atime(p, atime);
1090}
1091
1092int session_get_idle_hint(Session *s, dual_timestamp *t) {
82325af3 1093 usec_t atime = 0, dtime = 0;
23406ce5 1094 int r;
a185c5aa
LP
1095
1096 assert(s);
1097
be2bb14f
LP
1098 /* Graphical sessions have an explicit idle hint */
1099 if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
a185c5aa
LP
1100 if (t)
1101 *t = s->idle_hint_timestamp;
1102
1103 return s->idle_hint;
1104 }
1105
20604ff2
LP
1106 if (s->type == SESSION_TTY) {
1107 /* For sessions with an explicitly configured tty, let's check its atime */
1108 if (s->tty) {
1109 r = get_tty_atime(s->tty, &atime);
1110 if (r >= 0)
1111 goto found_atime;
1112 }
a185c5aa 1113
20604ff2
LP
1114 /* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
1115 * the leader */
1116 if (pidref_is_set(&s->leader)) {
1117 r = get_process_ctty_atime(s->leader.pid, &atime);
1118 if (r >= 0)
1119 goto found_atime;
1120 }
a185c5aa
LP
1121 }
1122
a185c5aa 1123 if (t)
be2bb14f 1124 *t = DUAL_TIMESTAMP_NULL;
a185c5aa 1125
be2bb14f 1126 return false;
23406ce5
LP
1127
1128found_atime:
1129 if (t)
1130 dual_timestamp_from_realtime(t, atime);
1131
82325af3
MS
1132 if (s->manager->idle_action_usec > 0 && s->manager->stop_idle_session_usec != USEC_INFINITY)
1133 dtime = MIN(s->manager->idle_action_usec, s->manager->stop_idle_session_usec);
1134 else if (s->manager->idle_action_usec > 0)
1135 dtime = s->manager->idle_action_usec;
1136 else if (s->manager->stop_idle_session_usec != USEC_INFINITY)
1137 dtime = s->manager->stop_idle_session_usec;
1138 else
be2bb14f 1139 return false;
23406ce5 1140
82325af3 1141 return usec_add(atime, dtime) <= now(CLOCK_REALTIME);
a185c5aa
LP
1142}
1143
be2bb14f 1144int session_set_idle_hint(Session *s, bool b) {
bef422ae
LP
1145 assert(s);
1146
b4f01bc1
LP
1147 if (!SESSION_CLASS_CAN_IDLE(s->class)) /* Only some session classes know the idle concept at all */
1148 return -ENOTTY;
1149 if (!SESSION_TYPE_IS_GRAPHICAL(s->type)) /* And only graphical session types can set the field explicitly */
be2bb14f
LP
1150 return -ENOTTY;
1151
bef422ae 1152 if (s->idle_hint == b)
be2bb14f 1153 return 0;
bef422ae
LP
1154
1155 s->idle_hint = b;
fa5a0251 1156 dual_timestamp_now(&s->idle_hint_timestamp);
9418f147 1157
cc377381 1158 session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
9418f147
LP
1159
1160 if (s->seat)
cc377381
LP
1161 seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1162
1163 user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1164 manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
be2bb14f
LP
1165
1166 return 1;
cc377381
LP
1167}
1168
42d35e13
VT
1169int session_get_locked_hint(Session *s) {
1170 assert(s);
1171
1172 return s->locked_hint;
1173}
1174
b4f01bc1 1175int session_set_locked_hint(Session *s, bool b) {
42d35e13
VT
1176 assert(s);
1177
b4f01bc1
LP
1178 if (!SESSION_CLASS_CAN_LOCK(s->class))
1179 return -ENOTTY;
1180
42d35e13 1181 if (s->locked_hint == b)
b4f01bc1 1182 return 0;
42d35e13
VT
1183
1184 s->locked_hint = b;
b4f01bc1
LP
1185 (void) session_save(s);
1186 (void) session_send_changed(s, "LockedHint", NULL);
42d35e13 1187
b4f01bc1 1188 return 1;
42d35e13
VT
1189}
1190
db72aea4
CH
1191void session_set_type(Session *s, SessionType t) {
1192 assert(s);
1193
1194 if (s->type == t)
1195 return;
1196
1197 s->type = t;
5157b0d8
LP
1198 (void) session_save(s);
1199 (void) session_send_changed(s, "Type", NULL);
db72aea4
CH
1200}
1201
6e9bf0ad
LP
1202void session_set_class(Session *s, SessionClass c) {
1203 assert(s);
1204
1205 if (s->class == c)
1206 return;
1207
1208 s->class = c;
1209 (void) session_save(s);
1210 (void) session_send_changed(s, "Class", NULL);
1211
e2a42c0c
MY
1212 /* This class change might mean we need the per-user session manager now. Try to start it. */
1213 (void) user_start_service_manager(s->user);
6e9bf0ad
LP
1214}
1215
4885d749
DT
1216int session_set_display(Session *s, const char *display) {
1217 int r;
1218
1219 assert(s);
1220 assert(display);
1221
4885d749 1222 r = free_and_strdup(&s->display, display);
e5c09aad 1223 if (r <= 0) /* 0 means the strings were equal */
4885d749
DT
1224 return r;
1225
5157b0d8
LP
1226 (void) session_save(s);
1227 (void) session_send_changed(s, "Display", NULL);
4885d749
DT
1228
1229 return 1;
1230}
1231
092e6cd1
TK
1232int session_set_tty(Session *s, const char *tty) {
1233 int r;
1234
1235 assert(s);
1236 assert(tty);
1237
1238 r = free_and_strdup(&s->tty, tty);
1239 if (r <= 0) /* 0 means the strings were equal */
1240 return r;
1241
5157b0d8
LP
1242 (void) session_save(s);
1243 (void) session_send_changed(s, "TTY", NULL);
092e6cd1
TK
1244
1245 return 1;
1246}
1247
cc377381 1248static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
99534007 1249 Session *s = ASSERT_PTR(userdata);
cc377381 1250
cc377381
LP
1251 assert(s->fifo_fd == fd);
1252
1253 /* EOF on the FIFO means the session died abnormally. */
1254
1255 session_remove_fifo(s);
bda62573 1256 session_stop(s, /* force = */ false);
cc377381
LP
1257
1258 return 1;
bef422ae
LP
1259}
1260
932e3ee7
LP
1261int session_create_fifo(Session *s) {
1262 int r;
1263
31b79c2b
LP
1264 assert(s);
1265
b4f78aea 1266 /* Create FIFO */
932e3ee7 1267 if (!s->fifo_path) {
37c1d5e9 1268 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
e6061ab2
LP
1269 if (r < 0)
1270 return r;
1271
d5ddc930
LP
1272 s->fifo_path = strjoin("/run/systemd/sessions/", s->id, ".ref");
1273 if (!s->fifo_path)
932e3ee7 1274 return -ENOMEM;
31b79c2b 1275
932e3ee7
LP
1276 if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
1277 return -errno;
1278 }
31b79c2b 1279
932e3ee7 1280 /* Open reading side */
b4f78aea 1281 if (s->fifo_fd < 0) {
db4a47e9 1282 s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
b4f78aea
LP
1283 if (s->fifo_fd < 0)
1284 return -errno;
cc377381
LP
1285 }
1286
1287 if (!s->fifo_event_source) {
151b9b96 1288 r = sd_event_add_io(s->manager->event, &s->fifo_event_source, s->fifo_fd, 0, session_dispatch_fifo, s);
b4f78aea
LP
1289 if (r < 0)
1290 return r;
1291
6c75e317
ZJS
1292 /* Let's make sure we noticed dead sessions before we process new bus requests (which might
1293 * create new sessions). */
e11544a8 1294 r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_NORMAL-10);
cc377381
LP
1295 if (r < 0)
1296 return r;
b4f78aea 1297 }
932e3ee7
LP
1298
1299 /* Open writing side */
7c248223 1300 return RET_NERRNO(open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK));
932e3ee7
LP
1301}
1302
5f41d1f1 1303static void session_remove_fifo(Session *s) {
932e3ee7
LP
1304 assert(s);
1305
03e334a1
LP
1306 s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
1307 s->fifo_fd = safe_close(s->fifo_fd);
489f67b4 1308 s->fifo_path = unlink_and_free(s->fifo_path);
31b79c2b
LP
1309}
1310
5c093a23 1311bool session_may_gc(Session *s, bool drop_not_started) {
bd26aee1
LP
1312 int r;
1313
20263082
LP
1314 assert(s);
1315
4a4b033f 1316 if (drop_not_started && !s->started)
5c093a23 1317 return true;
932e3ee7 1318
9444b1f2 1319 if (!s->user)
5c093a23 1320 return true;
9444b1f2 1321
76f2191d 1322 r = pidref_is_alive(&s->leader);
9d5b6901
MY
1323 if (r == -ESRCH)
1324 /* Session has no leader. This is probably because the leader vanished before deserializing
1325 * pidfd from FD store. */
1326 return true;
76f2191d 1327 if (r < 0)
9d5b6901 1328 log_debug_errno(r, "Unable to determine if leader PID " PID_FMT " is still alive, assuming not: %m", s->leader.pid);
76f2191d
MS
1329 if (r > 0)
1330 return false;
1331
9d5b6901
MY
1332 if (s->fifo_fd >= 0 && pipe_eof(s->fifo_fd) <= 0)
1333 return false;
20263082 1334
bd26aee1
LP
1335 if (s->scope_job) {
1336 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1337
1338 r = manager_job_is_active(s->manager, s->scope_job, &error);
1339 if (r < 0)
1340 log_debug_errno(r, "Failed to determine whether job '%s' is pending, ignoring: %s", s->scope_job, bus_error_message(&error, r));
1341 if (r != 0)
1342 return false;
1343 }
20263082 1344
bd26aee1
LP
1345 if (s->scope) {
1346 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1347
1348 r = manager_unit_is_active(s->manager, s->scope, &error);
1349 if (r < 0)
1350 log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring: %s", s->scope, bus_error_message(&error, r));
1351 if (r != 0)
1352 return false;
1353 }
20263082 1354
5c093a23 1355 return true;
20263082
LP
1356}
1357
14c3baca
LP
1358void session_add_to_gc_queue(Session *s) {
1359 assert(s);
1360
1361 if (s->in_gc_queue)
1362 return;
1363
71fda00f 1364 LIST_PREPEND(gc_queue, s->manager->session_gc_queue, s);
14c3baca
LP
1365 s->in_gc_queue = true;
1366}
1367
0604381b
LP
1368SessionState session_get_state(Session *s) {
1369 assert(s);
1370
8fe63cd4 1371 /* always check closing first */
5f41d1f1
LP
1372 if (s->stopping || s->timer_event_source)
1373 return SESSION_CLOSING;
1374
76f2191d 1375 if (s->scope_job || (!pidref_is_set(&s->leader) && s->fifo_fd < 0))
405e0255 1376 return SESSION_OPENING;
fb6becb4 1377
0604381b
LP
1378 if (session_is_active(s))
1379 return SESSION_ACTIVE;
1380
1381 return SESSION_ONLINE;
1382}
1383
de07ab16 1384int session_kill(Session *s, KillWho who, int signo) {
de07ab16
LP
1385 assert(s);
1386
fb6becb4 1387 if (!s->scope)
de07ab16
LP
1388 return -ESRCH;
1389
fb6becb4 1390 return manager_kill_unit(s->manager, s->scope, who, signo, NULL);
de07ab16
LP
1391}
1392
93041c60
MY
1393static int session_open_vt(Session *s, bool reopen) {
1394 _cleanup_close_ int fd = -EBADF;
5f41d1f1 1395 char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)];
90a18413 1396
a8d5378a
MY
1397 assert(s);
1398
baccf3e4
OB
1399 if (s->vtnr < 1)
1400 return -ENODEV;
90a18413 1401
93041c60 1402 if (!reopen && s->vtfd >= 0)
90a18413
DH
1403 return s->vtfd;
1404
92bd5ff3 1405 sprintf(path, "/dev/tty%u", s->vtnr);
90a18413 1406
93041c60
MY
1407 fd = open_terminal(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
1408 if (fd < 0)
1409 return log_error_errno(fd, "Cannot open VT %s of session %s: %m", path, s->id);
1410
1411 close_and_replace(s->vtfd, fd);
90a18413
DH
1412 return s->vtfd;
1413}
1414
a03cdb17 1415static int session_prepare_vt(Session *s) {
90a18413 1416 int vt, r;
9fb2c8b8 1417 struct vt_mode mode = {};
90a18413 1418
a8d5378a
MY
1419 assert(s);
1420
baccf3e4
OB
1421 if (s->vtnr < 1)
1422 return 0;
1423
93041c60 1424 vt = session_open_vt(s, /* reopen = */ false);
90a18413 1425 if (vt < 0)
baccf3e4 1426 return vt;
90a18413 1427
22c902fa 1428 r = fchown(vt, s->user->user_record->uid, -1);
baccf3e4 1429 if (r < 0) {
94c156cd
LP
1430 r = log_error_errno(errno,
1431 "Cannot change owner of /dev/tty%u: %m",
1432 s->vtnr);
d6176c6c 1433 goto error;
baccf3e4 1434 }
d6176c6c 1435
90a18413 1436 r = ioctl(vt, KDSKBMODE, K_OFF);
baccf3e4 1437 if (r < 0) {
94c156cd
LP
1438 r = log_error_errno(errno,
1439 "Cannot set K_OFF on /dev/tty%u: %m",
1440 s->vtnr);
90a18413 1441 goto error;
baccf3e4 1442 }
90a18413
DH
1443
1444 r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
baccf3e4 1445 if (r < 0) {
94c156cd
LP
1446 r = log_error_errno(errno,
1447 "Cannot set KD_GRAPHICS on /dev/tty%u: %m",
1448 s->vtnr);
90a18413 1449 goto error;
baccf3e4 1450 }
90a18413 1451
90a18413
DH
1452 /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS.
1453 * So we need a dummy handler here which just acknowledges *all* VT
1454 * switch requests. */
1455 mode.mode = VT_PROCESS;
92683ad2
DH
1456 mode.relsig = SIGRTMIN;
1457 mode.acqsig = SIGRTMIN + 1;
90a18413 1458 r = ioctl(vt, VT_SETMODE, &mode);
baccf3e4 1459 if (r < 0) {
94c156cd
LP
1460 r = log_error_errno(errno,
1461 "Cannot set VT_PROCESS on /dev/tty%u: %m",
1462 s->vtnr);
90a18413 1463 goto error;
baccf3e4 1464 }
90a18413 1465
baccf3e4 1466 return 0;
90a18413
DH
1467
1468error:
90a18413 1469 session_restore_vt(s);
baccf3e4 1470 return r;
90a18413
DH
1471}
1472
0212126c 1473static void session_restore_vt(Session *s) {
8246905a 1474 int r;
128df4cf 1475
a8d5378a
MY
1476 assert(s);
1477
092e6cd1
TK
1478 if (s->vtfd < 0)
1479 return;
1480
8246905a
FB
1481 r = vt_restore(s->vtfd);
1482 if (r == -EIO) {
8246905a
FB
1483 /* It might happen if the controlling process exited before or while we were
1484 * restoring the VT as it would leave the old file-descriptor in a hung-up
1485 * state. In this case let's retry with a fresh handle to the virtual terminal. */
ad96887a 1486
8246905a
FB
1487 /* We do a little dance to avoid having the terminal be available
1488 * for reuse before we've cleaned it up. */
8246905a 1489
93041c60
MY
1490 int fd = session_open_vt(s, /* reopen = */ true);
1491 if (fd >= 0)
1492 r = vt_restore(fd);
8246905a 1493 }
c0f34168
FB
1494 if (r < 0)
1495 log_warning_errno(r, "Failed to restore VT, ignoring: %m");
d6176c6c 1496
03e334a1 1497 s->vtfd = safe_close(s->vtfd);
90a18413
DH
1498}
1499
2ec3ff66 1500void session_leave_vt(Session *s) {
ce540a24
DH
1501 int r;
1502
2ec3ff66
DH
1503 assert(s);
1504
1505 /* This is called whenever we get a VT-switch signal from the kernel.
1506 * We acknowledge all of them unconditionally. Note that session are
1507 * free to overwrite those handlers and we only register them for
1508 * sessions with controllers. Legacy sessions are not affected.
1509 * However, if we switch from a non-legacy to a legacy session, we must
1510 * make sure to pause all device before acknowledging the switch. We
1511 * process the real switch only after we are notified via sysfs, so the
1512 * legacy session might have already started using the devices. If we
1513 * don't pause the devices before the switch, we might confuse the
1514 * session we switch to. */
1515
1516 if (s->vtfd < 0)
1517 return;
1518
1519 session_device_pause_all(s);
93041c60 1520 r = vt_release(s->vtfd, /* restore = */ false);
99d4ad71 1521 if (r == -EIO) {
93041c60 1522 /* Handle the same VT hung-up case as in session_restore_vt */
99d4ad71 1523
93041c60
MY
1524 int fd = session_open_vt(s, /* reopen = */ true);
1525 if (fd >= 0)
1526 r = vt_release(fd, /* restore = */ false);
99d4ad71 1527 }
ce540a24 1528 if (r < 0)
27dafac9 1529 log_debug_errno(r, "Cannot release VT of session %s: %m", s->id);
2ec3ff66
DH
1530}
1531
cc377381 1532bool session_is_controller(Session *s, const char *sender) {
e5c09aad 1533 return streq_ptr(ASSERT_PTR(s)->controller, sender);
ae5e06bd
DH
1534}
1535
b12e5615 1536static void session_release_controller(Session *s, bool notify) {
d7ac0952 1537 _unused_ _cleanup_free_ char *name = NULL;
6d33772f
DH
1538 SessionDevice *sd;
1539
a8d5378a
MY
1540 assert(s);
1541
b12e5615
DH
1542 if (!s->controller)
1543 return;
6d33772f 1544
b12e5615 1545 name = s->controller;
90a18413 1546
6c75e317
ZJS
1547 /* By resetting the controller before releasing the devices, we won't send notification signals.
1548 * This avoids sending useless notifications if the controller is released on disconnects. */
b12e5615
DH
1549 if (!notify)
1550 s->controller = NULL;
6d33772f 1551
b12e5615
DH
1552 while ((sd = hashmap_first(s->devices)))
1553 session_device_free(sd);
1554
1555 s->controller = NULL;
3cde9e8f
DM
1556 s->track = sd_bus_track_unref(s->track);
1557}
1558
1559static int on_bus_track(sd_bus_track *track, void *userdata) {
99534007 1560 Session *s = ASSERT_PTR(userdata);
3cde9e8f
DM
1561
1562 assert(track);
3cde9e8f
DM
1563
1564 session_drop_controller(s);
1565
1566 return 0;
6d33772f
DH
1567}
1568
dc6284e9 1569int session_set_controller(Session *s, const char *sender, bool force, bool prepare) {
b12e5615 1570 _cleanup_free_ char *name = NULL;
ae5e06bd
DH
1571 int r;
1572
1573 assert(s);
1574 assert(sender);
1575
1576 if (session_is_controller(s, sender))
1577 return 0;
1578 if (s->controller && !force)
1579 return -EBUSY;
1580
b12e5615
DH
1581 name = strdup(sender);
1582 if (!name)
ae5e06bd
DH
1583 return -ENOMEM;
1584
3cde9e8f
DM
1585 s->track = sd_bus_track_unref(s->track);
1586 r = sd_bus_track_new(s->manager->bus, &s->track, on_bus_track, s);
1587 if (r < 0)
1588 return r;
1589
1590 r = sd_bus_track_add_name(s->track, name);
1591 if (r < 0)
ae5e06bd 1592 return r;
ae5e06bd 1593
90a18413
DH
1594 /* When setting a session controller, we forcibly mute the VT and set
1595 * it into graphics-mode. Applications can override that by changing
1596 * VT state after calling TakeControl(). However, this serves as a good
1597 * default and well-behaving controllers can now ignore VTs entirely.
1598 * Note that we reset the VT on ReleaseControl() and if the controller
1599 * exits.
1600 * If logind crashes/restarts, we restore the controller during restart
dc6284e9
FB
1601 * (without preparing the VT since the controller has probably overridden
1602 * VT state by now) or reset the VT in case it crashed/exited, too. */
1603 if (prepare) {
1604 r = session_prepare_vt(s);
1605 if (r < 0) {
1606 s->track = sd_bus_track_unref(s->track);
1607 return r;
1608 }
13f493dc 1609 }
baccf3e4 1610
b12e5615 1611 session_release_controller(s, true);
ae2a15bc 1612 s->controller = TAKE_PTR(name);
5157b0d8 1613 (void) session_save(s);
90a18413 1614
ae5e06bd
DH
1615 return 0;
1616}
1617
1618void session_drop_controller(Session *s) {
1619 assert(s);
1620
1621 if (!s->controller)
1622 return;
1623
3cde9e8f 1624 s->track = sd_bus_track_unref(s->track);
db72aea4 1625 session_set_type(s, s->original_type);
b12e5615 1626 session_release_controller(s, false);
5157b0d8 1627 (void) session_save(s);
b12e5615 1628 session_restore_vt(s);
ae5e06bd
DH
1629}
1630
fb6becb4
LP
1631static const char* const session_state_table[_SESSION_STATE_MAX] = {
1632 [SESSION_OPENING] = "opening",
6c75e317
ZJS
1633 [SESSION_ONLINE] = "online",
1634 [SESSION_ACTIVE] = "active",
1635 [SESSION_CLOSING] = "closing",
0604381b
LP
1636};
1637
1638DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
1639
20263082 1640static const char* const session_type_table[_SESSION_TYPE_MAX] = {
2c5859af 1641 [SESSION_UNSPECIFIED] = "unspecified",
6c75e317
ZJS
1642 [SESSION_TTY] = "tty",
1643 [SESSION_X11] = "x11",
1644 [SESSION_WAYLAND] = "wayland",
1645 [SESSION_MIR] = "mir",
1646 [SESSION_WEB] = "web",
20263082
LP
1647};
1648
1649DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
de07ab16 1650
55efac6c 1651static const char* const session_class_table[_SESSION_CLASS_MAX] = {
b5100c73
LP
1652 [SESSION_USER] = "user",
1653 [SESSION_USER_EARLY] = "user-early",
53ebde6d 1654 [SESSION_USER_INCOMPLETE] = "user-incomplete",
b5100c73
LP
1655 [SESSION_GREETER] = "greeter",
1656 [SESSION_LOCK_SCREEN] = "lock-screen",
1657 [SESSION_BACKGROUND] = "background",
1658 [SESSION_BACKGROUND_LIGHT] = "background-light",
1659 [SESSION_MANAGER] = "manager",
1660 [SESSION_MANAGER_EARLY] = "manager-early",
55efac6c
LP
1661};
1662
1663DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
1664
de07ab16
LP
1665static const char* const kill_who_table[_KILL_WHO_MAX] = {
1666 [KILL_LEADER] = "leader",
6c75e317 1667 [KILL_ALL] = "all",
de07ab16
LP
1668};
1669
1670DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
3d0ef5c7
LP
1671
1672static const char* const tty_validity_table[_TTY_VALIDITY_MAX] = {
6c75e317
ZJS
1673 [TTY_FROM_PAM] = "from-pam",
1674 [TTY_FROM_UTMP] = "from-utmp",
3d0ef5c7
LP
1675 [TTY_UTMP_INCONSISTENT] = "utmp-inconsistent",
1676};
1677
1678DEFINE_STRING_TABLE_LOOKUP(tty_validity, TTYValidity);