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/>.
26 #include <sys/capability.h>
29 #include "sd-messages.h"
32 #include "path-util.h"
34 #include "sleep-config.h"
35 #include "fileio-label.h"
38 #include "unit-name.h"
42 #include "bus-error.h"
44 #include "bus-errors.h"
45 #include "udev-util.h"
47 static int property_get_idle_hint(
50 const char *interface,
52 sd_bus_message *reply,
54 sd_bus_error *error) {
56 Manager *m = userdata;
62 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
65 static int property_get_idle_since_hint(
68 const char *interface,
70 sd_bus_message *reply,
72 sd_bus_error *error) {
74 Manager *m = userdata;
81 manager_get_idle_hint(m, &t);
83 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
86 static int property_get_inhibited(
89 const char *interface,
91 sd_bus_message *reply,
93 sd_bus_error *error) {
95 Manager *m = userdata;
102 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
104 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
107 static int property_get_preparing(
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
114 sd_bus_error *error) {
116 Manager *m = userdata;
123 if (streq(property, "PreparingForShutdown"))
124 b = !!(m->action_what & INHIBIT_SHUTDOWN);
126 b = !!(m->action_what & INHIBIT_SLEEP);
128 return sd_bus_message_append(reply, "b", b);
131 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
133 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
134 _cleanup_free_ char *p = NULL;
135 Manager *m = userdata;
144 r = sd_bus_message_read(message, "s", &name);
148 session = hashmap_get(m->sessions, name);
150 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
152 p = session_bus_path(session);
156 return sd_bus_reply_method_return(message, "o", p);
159 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
160 _cleanup_free_ char *p = NULL;
161 Session *session = NULL;
162 Manager *m = userdata;
170 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
172 r = sd_bus_message_read(message, "u", &pid);
177 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
179 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
183 r = sd_bus_creds_get_pid(creds, &pid);
188 r = manager_get_session_by_pid(m, pid, &session);
192 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
194 p = session_bus_path(session);
198 return sd_bus_reply_method_return(message, "o", p);
201 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
202 _cleanup_free_ char *p = NULL;
203 Manager *m = userdata;
212 r = sd_bus_message_read(message, "u", &uid);
216 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
218 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
220 p = user_bus_path(user);
224 return sd_bus_reply_method_return(message, "o", p);
227 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
228 _cleanup_free_ char *p = NULL;
229 Manager *m = userdata;
238 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
240 r = sd_bus_message_read(message, "u", &pid);
245 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
247 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
251 r = sd_bus_creds_get_pid(creds, &pid);
256 r = manager_get_user_by_pid(m, pid, &user);
260 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
262 p = user_bus_path(user);
266 return sd_bus_reply_method_return(message, "o", p);
269 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
270 _cleanup_free_ char *p = NULL;
271 Manager *m = userdata;
280 r = sd_bus_message_read(message, "s", &name);
284 seat = hashmap_get(m->seats, name);
286 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
288 p = seat_bus_path(seat);
292 return sd_bus_reply_method_return(message, "o", p);
295 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
297 Manager *m = userdata;
306 r = sd_bus_message_new_method_return(message, &reply);
310 r = sd_bus_message_open_container(reply, 'a', "(susso)");
314 HASHMAP_FOREACH(session, m->sessions, i) {
315 _cleanup_free_ char *p = NULL;
317 p = session_bus_path(session);
321 r = sd_bus_message_append(reply, "(susso)",
323 (uint32_t) session->user->uid,
325 session->seat ? session->seat->id : "",
331 r = sd_bus_message_close_container(reply);
335 return sd_bus_send(bus, reply, NULL);
338 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
339 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
340 Manager *m = userdata;
349 r = sd_bus_message_new_method_return(message, &reply);
353 r = sd_bus_message_open_container(reply, 'a', "(uso)");
357 HASHMAP_FOREACH(user, m->users, i) {
358 _cleanup_free_ char *p = NULL;
360 p = user_bus_path(user);
364 r = sd_bus_message_append(reply, "(uso)",
365 (uint32_t) user->uid,
372 r = sd_bus_message_close_container(reply);
376 return sd_bus_send(bus, reply, NULL);
379 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
380 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
381 Manager *m = userdata;
390 r = sd_bus_message_new_method_return(message, &reply);
394 r = sd_bus_message_open_container(reply, 'a', "(so)");
398 HASHMAP_FOREACH(seat, m->seats, i) {
399 _cleanup_free_ char *p = NULL;
401 p = seat_bus_path(seat);
405 r = sd_bus_message_append(reply, "(so)", seat->id, p);
410 r = sd_bus_message_close_container(reply);
414 return sd_bus_send(bus, reply, NULL);
417 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
418 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
419 Manager *m = userdata;
420 Inhibitor *inhibitor;
424 r = sd_bus_message_new_method_return(message, &reply);
428 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
432 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
434 r = sd_bus_message_append(reply, "(ssssuu)",
435 strempty(inhibit_what_to_string(inhibitor->what)),
436 strempty(inhibitor->who),
437 strempty(inhibitor->why),
438 strempty(inhibit_mode_to_string(inhibitor->mode)),
439 (uint32_t) inhibitor->uid,
440 (uint32_t) inhibitor->pid);
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(bus, reply, NULL);
452 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
454 uint32_t uid, leader, audit_id = 0;
455 _cleanup_free_ char *id = NULL;
456 Session *session = NULL;
457 Manager *m = userdata;
470 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
475 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
478 t = _SESSION_TYPE_INVALID;
480 t = session_type_from_string(type);
482 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
486 c = _SESSION_CLASS_INVALID;
488 c = session_class_from_string(class);
490 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
496 seat = hashmap_get(m->seats, cseat);
498 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
501 if (tty_is_vc(tty)) {
506 else if (seat != m->seat0)
507 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
509 v = vtnr_from_tty(tty);
511 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
515 else if (vtnr != (uint32_t) v)
516 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
518 } else if (tty_is_console(tty)) {
522 else if (seat != m->seat0)
523 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
526 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
530 if (seat_has_vts(seat)) {
531 if (!vtnr || vtnr > 63)
532 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
535 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
539 r = sd_bus_message_enter_container(message, 'a', "(sv)");
543 if (t == _SESSION_TYPE_INVALID) {
544 if (!isempty(display))
546 else if (!isempty(tty))
549 t = SESSION_UNSPECIFIED;
552 if (c == _SESSION_CLASS_INVALID) {
553 if (!isempty(display) || !isempty(tty))
556 c = SESSION_BACKGROUND;
560 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
562 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
566 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
568 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
573 manager_get_session_by_pid(m, leader, &session);
575 _cleanup_free_ char *path = NULL;
576 _cleanup_close_ int fifo_fd = -1;
578 /* Session already exists, client is probably
579 * something like "su" which changes uid but is still
580 * the same session */
582 fifo_fd = session_create_fifo(session);
586 path = session_bus_path(session);
590 return sd_bus_reply_method_return(
594 session->user->runtime_path,
596 (uint32_t) session->user->uid,
597 session->seat ? session->seat->id : "",
598 (uint32_t) session->vtnr,
602 audit_session_from_pid(leader, &audit_id);
604 /* Keep our session IDs and the audit session IDs in sync */
606 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
609 /* Wut? There's already a session by this name and we
610 * didn't find it above? Weird, then let's not trust
611 * the audit data and let's better register a new
613 if (hashmap_get(m->sessions, id)) {
614 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
627 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
630 } while (hashmap_get(m->sessions, id));
633 r = manager_add_user_by_uid(m, uid, &user);
637 r = manager_add_session(m, id, &session);
641 session_set_user(session, user);
643 session->leader = leader;
644 session->audit_id = audit_id;
647 session->remote = remote;
648 session->vtnr = vtnr;
651 session->tty = strdup(tty);
658 if (!isempty(display)) {
659 session->display = strdup(display);
660 if (!session->display) {
666 if (!isempty(remote_user)) {
667 session->remote_user = strdup(remote_user);
668 if (!session->remote_user) {
674 if (!isempty(remote_host)) {
675 session->remote_host = strdup(remote_host);
676 if (!session->remote_host) {
682 if (!isempty(service)) {
683 session->service = strdup(service);
684 if (!session->service) {
691 r = seat_attach_session(seat, session);
696 r = session_start(session);
700 session->create_message = sd_bus_message_ref(message);
702 /* Now, let's wait until the slice unit and stuff got
703 * created. We send the reply back from
704 * session_send_create_reply().*/
710 session_add_to_gc_queue(session);
713 user_add_to_gc_queue(user);
718 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
719 Manager *m = userdata;
728 r = sd_bus_message_read(message, "s", &name);
732 session = hashmap_get(m->sessions, name);
734 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
736 /* We use the FIFO to detect stray sessions where the process
737 invoking PAM dies abnormally. We need to make sure that
738 that process is not killed if at the clean end of the
739 session it closes the FIFO. Hence, with this call
740 explicitly turn off the FIFO logic, so that the PAM code
741 can finish clean up on its own */
742 session_remove_fifo(session);
743 session_save(session);
744 user_save(session->user);
746 return sd_bus_reply_method_return(message, NULL);
749 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
750 Manager *m = userdata;
759 r = sd_bus_message_read(message, "s", &name);
763 session = hashmap_get(m->sessions, name);
765 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
767 r = session_activate(session);
771 return sd_bus_reply_method_return(message, NULL);
774 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
775 const char *session_name, *seat_name;
776 Manager *m = userdata;
785 /* Same as ActivateSession() but refuses to work if
786 * the seat doesn't match */
788 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
792 session = hashmap_get(m->sessions, session_name);
794 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
796 seat = hashmap_get(m->seats, seat_name);
798 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
800 if (session->seat != seat)
801 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
803 r = session_activate(session);
807 return sd_bus_reply_method_return(message, NULL);
810 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
811 Manager *m = userdata;
820 r = sd_bus_message_read(message, "s", &name);
824 session = hashmap_get(m->sessions, name);
826 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
828 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
832 return sd_bus_reply_method_return(message, NULL);
835 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
836 Manager *m = userdata;
843 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
847 return sd_bus_reply_method_return(message, NULL);
850 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
851 const char *name, *swho;
852 Manager *m = userdata;
862 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
869 who = kill_who_from_string(swho);
871 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
874 if (signo <= 0 || signo >= _NSIG)
875 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
877 session = hashmap_get(m->sessions, name);
879 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
881 r = session_kill(session, who, signo);
885 return sd_bus_reply_method_return(message, NULL);
888 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
889 Manager *m = userdata;
899 r = sd_bus_message_read(message, "ui", &uid, &signo);
903 if (signo <= 0 || signo >= _NSIG)
904 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
906 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
908 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
910 r = user_kill(user, signo);
914 return sd_bus_reply_method_return(message, NULL);
917 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
918 Manager *m = userdata;
927 r = sd_bus_message_read(message, "s", &name);
931 session = hashmap_get(m->sessions, name);
933 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
935 r = session_stop(session);
939 return sd_bus_reply_method_return(message, NULL);
942 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
943 Manager *m = userdata;
952 r = sd_bus_message_read(message, "u", &uid);
956 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
958 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
964 return sd_bus_reply_method_return(message, NULL);
967 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
968 Manager *m = userdata;
977 r = sd_bus_message_read(message, "s", &name);
981 seat = hashmap_get(m->seats, name);
983 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
985 r = seat_stop_sessions(seat);
989 return sd_bus_reply_method_return(message, NULL);
992 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
993 _cleanup_free_ char *cc = NULL;
994 Manager *m = userdata;
1005 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1012 return errno ? -errno : -ENOENT;
1014 r = bus_verify_polkit_async(bus,
1015 &m->polkit_registry,
1017 "org.freedesktop.login1.set-user-linger",
1020 method_set_user_linger, m);
1024 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1026 mkdir_p_label("/var/lib/systemd", 0755);
1028 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1032 cc = cescape(pw->pw_name);
1036 path = strappenda("/var/lib/systemd/linger/", cc);
1044 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1051 if (r < 0 && errno != ENOENT)
1054 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1056 user_add_to_gc_queue(u);
1059 return sd_bus_reply_method_return(message, NULL);
1062 static int trigger_device(Manager *m, struct udev_device *d) {
1063 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1064 struct udev_list_entry *first, *item;
1069 e = udev_enumerate_new(m->udev);
1074 r = udev_enumerate_add_match_parent(e, d);
1079 r = udev_enumerate_scan_devices(e);
1083 first = udev_enumerate_get_list_entry(e);
1084 udev_list_entry_foreach(item, first) {
1085 _cleanup_free_ char *t = NULL;
1088 p = udev_list_entry_get_name(item);
1090 t = strappend(p, "/uevent");
1094 write_string_file(t, "change");
1100 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1101 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1102 _cleanup_free_ char *rule = NULL, *file = NULL;
1103 const char *id_for_seat;
1110 d = udev_device_new_from_syspath(m->udev, sysfs);
1114 if (!udev_device_has_tag(d, "seat"))
1117 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1121 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1124 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1127 mkdir_p_label("/etc/udev/rules.d", 0755);
1129 r = write_string_file_atomic_label(file, rule);
1133 return trigger_device(m, d);
1136 static int flush_devices(Manager *m) {
1137 _cleanup_closedir_ DIR *d;
1141 d = opendir("/etc/udev/rules.d");
1143 if (errno != ENOENT)
1144 log_warning("Failed to open /etc/udev/rules.d: %m");
1148 while ((de = readdir(d))) {
1150 if (!dirent_is_file(de))
1153 if (!startswith(de->d_name, "72-seat-"))
1156 if (!endswith(de->d_name, ".rules"))
1159 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1160 log_warning("Failed to unlink %s: %m", de->d_name);
1164 return trigger_device(m, NULL);
1167 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1168 const char *sysfs, *seat;
1169 Manager *m = userdata;
1176 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1180 if (!path_startswith(sysfs, "/sys"))
1181 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1183 if (!seat_name_is_valid(seat))
1184 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1186 r = bus_verify_polkit_async(bus,
1187 &m->polkit_registry,
1189 "org.freedesktop.login1.attach-device",
1192 method_attach_device, m);
1196 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1198 r = attach_device(m, seat, sysfs);
1202 return sd_bus_reply_method_return(message, NULL);
1205 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1206 Manager *m = userdata;
1213 r = sd_bus_message_read(message, "b", &interactive);
1217 r = bus_verify_polkit_async(bus,
1218 &m->polkit_registry,
1220 "org.freedesktop.login1.flush-devices",
1223 method_flush_devices, m);
1227 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1229 r = flush_devices(m);
1233 return sd_bus_reply_method_return(message, NULL);
1236 static int have_multiple_sessions(
1245 /* Check for other users' sessions. Greeter sessions do not
1246 * count, and non-login sessions do not count either. */
1247 HASHMAP_FOREACH(session, m->sessions, i)
1248 if (session->class == SESSION_USER &&
1249 session->user->uid != uid)
1255 static int bus_manager_log_shutdown(
1258 const char *unit_name) {
1265 if (w != INHIBIT_SHUTDOWN)
1268 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1269 p = "MESSAGE=System is powering down.";
1270 q = "SHUTDOWN=power-off";
1271 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1272 p = "MESSAGE=System is halting.";
1273 q = "SHUTDOWN=halt";
1274 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1275 p = "MESSAGE=System is rebooting.";
1276 q = "SHUTDOWN=reboot";
1277 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1278 p = "MESSAGE=System is rebooting with kexec.";
1279 q = "SHUTDOWN=kexec";
1281 p = "MESSAGE=System is shutting down.";
1285 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1290 static int execute_shutdown_or_sleep(
1293 const char *unit_name,
1294 sd_bus_error *error) {
1296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1303 assert(w < _INHIBIT_WHAT_MAX);
1306 bus_manager_log_shutdown(m, w, unit_name);
1308 r = sd_bus_call_method(
1310 "org.freedesktop.systemd1",
1311 "/org/freedesktop/systemd1",
1312 "org.freedesktop.systemd1.Manager",
1316 "ss", unit_name, "replace-irreversibly");
1320 r = sd_bus_message_read(reply, "o", &p);
1328 m->action_unit = unit_name;
1329 free(m->action_job);
1336 static int delay_shutdown_or_sleep(
1339 const char *unit_name) {
1343 assert(w < _INHIBIT_WHAT_MAX);
1346 m->action_timestamp = now(CLOCK_MONOTONIC);
1347 m->action_unit = unit_name;
1353 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1355 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1356 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1357 [INHIBIT_SLEEP] = "PrepareForSleep"
1360 int active = _active;
1364 assert(w < _INHIBIT_WHAT_MAX);
1365 assert(signal_name[w]);
1367 return sd_bus_emit_signal(m->bus,
1368 "/org/freedesktop/login1",
1369 "org.freedesktop.login1.Manager",
1375 int bus_manager_shutdown_or_sleep_now_or_later(
1377 const char *unit_name,
1379 sd_bus_error *error) {
1387 assert(w <= _INHIBIT_WHAT_MAX);
1388 assert(!m->action_job);
1390 /* Tell everybody to prepare for shutdown/sleep */
1391 send_prepare_for(m, w, true);
1394 m->inhibit_delay_max > 0 &&
1395 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1398 /* Shutdown is delayed, keep in mind what we
1399 * want to do, and start a timeout */
1400 r = delay_shutdown_or_sleep(m, w, unit_name);
1402 /* Shutdown is not delayed, execute it
1404 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1409 static int method_do_shutdown_or_sleep(
1411 sd_bus_message *message,
1412 const char *unit_name,
1415 const char *action_multiple_sessions,
1416 const char *action_ignore_inhibit,
1417 const char *sleep_verb,
1418 sd_bus_message_handler_t method,
1419 sd_bus_error *error) {
1421 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1422 bool multiple_sessions, blocked;
1430 assert(w <= _INHIBIT_WHAT_MAX);
1432 assert(action_multiple_sessions);
1433 assert(action_ignore_inhibit);
1436 r = sd_bus_message_read(message, "b", &interactive);
1440 /* Don't allow multiple jobs being executed at the same time */
1442 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1445 r = can_sleep(sleep_verb);
1450 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1453 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1457 r = sd_bus_creds_get_uid(creds, &uid);
1461 r = have_multiple_sessions(m, uid);
1465 multiple_sessions = r > 0;
1466 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1468 if (multiple_sessions) {
1469 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1470 action_multiple_sessions, interactive, error, method, m);
1476 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1477 action_ignore_inhibit, interactive, error, method, m);
1482 if (!multiple_sessions && !blocked) {
1483 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1484 action, interactive, error, method, m);
1489 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1493 return sd_bus_reply_method_return(message, NULL);
1496 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1497 Manager *m = userdata;
1499 return method_do_shutdown_or_sleep(
1501 SPECIAL_POWEROFF_TARGET,
1503 "org.freedesktop.login1.power-off",
1504 "org.freedesktop.login1.power-off-multiple-sessions",
1505 "org.freedesktop.login1.power-off-ignore-inhibit",
1511 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1512 Manager *m = userdata;
1514 return method_do_shutdown_or_sleep(
1516 SPECIAL_REBOOT_TARGET,
1518 "org.freedesktop.login1.reboot",
1519 "org.freedesktop.login1.reboot-multiple-sessions",
1520 "org.freedesktop.login1.reboot-ignore-inhibit",
1526 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1527 Manager *m = userdata;
1529 return method_do_shutdown_or_sleep(
1531 SPECIAL_SUSPEND_TARGET,
1533 "org.freedesktop.login1.suspend",
1534 "org.freedesktop.login1.suspend-multiple-sessions",
1535 "org.freedesktop.login1.suspend-ignore-inhibit",
1541 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1542 Manager *m = userdata;
1544 return method_do_shutdown_or_sleep(
1546 SPECIAL_HIBERNATE_TARGET,
1548 "org.freedesktop.login1.hibernate",
1549 "org.freedesktop.login1.hibernate-multiple-sessions",
1550 "org.freedesktop.login1.hibernate-ignore-inhibit",
1556 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1557 Manager *m = userdata;
1559 return method_do_shutdown_or_sleep(
1561 SPECIAL_HYBRID_SLEEP_TARGET,
1563 "org.freedesktop.login1.hibernate",
1564 "org.freedesktop.login1.hibernate-multiple-sessions",
1565 "org.freedesktop.login1.hibernate-ignore-inhibit",
1567 method_hybrid_sleep,
1571 static int method_can_shutdown_or_sleep(
1573 sd_bus_message *message,
1576 const char *action_multiple_sessions,
1577 const char *action_ignore_inhibit,
1578 const char *sleep_verb,
1579 sd_bus_error *error) {
1581 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1582 bool multiple_sessions, challenge, blocked;
1583 const char *result = NULL;
1590 assert(w <= _INHIBIT_WHAT_MAX);
1592 assert(action_multiple_sessions);
1593 assert(action_ignore_inhibit);
1596 r = can_sleep(sleep_verb);
1600 return sd_bus_reply_method_return(message, "s", "na");
1603 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1607 r = sd_bus_creds_get_uid(creds, &uid);
1611 r = have_multiple_sessions(m, uid);
1615 multiple_sessions = r > 0;
1616 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1618 if (multiple_sessions) {
1619 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1626 result = "challenge";
1632 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1636 if (r > 0 && !result)
1638 else if (challenge && (!result || streq(result, "yes")))
1639 result = "challenge";
1644 if (!multiple_sessions && !blocked) {
1645 /* If neither inhibit nor multiple sessions
1646 * apply then just check the normal policy */
1648 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1655 result = "challenge";
1660 return sd_bus_reply_method_return(message, "s", result);
1663 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1664 Manager *m = userdata;
1666 return method_can_shutdown_or_sleep(
1669 "org.freedesktop.login1.power-off",
1670 "org.freedesktop.login1.power-off-multiple-sessions",
1671 "org.freedesktop.login1.power-off-ignore-inhibit",
1676 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1677 Manager *m = userdata;
1679 return method_can_shutdown_or_sleep(
1682 "org.freedesktop.login1.reboot",
1683 "org.freedesktop.login1.reboot-multiple-sessions",
1684 "org.freedesktop.login1.reboot-ignore-inhibit",
1689 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1690 Manager *m = userdata;
1692 return method_can_shutdown_or_sleep(
1695 "org.freedesktop.login1.suspend",
1696 "org.freedesktop.login1.suspend-multiple-sessions",
1697 "org.freedesktop.login1.suspend-ignore-inhibit",
1702 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1703 Manager *m = userdata;
1705 return method_can_shutdown_or_sleep(
1708 "org.freedesktop.login1.hibernate",
1709 "org.freedesktop.login1.hibernate-multiple-sessions",
1710 "org.freedesktop.login1.hibernate-ignore-inhibit",
1715 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1716 Manager *m = userdata;
1718 return method_can_shutdown_or_sleep(
1721 "org.freedesktop.login1.hibernate",
1722 "org.freedesktop.login1.hibernate-multiple-sessions",
1723 "org.freedesktop.login1.hibernate-ignore-inhibit",
1728 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1729 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1730 const char *who, *why, *what, *mode;
1731 _cleanup_free_ char *id = NULL;
1732 _cleanup_close_ int fifo_fd = -1;
1733 Manager *m = userdata;
1734 Inhibitor *i = NULL;
1745 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1749 w = inhibit_what_from_string(what);
1751 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1753 mm = inhibit_mode_from_string(mode);
1755 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1757 /* Delay is only supported for shutdown/sleep */
1758 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1759 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1761 /* Don't allow taking delay locks while we are already
1762 * executing the operation. We shouldn't create the impression
1763 * that the lock was successful if the machine is about to go
1764 * down/suspend any moment. */
1765 if (m->action_what & w)
1766 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1768 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1769 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1770 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1771 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1772 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1773 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1774 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1775 "org.freedesktop.login1.inhibit-handle-lid-switch",
1776 false, error, method_inhibit, m);
1780 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1782 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1786 r = sd_bus_creds_get_uid(creds, &uid);
1790 r = sd_bus_creds_get_pid(creds, &pid);
1798 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1801 } while (hashmap_get(m->inhibitors, id));
1803 r = manager_add_inhibitor(m, id, &i);
1811 i->why = strdup(why);
1812 i->who = strdup(who);
1814 if (!i->why || !i->who) {
1819 fifo_fd = inhibitor_create_fifo(i);
1827 return sd_bus_reply_method_return(message, "h", fifo_fd);
1836 const sd_bus_vtable manager_vtable[] = {
1837 SD_BUS_VTABLE_START(0),
1839 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1840 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1841 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1842 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1843 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1844 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1845 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1846 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1847 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1848 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1849 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1850 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1851 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1852 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1853 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1854 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1855 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1856 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1858 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1859 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1860 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1861 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1862 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1863 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1864 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1865 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1866 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1867 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
1868 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1869 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1870 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1871 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1872 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1873 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1874 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1875 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1876 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1877 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1878 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1879 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1880 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1881 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1882 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1883 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1884 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1885 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1887 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1888 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1889 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1890 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1893 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1895 SD_BUS_SIGNAL("SessionNew", "so", 0),
1896 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1897 SD_BUS_SIGNAL("UserNew", "uo", 0),
1898 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1899 SD_BUS_SIGNAL("SeatNew", "so", 0),
1900 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1901 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1902 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1907 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1908 const char *path, *result, *unit;
1909 Manager *m = userdata;
1919 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1921 bus_log_parse_error(r);
1925 if (m->action_job && streq(m->action_job, path)) {
1926 log_info("Operation finished.");
1928 /* Tell people that they now may take a lock again */
1929 send_prepare_for(m, m->action_what, false);
1931 free(m->action_job);
1932 m->action_job = NULL;
1933 m->action_unit = NULL;
1938 session = hashmap_get(m->session_units, unit);
1941 if (streq_ptr(path, session->scope_job)) {
1942 free(session->scope_job);
1943 session->scope_job = NULL;
1946 if (session->started) {
1947 if (streq(result, "done"))
1948 session_send_create_reply(session, NULL);
1950 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1952 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1953 session_send_create_reply(session, &e);
1956 session_save(session);
1958 session_add_to_gc_queue(session);
1961 user = hashmap_get(m->user_units, unit);
1964 if (streq_ptr(path, user->service_job)) {
1965 free(user->service_job);
1966 user->service_job = NULL;
1969 if (streq_ptr(path, user->slice_job)) {
1970 free(user->slice_job);
1971 user->slice_job = NULL;
1975 user_add_to_gc_queue(user);
1981 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1982 const char *path, *unit;
1983 Manager *m = userdata;
1992 r = sd_bus_message_read(message, "so", &unit, &path);
1994 bus_log_parse_error(r);
1998 session = hashmap_get(m->session_units, unit);
2000 session_add_to_gc_queue(session);
2002 user = hashmap_get(m->user_units, unit);
2004 user_add_to_gc_queue(user);
2009 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2010 _cleanup_free_ char *unit = NULL;
2011 Manager *m = userdata;
2021 path = sd_bus_message_get_path(message);
2025 r = unit_name_from_dbus_path(path, &unit);
2029 session = hashmap_get(m->session_units, unit);
2031 session_add_to_gc_queue(session);
2033 user = hashmap_get(m->user_units, unit);
2035 user_add_to_gc_queue(user);
2040 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2041 Manager *m = userdata;
2048 r = sd_bus_message_read(message, "b", &b);
2050 bus_log_parse_error(r);
2057 /* systemd finished reloading, let's recheck all our sessions */
2058 log_debug("System manager has been reloaded, rechecking sessions...");
2060 HASHMAP_FOREACH(session, m->sessions, i)
2061 session_add_to_gc_queue(session);
2066 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2067 const char *name, *old, *new;
2068 Manager *m = userdata;
2076 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2078 bus_log_parse_error(r);
2082 if (isempty(old) || !isempty(new))
2085 key = set_remove(m->busnames, (char*) old);
2089 /* Drop all controllers owned by this name */
2093 HASHMAP_FOREACH(session, m->sessions, i)
2094 if (session_is_controller(session, old))
2095 session_drop_controller(session);
2100 int manager_send_changed(Manager *manager, const char *property, ...) {
2105 l = strv_from_stdarg_alloca(property);
2107 return sd_bus_emit_properties_changed_strv(
2109 "/org/freedesktop/login1",
2110 "org.freedesktop.login1.Manager",
2114 int manager_dispatch_delayed(Manager *manager) {
2115 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2116 Inhibitor *offending = NULL;
2121 if (manager->action_what == 0 || manager->action_job)
2124 /* Continue delay? */
2125 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2126 _cleanup_free_ char *comm = NULL, *u = NULL;
2128 get_process_comm(offending->pid, &comm);
2129 u = uid_to_name(offending->uid);
2131 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2134 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2135 (unsigned long) offending->uid, strna(u),
2136 (unsigned long) offending->pid, strna(comm));
2139 /* Actually do the operation */
2140 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2142 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2144 manager->action_unit = NULL;
2145 manager->action_what = 0;
2152 int manager_start_scope(
2157 const char *description,
2159 const char *kill_mode,
2160 sd_bus_error *error,
2163 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2170 r = sd_bus_message_new_method_call(
2172 "org.freedesktop.systemd1",
2173 "/org/freedesktop/systemd1",
2174 "org.freedesktop.systemd1.Manager",
2175 "StartTransientUnit",
2180 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2184 r = sd_bus_message_open_container(m, 'a', "(sv)");
2188 if (!isempty(slice)) {
2189 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2194 if (!isempty(description)) {
2195 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2200 if (!isempty(description)) {
2201 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2206 if (!isempty(kill_mode)) {
2207 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2212 /* cgroup empty notification is not available in containers
2213 * currently. To make this less problematic, let's shorten the
2214 * stop timeout for sessions, so that we don't wait
2217 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2221 /* Make sure that the session shells are terminated with
2222 * SIGHUP since bash and friends tend to ignore SIGTERM */
2223 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2227 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2231 r = sd_bus_message_close_container(m);
2235 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2239 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2247 r = sd_bus_message_read(reply, "o", &j);
2261 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2262 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2268 r = sd_bus_call_method(
2270 "org.freedesktop.systemd1",
2271 "/org/freedesktop/systemd1",
2272 "org.freedesktop.systemd1.Manager",
2276 "ss", unit, "fail");
2284 r = sd_bus_message_read(reply, "o", &j);
2298 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2299 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2305 r = sd_bus_call_method(
2307 "org.freedesktop.systemd1",
2308 "/org/freedesktop/systemd1",
2309 "org.freedesktop.systemd1.Manager",
2313 "ss", unit, "fail");
2315 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2316 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2321 sd_bus_error_free(error);
2332 r = sd_bus_message_read(reply, "o", &j);
2346 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2350 return sd_bus_call_method(
2352 "org.freedesktop.systemd1",
2353 "/org/freedesktop/systemd1",
2354 "org.freedesktop.systemd1.Manager",
2358 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2361 int manager_unit_is_active(Manager *manager, const char *unit) {
2362 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2363 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2364 _cleanup_free_ char *path = NULL;
2371 path = unit_dbus_path_from_name(unit);
2375 r = sd_bus_get_property(
2377 "org.freedesktop.systemd1",
2379 "org.freedesktop.systemd1.Unit",
2385 /* systemd might have droppped off momentarily, let's
2386 * not make this an error */
2387 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2388 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2391 /* If the unit is already unloaded then it's not
2393 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2394 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2400 r = sd_bus_message_read(reply, "s", &state);
2404 return !streq(state, "inactive") && !streq(state, "failed");
2407 int manager_job_is_active(Manager *manager, const char *path) {
2408 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2409 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2415 r = sd_bus_get_property(
2417 "org.freedesktop.systemd1",
2419 "org.freedesktop.systemd1.Job",
2425 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2426 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2429 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2435 /* We don't actually care about the state really. The fact
2436 * that we could read the job state is enough for us */