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