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 "user-util.h"
40 #include "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
session_new(Session ** ret,Manager * m,const char * id)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
session_free(Session * s)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 return mfree(s);
155 }
156
session_set_user(Session * s,User * u)157 void session_set_user(Session *s, User *u) {
158 assert(s);
159 assert(!s->user);
160
161 s->user = u;
162 LIST_PREPEND(sessions_by_user, u->sessions, s);
163
164 user_update_last_session_timer(u);
165 }
166
session_set_leader(Session * s,pid_t pid)167 int session_set_leader(Session *s, pid_t pid) {
168 int r;
169
170 assert(s);
171
172 if (!pid_is_valid(pid))
173 return -EINVAL;
174
175 if (s->leader == pid)
176 return 0;
177
178 r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
179 if (r < 0)
180 return r;
181
182 if (pid_is_valid(s->leader))
183 (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
184
185 s->leader = pid;
186 (void) audit_session_from_pid(pid, &s->audit_id);
187
188 return 1;
189 }
190
session_save_devices(Session * s,FILE * f)191 static void session_save_devices(Session *s, FILE *f) {
192 SessionDevice *sd;
193
194 if (!hashmap_isempty(s->devices)) {
195 fprintf(f, "DEVICES=");
196 HASHMAP_FOREACH(sd, s->devices)
197 fprintf(f, "%u:%u ", major(sd->dev), minor(sd->dev));
198 fprintf(f, "\n");
199 }
200 }
201
session_save(Session * s)202 int session_save(Session *s) {
203 _cleanup_free_ char *temp_path = NULL;
204 _cleanup_fclose_ FILE *f = NULL;
205 int r;
206
207 assert(s);
208
209 if (!s->user)
210 return -ESTALE;
211
212 if (!s->started)
213 return 0;
214
215 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
216 if (r < 0)
217 goto fail;
218
219 r = fopen_temporary(s->state_file, &f, &temp_path);
220 if (r < 0)
221 goto fail;
222
223 (void) fchmod(fileno(f), 0644);
224
225 fprintf(f,
226 "# This is private data. Do not parse.\n"
227 "UID="UID_FMT"\n"
228 "USER=%s\n"
229 "ACTIVE=%i\n"
230 "IS_DISPLAY=%i\n"
231 "STATE=%s\n"
232 "REMOTE=%i\n",
233 s->user->user_record->uid,
234 s->user->user_record->user_name,
235 session_is_active(s),
236 s->user->display == s,
237 session_state_to_string(session_get_state(s)),
238 s->remote);
239
240 if (s->type >= 0)
241 fprintf(f, "TYPE=%s\n", session_type_to_string(s->type));
242
243 if (s->original_type >= 0)
244 fprintf(f, "ORIGINAL_TYPE=%s\n", session_type_to_string(s->original_type));
245
246 if (s->class >= 0)
247 fprintf(f, "CLASS=%s\n", session_class_to_string(s->class));
248
249 if (s->scope)
250 fprintf(f, "SCOPE=%s\n", s->scope);
251 if (s->scope_job)
252 fprintf(f, "SCOPE_JOB=%s\n", s->scope_job);
253
254 if (s->fifo_path)
255 fprintf(f, "FIFO=%s\n", s->fifo_path);
256
257 if (s->seat)
258 fprintf(f, "SEAT=%s\n", s->seat->id);
259
260 if (s->tty)
261 fprintf(f, "TTY=%s\n", s->tty);
262
263 if (s->tty_validity >= 0)
264 fprintf(f, "TTY_VALIDITY=%s\n", tty_validity_to_string(s->tty_validity));
265
266 if (s->display)
267 fprintf(f, "DISPLAY=%s\n", s->display);
268
269 if (s->remote_host) {
270 _cleanup_free_ char *escaped = NULL;
271
272 escaped = cescape(s->remote_host);
273 if (!escaped) {
274 r = -ENOMEM;
275 goto fail;
276 }
277
278 fprintf(f, "REMOTE_HOST=%s\n", escaped);
279 }
280
281 if (s->remote_user) {
282 _cleanup_free_ char *escaped = NULL;
283
284 escaped = cescape(s->remote_user);
285 if (!escaped) {
286 r = -ENOMEM;
287 goto fail;
288 }
289
290 fprintf(f, "REMOTE_USER=%s\n", escaped);
291 }
292
293 if (s->service) {
294 _cleanup_free_ char *escaped = NULL;
295
296 escaped = cescape(s->service);
297 if (!escaped) {
298 r = -ENOMEM;
299 goto fail;
300 }
301
302 fprintf(f, "SERVICE=%s\n", escaped);
303 }
304
305 if (s->desktop) {
306 _cleanup_free_ char *escaped = NULL;
307
308 escaped = cescape(s->desktop);
309 if (!escaped) {
310 r = -ENOMEM;
311 goto fail;
312 }
313
314 fprintf(f, "DESKTOP=%s\n", escaped);
315 }
316
317 if (s->seat && seat_has_vts(s->seat))
318 fprintf(f, "VTNR=%u\n", s->vtnr);
319
320 if (!s->vtnr)
321 fprintf(f, "POSITION=%u\n", s->position);
322
323 if (pid_is_valid(s->leader))
324 fprintf(f, "LEADER="PID_FMT"\n", s->leader);
325
326 if (audit_session_is_valid(s->audit_id))
327 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
328
329 if (dual_timestamp_is_set(&s->timestamp))
330 fprintf(f,
331 "REALTIME="USEC_FMT"\n"
332 "MONOTONIC="USEC_FMT"\n",
333 s->timestamp.realtime,
334 s->timestamp.monotonic);
335
336 if (s->controller) {
337 fprintf(f, "CONTROLLER=%s\n", s->controller);
338 session_save_devices(s, f);
339 }
340
341 r = fflush_and_check(f);
342 if (r < 0)
343 goto fail;
344
345 if (rename(temp_path, s->state_file) < 0) {
346 r = -errno;
347 goto fail;
348 }
349
350 return 0;
351
352 fail:
353 (void) unlink(s->state_file);
354
355 if (temp_path)
356 (void) unlink(temp_path);
357
358 return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
359 }
360
session_load_devices(Session * s,const char * devices)361 static int session_load_devices(Session *s, const char *devices) {
362 const char *p;
363 int r = 0;
364
365 assert(s);
366
367 for (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
session_load(Session * s)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 (state && streq(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
session_activate(Session * s)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
session_start_scope(Session * s,sd_bus_message * properties,sd_bus_error * error)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_free_ char *scope = NULL;
650 const char *description;
651
652 s->scope_job = mfree(s->scope_job);
653
654 scope = strjoin("session-", s->id, ".scope");
655 if (!scope)
656 return log_oom();
657
658 description = strjoina("Session ", s->id, " of User ", s->user->user_record->user_name);
659
660 r = manager_start_scope(
661 s->manager,
662 scope,
663 s->leader,
664 s->user->slice,
665 description,
666 /* These two have StopWhenUnneeded= set, hence add a dep towards them */
667 STRV_MAKE(s->user->runtime_dir_service,
668 s->user->service),
669 /* And order us after some more */
670 STRV_MAKE("systemd-logind.service",
671 "systemd-user-sessions.service",
672 s->user->runtime_dir_service,
673 s->user->service),
674 user_record_home_directory(s->user->user_record),
675 properties,
676 error,
677 &s->scope_job);
678 if (r < 0)
679 return log_error_errno(r, "Failed to start session scope %s: %s",
680 scope, bus_error_message(error, r));
681
682 s->scope = TAKE_PTR(scope);
683 }
684
685 (void) hashmap_put(s->manager->session_units, s->scope, s);
686
687 return 0;
688 }
689
session_start(Session * s,sd_bus_message * properties,sd_bus_error * error)690 int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
691 int r;
692
693 assert(s);
694
695 if (!s->user)
696 return -ESTALE;
697
698 if (s->stopping)
699 return -EINVAL;
700
701 if (s->started)
702 return 0;
703
704 r = user_start(s->user);
705 if (r < 0)
706 return r;
707
708 r = session_start_scope(s, properties, error);
709 if (r < 0)
710 return r;
711
712 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
713 "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
714 "SESSION_ID=%s", s->id,
715 "USER_ID=%s", s->user->user_record->user_name,
716 "LEADER="PID_FMT, s->leader,
717 LOG_MESSAGE("New session %s of user %s.", s->id, s->user->user_record->user_name));
718
719 if (!dual_timestamp_is_set(&s->timestamp))
720 dual_timestamp_get(&s->timestamp);
721
722 if (s->seat)
723 seat_read_active_vt(s->seat);
724
725 s->started = true;
726
727 user_elect_display(s->user);
728
729 /* Save data */
730 session_save(s);
731 user_save(s->user);
732 if (s->seat)
733 seat_save(s->seat);
734
735 /* Send signals */
736 session_send_signal(s, true);
737 user_send_changed(s->user, "Display", NULL);
738
739 if (s->seat && s->seat->active == s)
740 seat_send_changed(s->seat, "ActiveSession", NULL);
741
742 return 0;
743 }
744
session_stop_scope(Session * s,bool force)745 static int session_stop_scope(Session *s, bool force) {
746 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
747 int r;
748
749 assert(s);
750
751 if (!s->scope)
752 return 0;
753
754 /* Let's always abandon the scope first. This tells systemd that we are not interested anymore, and everything
755 * that is left in the scope is "left-over". Informing systemd about this has the benefit that it will log
756 * when killing any processes left after this point. */
757 r = manager_abandon_scope(s->manager, s->scope, &error);
758 if (r < 0) {
759 log_warning_errno(r, "Failed to abandon session scope, ignoring: %s", bus_error_message(&error, r));
760 sd_bus_error_free(&error);
761 }
762
763 s->scope_job = mfree(s->scope_job);
764
765 /* Optionally, let's kill everything that's left now. */
766 if (force ||
767 (s->user->user_record->kill_processes != 0 &&
768 (s->user->user_record->kill_processes > 0 ||
769 manager_shall_kill(s->manager, s->user->user_record->user_name)))) {
770
771 r = manager_stop_unit(s->manager, s->scope, force ? "replace" : "fail", &error, &s->scope_job);
772 if (r < 0) {
773 if (force)
774 return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));
775
776 log_warning_errno(r, "Failed to stop session scope, ignoring: %s", bus_error_message(&error, r));
777 }
778 } else {
779
780 /* With no killing, this session is allowed to persist in "closing" state indefinitely.
781 * Therefore session stop and session removal may be two distinct events.
782 * Session stop is quite significant on its own, let's log it. */
783 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
784 "SESSION_ID=%s", s->id,
785 "USER_ID=%s", s->user->user_record->user_name,
786 "LEADER="PID_FMT, s->leader,
787 LOG_MESSAGE("Session %s logged out. Waiting for processes to exit.", s->id));
788 }
789
790 return 0;
791 }
792
session_stop(Session * s,bool force)793 int session_stop(Session *s, bool force) {
794 int r;
795
796 assert(s);
797
798 /* This is called whenever we begin with tearing down a session record. It's called in four cases: explicit API
799 * request via the bus (either directly for the session object or for the seat or user object this session
800 * belongs to; 'force' is true), or due to automatic GC (i.e. scope vanished; 'force' is false), or because the
801 * session FIFO saw an EOF ('force' is false), or because the release timer hit ('force' is false). */
802
803 if (!s->user)
804 return -ESTALE;
805 if (!s->started)
806 return 0;
807 if (s->stopping)
808 return 0;
809
810 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
811
812 if (s->seat)
813 seat_evict_position(s->seat, s);
814
815 /* We are going down, don't care about FIFOs anymore */
816 session_remove_fifo(s);
817
818 /* Kill cgroup */
819 r = session_stop_scope(s, force);
820
821 s->stopping = true;
822
823 user_elect_display(s->user);
824
825 session_save(s);
826 user_save(s->user);
827
828 return r;
829 }
830
session_finalize(Session * s)831 int session_finalize(Session *s) {
832 SessionDevice *sd;
833
834 assert(s);
835
836 if (!s->user)
837 return -ESTALE;
838
839 if (s->started)
840 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
841 "MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
842 "SESSION_ID=%s", s->id,
843 "USER_ID=%s", s->user->user_record->user_name,
844 "LEADER="PID_FMT, s->leader,
845 LOG_MESSAGE("Removed session %s.", s->id));
846
847 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
848
849 if (s->seat)
850 seat_evict_position(s->seat, s);
851
852 /* Kill session devices */
853 while ((sd = hashmap_first(s->devices)))
854 session_device_free(sd);
855
856 (void) unlink(s->state_file);
857 session_add_to_gc_queue(s);
858 user_add_to_gc_queue(s->user);
859
860 if (s->started) {
861 session_send_signal(s, false);
862 s->started = false;
863 }
864
865 if (s->seat) {
866 if (s->seat->active == s)
867 seat_set_active(s->seat, NULL);
868
869 seat_save(s->seat);
870 }
871
872 user_save(s->user);
873 user_send_changed(s->user, "Display", NULL);
874
875 return 0;
876 }
877
release_timeout_callback(sd_event_source * es,uint64_t usec,void * userdata)878 static int release_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) {
879 Session *s = userdata;
880
881 assert(es);
882 assert(s);
883
884 session_stop(s, /* force = */ false);
885 return 0;
886 }
887
session_release(Session * s)888 int session_release(Session *s) {
889 assert(s);
890
891 if (!s->started || s->stopping)
892 return 0;
893
894 if (s->timer_event_source)
895 return 0;
896
897 return sd_event_add_time_relative(
898 s->manager->event,
899 &s->timer_event_source,
900 CLOCK_MONOTONIC,
901 RELEASE_USEC, 0,
902 release_timeout_callback, s);
903 }
904
session_is_active(Session * s)905 bool session_is_active(Session *s) {
906 assert(s);
907
908 if (!s->seat)
909 return true;
910
911 return s->seat->active == s;
912 }
913
get_tty_atime(const char * tty,usec_t * atime)914 static int get_tty_atime(const char *tty, usec_t *atime) {
915 _cleanup_free_ char *p = NULL;
916 struct stat st;
917
918 assert(tty);
919 assert(atime);
920
921 if (!path_is_absolute(tty)) {
922 p = path_join("/dev", tty);
923 if (!p)
924 return -ENOMEM;
925
926 tty = p;
927 } else if (!path_startswith(tty, "/dev/"))
928 return -ENOENT;
929
930 if (lstat(tty, &st) < 0)
931 return -errno;
932
933 *atime = timespec_load(&st.st_atim);
934 return 0;
935 }
936
get_process_ctty_atime(pid_t pid,usec_t * atime)937 static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
938 _cleanup_free_ char *p = NULL;
939 int r;
940
941 assert(pid > 0);
942 assert(atime);
943
944 r = get_ctty(pid, NULL, &p);
945 if (r < 0)
946 return r;
947
948 return get_tty_atime(p, atime);
949 }
950
session_get_idle_hint(Session * s,dual_timestamp * t)951 int session_get_idle_hint(Session *s, dual_timestamp *t) {
952 usec_t atime = 0;
953 int r;
954
955 assert(s);
956
957 /* Graphical sessions have an explicit idle hint */
958 if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
959 if (t)
960 *t = s->idle_hint_timestamp;
961
962 return s->idle_hint;
963 }
964
965 /* For sessions with an explicitly configured tty, let's check its atime */
966 if (s->tty) {
967 r = get_tty_atime(s->tty, &atime);
968 if (r >= 0)
969 goto found_atime;
970 }
971
972 /* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
973 * the leader */
974 if (pid_is_valid(s->leader)) {
975 r = get_process_ctty_atime(s->leader, &atime);
976 if (r >= 0)
977 goto found_atime;
978 }
979
980 if (t)
981 *t = DUAL_TIMESTAMP_NULL;
982
983 return false;
984
985 found_atime:
986 if (t)
987 dual_timestamp_from_realtime(t, atime);
988
989 if (s->manager->idle_action_usec <= 0)
990 return false;
991
992 return usec_add(atime, s->manager->idle_action_usec) <= now(CLOCK_REALTIME);
993 }
994
session_set_idle_hint(Session * s,bool b)995 int session_set_idle_hint(Session *s, bool b) {
996 assert(s);
997
998 if (!SESSION_TYPE_IS_GRAPHICAL(s->type))
999 return -ENOTTY;
1000
1001 if (s->idle_hint == b)
1002 return 0;
1003
1004 s->idle_hint = b;
1005 dual_timestamp_get(&s->idle_hint_timestamp);
1006
1007 session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1008
1009 if (s->seat)
1010 seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1011
1012 user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1013 manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1014
1015 return 1;
1016 }
1017
session_get_locked_hint(Session * s)1018 int session_get_locked_hint(Session *s) {
1019 assert(s);
1020
1021 return s->locked_hint;
1022 }
1023
session_set_locked_hint(Session * s,bool b)1024 void session_set_locked_hint(Session *s, bool b) {
1025 assert(s);
1026
1027 if (s->locked_hint == b)
1028 return;
1029
1030 s->locked_hint = b;
1031
1032 session_send_changed(s, "LockedHint", NULL);
1033 }
1034
session_set_type(Session * s,SessionType t)1035 void session_set_type(Session *s, SessionType t) {
1036 assert(s);
1037
1038 if (s->type == t)
1039 return;
1040
1041 s->type = t;
1042 session_save(s);
1043
1044 session_send_changed(s, "Type", NULL);
1045 }
1046
session_dispatch_fifo(sd_event_source * es,int fd,uint32_t revents,void * userdata)1047 static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
1048 Session *s = userdata;
1049
1050 assert(s);
1051 assert(s->fifo_fd == fd);
1052
1053 /* EOF on the FIFO means the session died abnormally. */
1054
1055 session_remove_fifo(s);
1056 session_stop(s, /* force = */ false);
1057
1058 return 1;
1059 }
1060
session_create_fifo(Session * s)1061 int session_create_fifo(Session *s) {
1062 int r;
1063
1064 assert(s);
1065
1066 /* Create FIFO */
1067 if (!s->fifo_path) {
1068 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
1069 if (r < 0)
1070 return r;
1071
1072 s->fifo_path = strjoin("/run/systemd/sessions/", s->id, ".ref");
1073 if (!s->fifo_path)
1074 return -ENOMEM;
1075
1076 if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
1077 return -errno;
1078 }
1079
1080 /* Open reading side */
1081 if (s->fifo_fd < 0) {
1082 s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
1083 if (s->fifo_fd < 0)
1084 return -errno;
1085 }
1086
1087 if (!s->fifo_event_source) {
1088 r = sd_event_add_io(s->manager->event, &s->fifo_event_source, s->fifo_fd, 0, session_dispatch_fifo, s);
1089 if (r < 0)
1090 return r;
1091
1092 /* Let's make sure we noticed dead sessions before we process new bus requests (which might
1093 * create new sessions). */
1094 r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_NORMAL-10);
1095 if (r < 0)
1096 return r;
1097 }
1098
1099 /* Open writing side */
1100 return RET_NERRNO(open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK));
1101 }
1102
session_remove_fifo(Session * s)1103 static void session_remove_fifo(Session *s) {
1104 assert(s);
1105
1106 s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
1107 s->fifo_fd = safe_close(s->fifo_fd);
1108
1109 if (s->fifo_path) {
1110 (void) unlink(s->fifo_path);
1111 s->fifo_path = mfree(s->fifo_path);
1112 }
1113 }
1114
session_may_gc(Session * s,bool drop_not_started)1115 bool session_may_gc(Session *s, bool drop_not_started) {
1116 int r;
1117
1118 assert(s);
1119
1120 if (drop_not_started && !s->started)
1121 return true;
1122
1123 if (!s->user)
1124 return true;
1125
1126 if (s->fifo_fd >= 0) {
1127 if (pipe_eof(s->fifo_fd) <= 0)
1128 return false;
1129 }
1130
1131 if (s->scope_job) {
1132 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1133
1134 r = manager_job_is_active(s->manager, s->scope_job, &error);
1135 if (r < 0)
1136 log_debug_errno(r, "Failed to determine whether job '%s' is pending, ignoring: %s", s->scope_job, bus_error_message(&error, r));
1137 if (r != 0)
1138 return false;
1139 }
1140
1141 if (s->scope) {
1142 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1143
1144 r = manager_unit_is_active(s->manager, s->scope, &error);
1145 if (r < 0)
1146 log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring: %s", s->scope, bus_error_message(&error, r));
1147 if (r != 0)
1148 return false;
1149 }
1150
1151 return true;
1152 }
1153
session_add_to_gc_queue(Session * s)1154 void session_add_to_gc_queue(Session *s) {
1155 assert(s);
1156
1157 if (s->in_gc_queue)
1158 return;
1159
1160 LIST_PREPEND(gc_queue, s->manager->session_gc_queue, s);
1161 s->in_gc_queue = true;
1162 }
1163
session_get_state(Session * s)1164 SessionState session_get_state(Session *s) {
1165 assert(s);
1166
1167 /* always check closing first */
1168 if (s->stopping || s->timer_event_source)
1169 return SESSION_CLOSING;
1170
1171 if (s->scope_job || s->fifo_fd < 0)
1172 return SESSION_OPENING;
1173
1174 if (session_is_active(s))
1175 return SESSION_ACTIVE;
1176
1177 return SESSION_ONLINE;
1178 }
1179
session_kill(Session * s,KillWho who,int signo)1180 int session_kill(Session *s, KillWho who, int signo) {
1181 assert(s);
1182
1183 if (!s->scope)
1184 return -ESRCH;
1185
1186 return manager_kill_unit(s->manager, s->scope, who, signo, NULL);
1187 }
1188
session_open_vt(Session * s)1189 static int session_open_vt(Session *s) {
1190 char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)];
1191
1192 if (s->vtnr < 1)
1193 return -ENODEV;
1194
1195 if (s->vtfd >= 0)
1196 return s->vtfd;
1197
1198 sprintf(path, "/dev/tty%u", s->vtnr);
1199 s->vtfd = open_terminal(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
1200 if (s->vtfd < 0)
1201 return log_error_errno(s->vtfd, "cannot open VT %s of session %s: %m", path, s->id);
1202
1203 return s->vtfd;
1204 }
1205
session_prepare_vt(Session * s)1206 static int session_prepare_vt(Session *s) {
1207 int vt, r;
1208 struct vt_mode mode = {};
1209
1210 if (s->vtnr < 1)
1211 return 0;
1212
1213 vt = session_open_vt(s);
1214 if (vt < 0)
1215 return vt;
1216
1217 r = fchown(vt, s->user->user_record->uid, -1);
1218 if (r < 0) {
1219 r = log_error_errno(errno,
1220 "Cannot change owner of /dev/tty%u: %m",
1221 s->vtnr);
1222 goto error;
1223 }
1224
1225 r = ioctl(vt, KDSKBMODE, K_OFF);
1226 if (r < 0) {
1227 r = log_error_errno(errno,
1228 "Cannot set K_OFF on /dev/tty%u: %m",
1229 s->vtnr);
1230 goto error;
1231 }
1232
1233 r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
1234 if (r < 0) {
1235 r = log_error_errno(errno,
1236 "Cannot set KD_GRAPHICS on /dev/tty%u: %m",
1237 s->vtnr);
1238 goto error;
1239 }
1240
1241 /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS.
1242 * So we need a dummy handler here which just acknowledges *all* VT
1243 * switch requests. */
1244 mode.mode = VT_PROCESS;
1245 mode.relsig = SIGRTMIN;
1246 mode.acqsig = SIGRTMIN + 1;
1247 r = ioctl(vt, VT_SETMODE, &mode);
1248 if (r < 0) {
1249 r = log_error_errno(errno,
1250 "Cannot set VT_PROCESS on /dev/tty%u: %m",
1251 s->vtnr);
1252 goto error;
1253 }
1254
1255 return 0;
1256
1257 error:
1258 session_restore_vt(s);
1259 return r;
1260 }
1261
session_restore_vt(Session * s)1262 static void session_restore_vt(Session *s) {
1263 int r;
1264
1265 r = vt_restore(s->vtfd);
1266 if (r == -EIO) {
1267 int vt, old_fd;
1268
1269 /* It might happen if the controlling process exited before or while we were
1270 * restoring the VT as it would leave the old file-descriptor in a hung-up
1271 * state. In this case let's retry with a fresh handle to the virtual terminal. */
1272
1273 /* We do a little dance to avoid having the terminal be available
1274 * for reuse before we've cleaned it up. */
1275 old_fd = TAKE_FD(s->vtfd);
1276
1277 vt = session_open_vt(s);
1278 safe_close(old_fd);
1279
1280 if (vt >= 0)
1281 r = vt_restore(vt);
1282 }
1283
1284 if (r < 0)
1285 log_warning_errno(r, "Failed to restore VT, ignoring: %m");
1286
1287 s->vtfd = safe_close(s->vtfd);
1288 }
1289
session_leave_vt(Session * s)1290 void session_leave_vt(Session *s) {
1291 int r;
1292
1293 assert(s);
1294
1295 /* This is called whenever we get a VT-switch signal from the kernel.
1296 * We acknowledge all of them unconditionally. Note that session are
1297 * free to overwrite those handlers and we only register them for
1298 * sessions with controllers. Legacy sessions are not affected.
1299 * However, if we switch from a non-legacy to a legacy session, we must
1300 * make sure to pause all device before acknowledging the switch. We
1301 * process the real switch only after we are notified via sysfs, so the
1302 * legacy session might have already started using the devices. If we
1303 * don't pause the devices before the switch, we might confuse the
1304 * session we switch to. */
1305
1306 if (s->vtfd < 0)
1307 return;
1308
1309 session_device_pause_all(s);
1310 r = vt_release(s->vtfd, false);
1311 if (r < 0)
1312 log_debug_errno(r, "Cannot release VT of session %s: %m", s->id);
1313 }
1314
session_is_controller(Session * s,const char * sender)1315 bool session_is_controller(Session *s, const char *sender) {
1316 assert(s);
1317
1318 return streq_ptr(s->controller, sender);
1319 }
1320
session_release_controller(Session * s,bool notify)1321 static void session_release_controller(Session *s, bool notify) {
1322 _unused_ _cleanup_free_ char *name = NULL;
1323 SessionDevice *sd;
1324
1325 if (!s->controller)
1326 return;
1327
1328 name = s->controller;
1329
1330 /* By resetting the controller before releasing the devices, we won't send notification signals.
1331 * This avoids sending useless notifications if the controller is released on disconnects. */
1332 if (!notify)
1333 s->controller = NULL;
1334
1335 while ((sd = hashmap_first(s->devices)))
1336 session_device_free(sd);
1337
1338 s->controller = NULL;
1339 s->track = sd_bus_track_unref(s->track);
1340 }
1341
on_bus_track(sd_bus_track * track,void * userdata)1342 static int on_bus_track(sd_bus_track *track, void *userdata) {
1343 Session *s = userdata;
1344
1345 assert(track);
1346 assert(s);
1347
1348 session_drop_controller(s);
1349
1350 return 0;
1351 }
1352
session_set_controller(Session * s,const char * sender,bool force,bool prepare)1353 int session_set_controller(Session *s, const char *sender, bool force, bool prepare) {
1354 _cleanup_free_ char *name = NULL;
1355 int r;
1356
1357 assert(s);
1358 assert(sender);
1359
1360 if (session_is_controller(s, sender))
1361 return 0;
1362 if (s->controller && !force)
1363 return -EBUSY;
1364
1365 name = strdup(sender);
1366 if (!name)
1367 return -ENOMEM;
1368
1369 s->track = sd_bus_track_unref(s->track);
1370 r = sd_bus_track_new(s->manager->bus, &s->track, on_bus_track, s);
1371 if (r < 0)
1372 return r;
1373
1374 r = sd_bus_track_add_name(s->track, name);
1375 if (r < 0)
1376 return r;
1377
1378 /* When setting a session controller, we forcibly mute the VT and set
1379 * it into graphics-mode. Applications can override that by changing
1380 * VT state after calling TakeControl(). However, this serves as a good
1381 * default and well-behaving controllers can now ignore VTs entirely.
1382 * Note that we reset the VT on ReleaseControl() and if the controller
1383 * exits.
1384 * If logind crashes/restarts, we restore the controller during restart
1385 * (without preparing the VT since the controller has probably overridden
1386 * VT state by now) or reset the VT in case it crashed/exited, too. */
1387 if (prepare) {
1388 r = session_prepare_vt(s);
1389 if (r < 0) {
1390 s->track = sd_bus_track_unref(s->track);
1391 return r;
1392 }
1393 }
1394
1395 session_release_controller(s, true);
1396 s->controller = TAKE_PTR(name);
1397 session_save(s);
1398
1399 return 0;
1400 }
1401
session_drop_controller(Session * s)1402 void session_drop_controller(Session *s) {
1403 assert(s);
1404
1405 if (!s->controller)
1406 return;
1407
1408 s->track = sd_bus_track_unref(s->track);
1409 session_set_type(s, s->original_type);
1410 session_release_controller(s, false);
1411 session_save(s);
1412 session_restore_vt(s);
1413 }
1414
1415 static const char* const session_state_table[_SESSION_STATE_MAX] = {
1416 [SESSION_OPENING] = "opening",
1417 [SESSION_ONLINE] = "online",
1418 [SESSION_ACTIVE] = "active",
1419 [SESSION_CLOSING] = "closing",
1420 };
1421
1422 DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
1423
1424 static const char* const session_type_table[_SESSION_TYPE_MAX] = {
1425 [SESSION_UNSPECIFIED] = "unspecified",
1426 [SESSION_TTY] = "tty",
1427 [SESSION_X11] = "x11",
1428 [SESSION_WAYLAND] = "wayland",
1429 [SESSION_MIR] = "mir",
1430 [SESSION_WEB] = "web",
1431 };
1432
1433 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
1434
1435 static const char* const session_class_table[_SESSION_CLASS_MAX] = {
1436 [SESSION_USER] = "user",
1437 [SESSION_GREETER] = "greeter",
1438 [SESSION_LOCK_SCREEN] = "lock-screen",
1439 [SESSION_BACKGROUND] = "background",
1440 };
1441
1442 DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
1443
1444 static const char* const kill_who_table[_KILL_WHO_MAX] = {
1445 [KILL_LEADER] = "leader",
1446 [KILL_ALL] = "all",
1447 };
1448
1449 DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
1450
1451 static const char* const tty_validity_table[_TTY_VALIDITY_MAX] = {
1452 [TTY_FROM_PAM] = "from-pam",
1453 [TTY_FROM_UTMP] = "from-utmp",
1454 [TTY_UTMP_INCONSISTENT] = "utmp-inconsistent",
1455 };
1456
1457 DEFINE_STRING_TABLE_LOOKUP(tty_validity, TTYValidity);
1458