1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include <sys/ioctl.h>
32 #include "sd-messages.h"
36 #include "path-util.h"
40 #include "bus-error.h"
41 #include "logind-session.h"
43 static unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
44 uint64_t u = *(const dev_t*)p;
46 return uint64_hash_func(&u, hash_key);
49 static int devt_compare_func(const void *_a, const void *_b) {
52 a = *(const dev_t*) _a;
53 b = *(const dev_t*) _b;
55 return a < b ? -1 : (a > b ? 1 : 0);
58 Session* session_new(Manager *m, const char *id) {
63 assert(session_id_valid(id));
69 s->state_file = strappend("/run/systemd/sessions/", id);
75 s->devices = hashmap_new(devt_hash_func, devt_compare_func);
82 s->id = basename(s->state_file);
84 if (hashmap_put(m->sessions, s->id, s) < 0) {
85 hashmap_free(s->devices);
98 void session_free(Session *s) {
104 LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s);
106 session_remove_fifo(s);
108 session_drop_controller(s);
110 while ((sd = hashmap_first(s->devices)))
111 session_device_free(sd);
113 hashmap_free(s->devices);
116 LIST_REMOVE(sessions_by_user, s->user->sessions, s);
118 if (s->user->display == s)
119 s->user->display = NULL;
123 if (s->seat->active == s)
124 s->seat->active = NULL;
125 if (s->seat->pending_switch == s)
126 s->seat->pending_switch = NULL;
128 LIST_REMOVE(sessions_by_seat, s->seat->sessions, s);
132 hashmap_remove(s->manager->session_units, s->scope);
138 sd_bus_message_unref(s->create_message);
142 free(s->remote_host);
143 free(s->remote_user);
146 hashmap_remove(s->manager->sessions, s->id);
152 void session_set_user(Session *s, User *u) {
157 LIST_PREPEND(sessions_by_user, u->sessions, s);
160 int session_save(Session *s) {
161 _cleanup_free_ char *temp_path = NULL;
162 _cleanup_fclose_ FILE *f = NULL;
173 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
177 r = fopen_temporary(s->state_file, &f, &temp_path);
183 fchmod(fileno(f), 0644);
186 "# This is private data. Do not parse.\n"
192 (unsigned long) s->user->uid,
194 session_is_active(s),
195 session_state_to_string(session_get_state(s)),
199 fprintf(f, "TYPE=%s\n", session_type_to_string(s->type));
202 fprintf(f, "CLASS=%s\n", session_class_to_string(s->class));
205 fprintf(f, "SCOPE=%s\n", s->scope);
208 fprintf(f, "SCOPE_JOB=%s\n", s->scope_job);
211 fprintf(f, "FIFO=%s\n", s->fifo_path);
214 fprintf(f, "SEAT=%s\n", s->seat->id);
217 fprintf(f, "TTY=%s\n", s->tty);
220 fprintf(f, "DISPLAY=%s\n", s->display);
223 fprintf(f, "REMOTE_HOST=%s\n", s->remote_host);
226 fprintf(f, "REMOTE_USER=%s\n", s->remote_user);
229 fprintf(f, "SERVICE=%s\n", s->service);
231 if (s->seat && seat_has_vts(s->seat))
232 fprintf(f, "VTNR=%u\n", s->vtnr);
235 fprintf(f, "LEADER=%lu\n", (unsigned long) s->leader);
238 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
240 if (dual_timestamp_is_set(&s->timestamp))
244 (unsigned long long) s->timestamp.realtime,
245 (unsigned long long) s->timestamp.monotonic);
248 fprintf(f, "CONTROLLER=%s\n", s->controller);
252 if (ferror(f) || rename(temp_path, s->state_file) < 0) {
254 unlink(s->state_file);
260 log_error("Failed to save session data for %s: %s", s->id, strerror(-r));
265 int session_load(Session *s) {
266 _cleanup_free_ char *remote = NULL,
281 r = parse_env_file(s->state_file, NEWLINE,
284 "SCOPE_JOB", &s->scope_job,
285 "FIFO", &s->fifo_path,
288 "DISPLAY", &s->display,
289 "REMOTE_HOST", &s->remote_host,
290 "REMOTE_USER", &s->remote_user,
291 "SERVICE", &s->service,
297 "REALTIME", &realtime,
298 "MONOTONIC", &monotonic,
299 "CONTROLLER", &controller,
303 log_error("Failed to read %s: %s", s->state_file, strerror(-r));
312 log_error("UID not specified for session %s", s->id);
316 r = parse_uid(uid, &u);
318 log_error("Failed to parse UID value %s for session %s.", uid, s->id);
322 user = hashmap_get(s->manager->users, ULONG_TO_PTR((unsigned long) u));
324 log_error("User of session %s not known.", s->id);
328 session_set_user(s, user);
332 k = parse_boolean(remote);
338 safe_atou(vtnr, &s->vtnr);
340 if (seat && !s->seat) {
343 o = hashmap_get(s->manager->seats, seat);
345 r = seat_attach_session(o, s);
347 log_error("Cannot attach session %s to seat %s", s->id, seat);
350 if (!s->seat || !seat_has_vts(s->seat))
354 k = parse_pid(leader, &s->leader);
356 audit_session_from_pid(s->leader, &s->audit_id);
362 t = session_type_from_string(type);
370 c = session_class_from_string(class);
378 /* If we open an unopened pipe for reading we will not
379 get an EOF. to trigger an EOF we hence open it for
380 reading, but close it right-away which then will
383 fd = session_create_fifo(s);
385 close_nointr_nofail(fd);
389 unsigned long long l;
390 if (sscanf(realtime, "%llu", &l) > 0)
391 s->timestamp.realtime = l;
395 unsigned long long l;
396 if (sscanf(monotonic, "%llu", &l) > 0)
397 s->timestamp.monotonic = l;
401 if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0)
402 session_set_controller(s, controller, false);
404 session_restore_vt(s);
410 int session_activate(Session *s) {
411 unsigned int num_pending;
419 if (s->seat->active == s)
422 /* on seats with VTs, we let VTs manage session-switching */
423 if (seat_has_vts(s->seat)) {
427 return chvt(s->vtnr);
430 /* On seats without VTs, we implement session-switching in logind. We
431 * try to pause all session-devices and wait until the session
432 * controller acknowledged them. Once all devices are asleep, we simply
433 * switch the active session and be done.
434 * We save the session we want to switch to in seat->pending_switch and
435 * seat_complete_switch() will perform the final switch. */
437 s->seat->pending_switch = s;
439 /* if no devices are running, immediately perform the session switch */
440 num_pending = session_device_try_pause_all(s);
442 seat_complete_switch(s->seat);
447 static int session_link_x11_socket(Session *s) {
448 _cleanup_free_ char *t = NULL, *f = NULL;
454 assert(s->user->runtime_path);
456 if (s->user->display)
459 if (!s->display || !display_is_local(s->display))
462 k = strspn(s->display+1, "0123456789");
463 f = new(char, sizeof("/tmp/.X11-unix/X") + k);
467 c = stpcpy(f, "/tmp/.X11-unix/X");
468 memcpy(c, s->display+1, k);
471 if (access(f, F_OK) < 0) {
472 log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f);
476 /* Note that this cannot be in a subdir to avoid
477 * vulnerabilities since we are privileged but the runtime
478 * path is owned by the user */
480 t = strappend(s->user->runtime_path, "/X11-display");
484 if (link(f, t) < 0) {
485 if (errno == EEXIST) {
492 if (symlink(f, t) < 0) {
494 if (errno == EEXIST) {
497 if (symlink(f, t) >= 0)
501 log_error("Failed to link %s to %s: %m", f, t);
507 log_info("Linked %s to %s.", f, t);
508 s->user->display = s;
513 static int session_start_scope(Session *s) {
518 assert(s->user->slice);
521 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
522 _cleanup_free_ char *description = NULL;
523 const char *kill_mode;
526 description = strjoin("Session ", s->id, " of user ", s->user->name, NULL);
530 scope = strjoin("session-", s->id, ".scope", NULL);
534 kill_mode = manager_shall_kill(s->manager, s->user->name) ? "control-group" : "none";
536 r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job);
538 log_error("Failed to start session scope %s: %s %s",
539 scope, bus_error_message(&error, r), error.name);
551 hashmap_put(s->manager->session_units, s->scope, s);
556 int session_start(Session *s) {
567 r = user_start(s->user);
572 r = session_start_scope(s);
576 log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
577 MESSAGE_ID(SD_MESSAGE_SESSION_START),
578 "SESSION_ID=%s", s->id,
579 "USER_ID=%s", s->user->name,
580 "LEADER=%lu", (unsigned long) s->leader,
581 "MESSAGE=New session %s of user %s.", s->id, s->user->name,
584 /* Create X11 symlink */
585 session_link_x11_socket(s);
587 if (!dual_timestamp_is_set(&s->timestamp))
588 dual_timestamp_get(&s->timestamp);
591 seat_read_active_vt(s->seat);
595 /* Save session data */
599 session_send_signal(s, true);
604 if (s->seat->active == s)
605 seat_send_changed(s->seat, "Sessions", "ActiveSession", NULL);
607 seat_send_changed(s->seat, "Sessions", NULL);
610 user_send_changed(s->user, "Sessions", NULL);
615 static int session_stop_scope(Session *s) {
616 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
625 r = manager_stop_unit(s->manager, s->scope, &error, &job);
627 log_error("Failed to stop session scope: %s", bus_error_message(&error, r));
637 static int session_unlink_x11_socket(Session *s) {
638 _cleanup_free_ char *t = NULL;
644 if (s->user->display != s)
647 s->user->display = NULL;
649 t = strappend(s->user->runtime_path, "/X11-display");
654 return r < 0 ? -errno : 0;
657 int session_stop(Session *s) {
666 r = session_stop_scope(s);
674 int session_finalize(Session *s) {
684 log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
685 MESSAGE_ID(SD_MESSAGE_SESSION_STOP),
686 "SESSION_ID=%s", s->id,
687 "USER_ID=%s", s->user->name,
688 "LEADER=%lu", (unsigned long) s->leader,
689 "MESSAGE=Removed session %s.", s->id,
692 /* Kill session devices */
693 while ((sd = hashmap_first(s->devices)))
694 session_device_free(sd);
696 /* Remove X11 symlink */
697 session_unlink_x11_socket(s);
699 unlink(s->state_file);
700 session_add_to_gc_queue(s);
701 user_add_to_gc_queue(s->user);
704 session_send_signal(s, false);
709 if (s->seat->active == s)
710 seat_set_active(s->seat, NULL);
712 seat_send_changed(s->seat, "Sessions", NULL);
716 user_send_changed(s->user, "Sessions", NULL);
722 bool session_is_active(Session *s) {
728 return s->seat->active == s;
731 static int get_tty_atime(const char *tty, usec_t *atime) {
732 _cleanup_free_ char *p = NULL;
738 if (!path_is_absolute(tty)) {
739 p = strappend("/dev/", tty);
744 } else if (!path_startswith(tty, "/dev/"))
747 if (lstat(tty, &st) < 0)
750 *atime = timespec_load(&st.st_atim);
754 static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
755 _cleanup_free_ char *p = NULL;
761 r = get_ctty(pid, NULL, &p);
765 return get_tty_atime(p, atime);
768 int session_get_idle_hint(Session *s, dual_timestamp *t) {
774 /* Explicit idle hint is set */
777 *t = s->idle_hint_timestamp;
782 /* Graphical sessions should really implement a real
787 /* For sessions with an explicitly configured tty, let's check
790 r = get_tty_atime(s->tty, &atime);
795 /* For sessions with a leader but no explicitly configured
796 * tty, let's check the controlling tty of the leader */
798 r = get_process_ctty_atime(s->leader, &atime);
805 *t = s->idle_hint_timestamp;
811 dual_timestamp_from_realtime(t, atime);
813 n = now(CLOCK_REALTIME);
815 if (s->manager->idle_action_usec <= 0)
818 return atime + s->manager->idle_action_usec <= n;
821 void session_set_idle_hint(Session *s, bool b) {
824 if (s->idle_hint == b)
828 dual_timestamp_get(&s->idle_hint_timestamp);
830 session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
833 seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
835 user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
836 manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
839 static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
840 Session *s = userdata;
843 assert(s->fifo_fd == fd);
845 /* EOF on the FIFO means the session died abnormally. */
847 session_remove_fifo(s);
853 int session_create_fifo(Session *s) {
860 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
864 if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0)
867 if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
871 /* Open reading side */
872 if (s->fifo_fd < 0) {
873 s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
879 if (!s->fifo_event_source) {
880 r = sd_event_add_io(s->manager->event, s->fifo_fd, 0, session_dispatch_fifo, s, &s->fifo_event_source);
884 r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_IDLE);
889 /* Open writing side */
890 r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY);
897 void session_remove_fifo(Session *s) {
900 if (s->fifo_event_source)
901 s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
903 if (s->fifo_fd >= 0) {
904 close_nointr_nofail(s->fifo_fd);
909 unlink(s->fifo_path);
915 bool session_check_gc(Session *s, bool drop_not_started) {
920 if (drop_not_started && !s->started)
926 if (s->fifo_fd >= 0) {
927 r = pipe_eof(s->fifo_fd);
935 if (s->scope_job && manager_job_is_active(s->manager, s->scope_job))
938 if (s->scope && manager_unit_is_active(s->manager, s->scope))
944 void session_add_to_gc_queue(Session *s) {
950 LIST_PREPEND(gc_queue, s->manager->session_gc_queue, s);
951 s->in_gc_queue = true;
954 SessionState session_get_state(Session *s) {
958 return SESSION_OPENING;
961 return SESSION_CLOSING;
963 if (session_is_active(s))
964 return SESSION_ACTIVE;
966 return SESSION_ONLINE;
969 int session_kill(Session *s, KillWho who, int signo) {
975 return manager_kill_unit(s->manager, s->scope, who, signo, NULL);
978 static int session_open_vt(Session *s) {
987 sprintf(path, "/dev/tty%u", s->vtnr);
988 s->vtfd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
990 log_error("cannot open VT %s of session %s: %m", path, s->id);
997 static int session_vt_fn(sd_event_source *source, const struct signalfd_siginfo *si, void *data) {
1001 ioctl(s->vtfd, VT_RELDISP, 1);
1006 void session_mute_vt(Session *s) {
1008 struct vt_mode mode = { 0 };
1011 vt = session_open_vt(s);
1015 r = ioctl(vt, KDSKBMODE, K_OFF);
1019 r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
1024 sigaddset(&mask, SIGUSR1);
1025 sigprocmask(SIG_BLOCK, &mask, NULL);
1027 r = sd_event_add_signal(s->manager->event, SIGUSR1, session_vt_fn, s, &s->vt_source);
1031 /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS.
1032 * So we need a dummy handler here which just acknowledges *all* VT
1033 * switch requests. */
1034 mode.mode = VT_PROCESS;
1035 mode.relsig = SIGUSR1;
1036 mode.acqsig = SIGUSR1;
1037 r = ioctl(vt, VT_SETMODE, &mode);
1044 log_error("cannot mute VT %u for session %s (%d/%d)", s->vtnr, s->id, r, errno);
1045 session_restore_vt(s);
1048 void session_restore_vt(Session *s) {
1049 _cleanup_free_ char *utf8;
1050 int vt, kb = K_XLATE;
1051 struct vt_mode mode = { 0 };
1053 vt = session_open_vt(s);
1057 sd_event_source_unref(s->vt_source);
1058 s->vt_source = NULL;
1060 ioctl(vt, KDSETMODE, KD_TEXT);
1062 if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
1064 ioctl(vt, KDSKBMODE, kb);
1066 mode.mode = VT_AUTO;
1067 ioctl(vt, VT_SETMODE, &mode);
1069 close_nointr_nofail(vt);
1073 bool session_is_controller(Session *s, const char *sender) {
1076 return streq_ptr(s->controller, sender);
1079 static void session_swap_controller(Session *s, char *name) {
1082 if (s->controller) {
1083 manager_drop_busname(s->manager, s->controller);
1084 free(s->controller);
1085 s->controller = NULL;
1087 /* Drop all devices as they're now unused. Do that after the
1088 * controller is released to avoid sending out useles
1090 while ((sd = hashmap_first(s->devices)))
1091 session_device_free(sd);
1094 session_restore_vt(s);
1097 s->controller = name;
1101 int session_set_controller(Session *s, const char *sender, bool force) {
1108 if (session_is_controller(s, sender))
1110 if (s->controller && !force)
1117 r = manager_watch_busname(s->manager, sender);
1123 session_swap_controller(s, t);
1125 /* When setting a session controller, we forcibly mute the VT and set
1126 * it into graphics-mode. Applications can override that by changing
1127 * VT state after calling TakeControl(). However, this serves as a good
1128 * default and well-behaving controllers can now ignore VTs entirely.
1129 * Note that we reset the VT on ReleaseControl() and if the controller
1131 * If logind crashes/restarts, we restore the controller during restart
1132 * or reset the VT in case it crashed/exited, too. */
1138 void session_drop_controller(Session *s) {
1144 session_swap_controller(s, NULL);
1147 static const char* const session_state_table[_SESSION_STATE_MAX] = {
1148 [SESSION_OPENING] = "opening",
1149 [SESSION_ONLINE] = "online",
1150 [SESSION_ACTIVE] = "active",
1151 [SESSION_CLOSING] = "closing"
1154 DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
1156 static const char* const session_type_table[_SESSION_TYPE_MAX] = {
1157 [SESSION_TTY] = "tty",
1158 [SESSION_X11] = "x11",
1159 [SESSION_UNSPECIFIED] = "unspecified"
1162 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
1164 static const char* const session_class_table[_SESSION_CLASS_MAX] = {
1165 [SESSION_USER] = "user",
1166 [SESSION_GREETER] = "greeter",
1167 [SESSION_LOCK_SCREEN] = "lock-screen",
1168 [SESSION_BACKGROUND] = "background"
1171 DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
1173 static const char* const kill_who_table[_KILL_WHO_MAX] = {
1174 [KILL_LEADER] = "leader",
1178 DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);