X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Flogind-session.c;h=fdeacb150acb42a84f203cb052fc412a613c6a50;hp=dc1d81c4be94271bc1451815709634fd87cb3628;hb=558c6490b1df7f82a63d0a747fda7412c4d28b0c;hpb=39883f622f392d8579f4428fc5a789a102efbb10 diff --git a/src/login/logind-session.c b/src/login/logind-session.c index dc1d81c4b..fdeacb150 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -213,7 +213,6 @@ int session_save(Session *s) { if (s->scope) fprintf(f, "SCOPE=%s\n", s->scope); - if (s->scope_job) fprintf(f, "SCOPE_JOB=%s\n", s->scope_job); @@ -229,17 +228,54 @@ int session_save(Session *s) { if (s->display) fprintf(f, "DISPLAY=%s\n", s->display); - if (s->remote_host) - fprintf(f, "REMOTE_HOST=%s\n", s->remote_host); + if (s->remote_host) { + _cleanup_free_ char *escaped; - if (s->remote_user) - fprintf(f, "REMOTE_USER=%s\n", s->remote_user); + escaped = cescape(s->remote_host); + if (!escaped) { + r = -ENOMEM; + goto finish; + } - if (s->service) - fprintf(f, "SERVICE=%s\n", s->service); + fprintf(f, "REMOTE_HOST=%s\n", escaped); + } - if (s->desktop) - fprintf(f, "DESKTOP=%s\n", s->desktop); + if (s->remote_user) { + _cleanup_free_ char *escaped; + + escaped = cescape(s->remote_user); + if (!escaped) { + r = -ENOMEM; + goto finish; + } + + fprintf(f, "REMOTE_USER=%s\n", escaped); + } + + if (s->service) { + _cleanup_free_ char *escaped; + + escaped = cescape(s->service); + if (!escaped) { + r = -ENOMEM; + goto finish; + } + + fprintf(f, "SERVICE=%s\n", escaped); + } + + if (s->desktop) { + _cleanup_free_ char *escaped; + + + escaped = cescape(s->desktop); + if (!escaped) { + r = -ENOMEM; + goto finish; + } + + fprintf(f, "DESKTOP=%s\n", escaped); + } if (s->seat && seat_has_vts(s->seat)) fprintf(f, "VTNR=%u\n", s->vtnr); @@ -407,8 +443,7 @@ int session_load(Session *s) { trigger the EOF. */ fd = session_create_fifo(s); - if (fd >= 0) - close_nointr_nofail(fd); + safe_close(fd); } if (realtime) { @@ -490,7 +525,7 @@ static int session_start_scope(Session *s) { if (!scope) return log_oom(); - r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-session.service", &error, &job); + r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job); if (r < 0) { log_error("Failed to start session scope %s: %s %s", scope, bus_error_message(&error, r), error.name); @@ -534,7 +569,7 @@ int session_start(Session *s) { MESSAGE_ID(SD_MESSAGE_SESSION_START), "SESSION_ID=%s", s->id, "USER_ID=%s", s->user->name, - "LEADER=%lu", (unsigned long) s->leader, + "LEADER="PID_FMT, s->leader, "MESSAGE=New session %s of user %s.", s->id, s->user->name, NULL); @@ -546,6 +581,8 @@ int session_start(Session *s) { s->started = true; + user_elect_display(s->user); + /* Save data */ session_save(s); user_save(s->user); @@ -554,7 +591,7 @@ int session_start(Session *s) { /* Send signals */ session_send_signal(s, true); - user_send_changed(s->user, "Sessions", NULL); + user_send_changed(s->user, "Sessions", "Display", NULL); if (s->seat) { if (s->seat->active == s) seat_send_changed(s->seat, "Sessions", "ActiveSession", NULL); @@ -613,6 +650,8 @@ int session_stop(Session *s, bool force) { s->stopping = true; + user_elect_display(s->user); + session_save(s); user_save(s->user); @@ -633,7 +672,7 @@ int session_finalize(Session *s) { MESSAGE_ID(SD_MESSAGE_SESSION_STOP), "SESSION_ID=%s", s->id, "USER_ID=%s", s->user->name, - "LEADER=%lu", (unsigned long) s->leader, + "LEADER="PID_FMT, s->leader, "MESSAGE=Removed session %s.", s->id, NULL); @@ -661,7 +700,7 @@ int session_finalize(Session *s) { } user_save(s->user); - user_send_changed(s->user, "Sessions", NULL); + user_send_changed(s->user, "Sessions", "Display", NULL); return r; } @@ -683,7 +722,11 @@ void session_release(Session *s) { return; if (!s->timer_event_source) - sd_event_add_monotonic(s->manager->event, now(CLOCK_MONOTONIC) + RELEASE_USEC, 0, release_timeout_callback, s, &s->timer_event_source); + sd_event_add_time(s->manager->event, + &s->timer_event_source, + CLOCK_MONOTONIC, + now(CLOCK_MONOTONIC) + RELEASE_USEC, 0, + release_timeout_callback, s); } bool session_is_active(Session *s) { @@ -844,7 +887,7 @@ int session_create_fifo(Session *s) { } if (!s->fifo_event_source) { - r = sd_event_add_io(s->manager->event, s->fifo_fd, 0, session_dispatch_fifo, s, &s->fifo_event_source); + r = sd_event_add_io(s->manager->event, &s->fifo_event_source, s->fifo_fd, 0, session_dispatch_fifo, s); if (r < 0) return r; @@ -864,13 +907,8 @@ int session_create_fifo(Session *s) { static void session_remove_fifo(Session *s) { assert(s); - if (s->fifo_event_source) - s->fifo_event_source = sd_event_source_unref(s->fifo_event_source); - - if (s->fifo_fd >= 0) { - close_nointr_nofail(s->fifo_fd); - s->fifo_fd = -1; - } + s->fifo_event_source = sd_event_source_unref(s->fifo_event_source); + s->fifo_fd = safe_close(s->fifo_fd); if (s->fifo_path) { unlink(s->fifo_path); @@ -950,7 +988,7 @@ static int session_open_vt(Session *s) { s->vtfd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY); if (s->vtfd < 0) { log_error("cannot open VT %s of session %s: %m", path, s->id); - return -1; + return -errno; } return s->vtfd; @@ -965,7 +1003,7 @@ static int session_vt_fn(sd_event_source *source, const struct signalfd_siginfo return 0; } -void session_mute_vt(Session *s) { +void session_prepare_vt(Session *s) { int vt, r; struct vt_mode mode = { 0 }; sigset_t mask; @@ -974,6 +1012,10 @@ void session_mute_vt(Session *s) { if (vt < 0) return; + r = fchown(vt, s->user->uid, -1); + if (r < 0) + goto error; + r = ioctl(vt, KDSKBMODE, K_OFF); if (r < 0) goto error; @@ -986,7 +1028,7 @@ void session_mute_vt(Session *s) { sigaddset(&mask, SIGUSR1); sigprocmask(SIG_BLOCK, &mask, NULL); - r = sd_event_add_signal(s->manager->event, SIGUSR1, session_vt_fn, s, &s->vt_source); + r = sd_event_add_signal(s->manager->event, &s->vt_source, SIGUSR1, session_vt_fn, s); if (r < 0) goto error; @@ -1008,7 +1050,7 @@ error: } void session_restore_vt(Session *s) { - _cleanup_free_ char *utf8; + _cleanup_free_ char *utf8 = NULL; int vt, kb = K_XLATE; struct vt_mode mode = { 0 }; @@ -1022,13 +1064,15 @@ void session_restore_vt(Session *s) { if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1') kb = K_UNICODE; + ioctl(vt, KDSKBMODE, kb); mode.mode = VT_AUTO; ioctl(vt, VT_SETMODE, &mode); - close_nointr_nofail(vt); - s->vtfd = -1; + fchown(vt, 0, -1); + + s->vtfd = safe_close(s->vtfd); } bool session_is_controller(Session *s, const char *sender) { @@ -1091,7 +1135,7 @@ int session_set_controller(Session *s, const char *sender, bool force) { * exits. * If logind crashes/restarts, we restore the controller during restart * or reset the VT in case it crashed/exited, too. */ - session_mute_vt(s); + session_prepare_vt(s); return 0; } @@ -1115,10 +1159,11 @@ static const char* const session_state_table[_SESSION_STATE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState); static const char* const session_type_table[_SESSION_TYPE_MAX] = { + [SESSION_UNSPECIFIED] = "unspecified", [SESSION_TTY] = "tty", [SESSION_X11] = "x11", [SESSION_WAYLAND] = "wayland", - [SESSION_UNSPECIFIED] = "unspecified", + [SESSION_MIR] = "mir", }; DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);