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