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, *desktop;
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, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &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);
493 if (isempty(desktop))
496 if (!string_is_safe(desktop))
497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
503 seat = hashmap_get(m->seats, cseat);
505 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
508 if (tty_is_vc(tty)) {
513 else if (seat != m->seat0)
514 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
516 v = vtnr_from_tty(tty);
518 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
522 else if (vtnr != (uint32_t) v)
523 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
525 } else if (tty_is_console(tty)) {
529 else if (seat != m->seat0)
530 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
533 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
537 if (seat_has_vts(seat)) {
538 if (!vtnr || vtnr > 63)
539 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
542 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
546 r = sd_bus_message_enter_container(message, 'a', "(sv)");
550 if (t == _SESSION_TYPE_INVALID) {
551 if (!isempty(display))
553 else if (!isempty(tty))
556 t = SESSION_UNSPECIFIED;
559 if (c == _SESSION_CLASS_INVALID) {
560 if (t == SESSION_UNSPECIFIED)
561 c = SESSION_BACKGROUND;
567 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
569 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
573 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
575 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
580 manager_get_session_by_pid(m, leader, &session);
582 _cleanup_free_ char *path = NULL;
583 _cleanup_close_ int fifo_fd = -1;
585 /* Session already exists, client is probably
586 * something like "su" which changes uid but is still
587 * the same session */
589 fifo_fd = session_create_fifo(session);
593 path = session_bus_path(session);
597 return sd_bus_reply_method_return(
601 session->user->runtime_path,
603 (uint32_t) session->user->uid,
604 session->seat ? session->seat->id : "",
605 (uint32_t) session->vtnr,
609 audit_session_from_pid(leader, &audit_id);
611 /* Keep our session IDs and the audit session IDs in sync */
613 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
616 /* Wut? There's already a session by this name and we
617 * didn't find it above? Weird, then let's not trust
618 * the audit data and let's better register a new
620 if (hashmap_get(m->sessions, id)) {
621 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
634 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
637 } while (hashmap_get(m->sessions, id));
640 r = manager_add_user_by_uid(m, uid, &user);
644 r = manager_add_session(m, id, &session);
648 session_set_user(session, user);
650 session->leader = leader;
651 session->audit_id = audit_id;
654 session->remote = remote;
655 session->vtnr = vtnr;
658 session->tty = strdup(tty);
665 if (!isempty(display)) {
666 session->display = strdup(display);
667 if (!session->display) {
673 if (!isempty(remote_user)) {
674 session->remote_user = strdup(remote_user);
675 if (!session->remote_user) {
681 if (!isempty(remote_host)) {
682 session->remote_host = strdup(remote_host);
683 if (!session->remote_host) {
689 if (!isempty(service)) {
690 session->service = strdup(service);
691 if (!session->service) {
697 if (!isempty(desktop)) {
698 session->desktop = strdup(desktop);
699 if (!session->desktop) {
706 r = seat_attach_session(seat, session);
711 r = session_start(session);
715 session->create_message = sd_bus_message_ref(message);
717 /* Now, let's wait until the slice unit and stuff got
718 * created. We send the reply back from
719 * session_send_create_reply().*/
725 session_add_to_gc_queue(session);
728 user_add_to_gc_queue(user);
733 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
734 Manager *m = userdata;
743 r = sd_bus_message_read(message, "s", &name);
747 session = hashmap_get(m->sessions, name);
749 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
751 session_release(session);
753 return sd_bus_reply_method_return(message, NULL);
756 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
757 Manager *m = userdata;
766 r = sd_bus_message_read(message, "s", &name);
770 session = hashmap_get(m->sessions, name);
772 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
774 r = session_activate(session);
778 return sd_bus_reply_method_return(message, NULL);
781 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
782 const char *session_name, *seat_name;
783 Manager *m = userdata;
792 /* Same as ActivateSession() but refuses to work if
793 * the seat doesn't match */
795 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
799 session = hashmap_get(m->sessions, session_name);
801 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
803 seat = hashmap_get(m->seats, seat_name);
805 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
807 if (session->seat != seat)
808 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
810 r = session_activate(session);
814 return sd_bus_reply_method_return(message, NULL);
817 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
818 Manager *m = userdata;
827 r = sd_bus_message_read(message, "s", &name);
831 session = hashmap_get(m->sessions, name);
833 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
835 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
839 return sd_bus_reply_method_return(message, NULL);
842 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
843 Manager *m = userdata;
850 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
854 return sd_bus_reply_method_return(message, NULL);
857 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
858 const char *name, *swho;
859 Manager *m = userdata;
869 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
876 who = kill_who_from_string(swho);
878 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
881 if (signo <= 0 || signo >= _NSIG)
882 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
884 session = hashmap_get(m->sessions, name);
886 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
888 r = session_kill(session, who, signo);
892 return sd_bus_reply_method_return(message, NULL);
895 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
896 Manager *m = userdata;
906 r = sd_bus_message_read(message, "ui", &uid, &signo);
910 if (signo <= 0 || signo >= _NSIG)
911 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
913 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
915 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
917 r = user_kill(user, signo);
921 return sd_bus_reply_method_return(message, NULL);
924 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
925 Manager *m = userdata;
934 r = sd_bus_message_read(message, "s", &name);
938 session = hashmap_get(m->sessions, name);
940 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
942 r = session_stop(session, true);
946 return sd_bus_reply_method_return(message, NULL);
949 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
950 Manager *m = userdata;
959 r = sd_bus_message_read(message, "u", &uid);
963 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
965 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
967 r = user_stop(user, true);
971 return sd_bus_reply_method_return(message, NULL);
974 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
975 Manager *m = userdata;
984 r = sd_bus_message_read(message, "s", &name);
988 seat = hashmap_get(m->seats, name);
990 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
992 r = seat_stop_sessions(seat, true);
996 return sd_bus_reply_method_return(message, NULL);
999 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1000 _cleanup_free_ char *cc = NULL;
1001 Manager *m = userdata;
1012 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1019 return errno ? -errno : -ENOENT;
1021 r = bus_verify_polkit_async(bus,
1022 &m->polkit_registry,
1024 "org.freedesktop.login1.set-user-linger",
1027 method_set_user_linger, m);
1031 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1033 mkdir_p_label("/var/lib/systemd", 0755);
1035 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1039 cc = cescape(pw->pw_name);
1043 path = strappenda("/var/lib/systemd/linger/", cc);
1051 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1058 if (r < 0 && errno != ENOENT)
1061 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1063 user_add_to_gc_queue(u);
1066 return sd_bus_reply_method_return(message, NULL);
1069 static int trigger_device(Manager *m, struct udev_device *d) {
1070 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1071 struct udev_list_entry *first, *item;
1076 e = udev_enumerate_new(m->udev);
1081 r = udev_enumerate_add_match_parent(e, d);
1086 r = udev_enumerate_scan_devices(e);
1090 first = udev_enumerate_get_list_entry(e);
1091 udev_list_entry_foreach(item, first) {
1092 _cleanup_free_ char *t = NULL;
1095 p = udev_list_entry_get_name(item);
1097 t = strappend(p, "/uevent");
1101 write_string_file(t, "change");
1107 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1108 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1109 _cleanup_free_ char *rule = NULL, *file = NULL;
1110 const char *id_for_seat;
1117 d = udev_device_new_from_syspath(m->udev, sysfs);
1121 if (!udev_device_has_tag(d, "seat"))
1124 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1128 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1131 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1134 mkdir_p_label("/etc/udev/rules.d", 0755);
1136 r = write_string_file_atomic_label(file, rule);
1140 return trigger_device(m, d);
1143 static int flush_devices(Manager *m) {
1144 _cleanup_closedir_ DIR *d;
1148 d = opendir("/etc/udev/rules.d");
1150 if (errno != ENOENT)
1151 log_warning("Failed to open /etc/udev/rules.d: %m");
1155 while ((de = readdir(d))) {
1157 if (!dirent_is_file(de))
1160 if (!startswith(de->d_name, "72-seat-"))
1163 if (!endswith(de->d_name, ".rules"))
1166 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1167 log_warning("Failed to unlink %s: %m", de->d_name);
1171 return trigger_device(m, NULL);
1174 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1175 const char *sysfs, *seat;
1176 Manager *m = userdata;
1183 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1187 if (!path_startswith(sysfs, "/sys"))
1188 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1190 if (!seat_name_is_valid(seat))
1191 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1193 r = bus_verify_polkit_async(bus,
1194 &m->polkit_registry,
1196 "org.freedesktop.login1.attach-device",
1199 method_attach_device, m);
1203 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1205 r = attach_device(m, seat, sysfs);
1209 return sd_bus_reply_method_return(message, NULL);
1212 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1213 Manager *m = userdata;
1220 r = sd_bus_message_read(message, "b", &interactive);
1224 r = bus_verify_polkit_async(bus,
1225 &m->polkit_registry,
1227 "org.freedesktop.login1.flush-devices",
1230 method_flush_devices, m);
1234 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1236 r = flush_devices(m);
1240 return sd_bus_reply_method_return(message, NULL);
1243 static int have_multiple_sessions(
1252 /* Check for other users' sessions. Greeter sessions do not
1253 * count, and non-login sessions do not count either. */
1254 HASHMAP_FOREACH(session, m->sessions, i)
1255 if (session->class == SESSION_USER &&
1256 session->user->uid != uid)
1262 static int bus_manager_log_shutdown(
1265 const char *unit_name) {
1272 if (w != INHIBIT_SHUTDOWN)
1275 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1276 p = "MESSAGE=System is powering down.";
1277 q = "SHUTDOWN=power-off";
1278 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1279 p = "MESSAGE=System is halting.";
1280 q = "SHUTDOWN=halt";
1281 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1282 p = "MESSAGE=System is rebooting.";
1283 q = "SHUTDOWN=reboot";
1284 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1285 p = "MESSAGE=System is rebooting with kexec.";
1286 q = "SHUTDOWN=kexec";
1288 p = "MESSAGE=System is shutting down.";
1292 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1297 static int execute_shutdown_or_sleep(
1300 const char *unit_name,
1301 sd_bus_error *error) {
1303 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1310 assert(w < _INHIBIT_WHAT_MAX);
1313 bus_manager_log_shutdown(m, w, unit_name);
1315 r = sd_bus_call_method(
1317 "org.freedesktop.systemd1",
1318 "/org/freedesktop/systemd1",
1319 "org.freedesktop.systemd1.Manager",
1323 "ss", unit_name, "replace-irreversibly");
1327 r = sd_bus_message_read(reply, "o", &p);
1335 m->action_unit = unit_name;
1336 free(m->action_job);
1340 /* Make sure the lid switch is ignored for a while */
1341 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
1346 static int delay_shutdown_or_sleep(
1349 const char *unit_name) {
1353 assert(w < _INHIBIT_WHAT_MAX);
1356 m->action_timestamp = now(CLOCK_MONOTONIC);
1357 m->action_unit = unit_name;
1363 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1365 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1366 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1367 [INHIBIT_SLEEP] = "PrepareForSleep"
1370 int active = _active;
1374 assert(w < _INHIBIT_WHAT_MAX);
1375 assert(signal_name[w]);
1377 return sd_bus_emit_signal(m->bus,
1378 "/org/freedesktop/login1",
1379 "org.freedesktop.login1.Manager",
1385 int bus_manager_shutdown_or_sleep_now_or_later(
1387 const char *unit_name,
1389 sd_bus_error *error) {
1397 assert(w <= _INHIBIT_WHAT_MAX);
1398 assert(!m->action_job);
1400 /* Tell everybody to prepare for shutdown/sleep */
1401 send_prepare_for(m, w, true);
1404 m->inhibit_delay_max > 0 &&
1405 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1408 /* Shutdown is delayed, keep in mind what we
1409 * want to do, and start a timeout */
1410 r = delay_shutdown_or_sleep(m, w, unit_name);
1412 /* Shutdown is not delayed, execute it
1414 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1419 static int method_do_shutdown_or_sleep(
1421 sd_bus_message *message,
1422 const char *unit_name,
1425 const char *action_multiple_sessions,
1426 const char *action_ignore_inhibit,
1427 const char *sleep_verb,
1428 sd_bus_message_handler_t method,
1429 sd_bus_error *error) {
1431 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1432 bool multiple_sessions, blocked;
1440 assert(w <= _INHIBIT_WHAT_MAX);
1442 assert(action_multiple_sessions);
1443 assert(action_ignore_inhibit);
1446 r = sd_bus_message_read(message, "b", &interactive);
1450 /* Don't allow multiple jobs being executed at the same time */
1452 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1455 r = can_sleep(sleep_verb);
1460 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1463 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1467 r = sd_bus_creds_get_uid(creds, &uid);
1471 r = have_multiple_sessions(m, uid);
1475 multiple_sessions = r > 0;
1476 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1478 if (multiple_sessions) {
1479 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1480 action_multiple_sessions, interactive, error, method, m);
1484 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1488 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1489 action_ignore_inhibit, interactive, error, method, m);
1493 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1496 if (!multiple_sessions && !blocked) {
1497 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1498 action, interactive, error, method, m);
1502 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1505 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1509 return sd_bus_reply_method_return(message, NULL);
1512 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1513 Manager *m = userdata;
1515 return method_do_shutdown_or_sleep(
1517 SPECIAL_POWEROFF_TARGET,
1519 "org.freedesktop.login1.power-off",
1520 "org.freedesktop.login1.power-off-multiple-sessions",
1521 "org.freedesktop.login1.power-off-ignore-inhibit",
1527 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1528 Manager *m = userdata;
1530 return method_do_shutdown_or_sleep(
1532 SPECIAL_REBOOT_TARGET,
1534 "org.freedesktop.login1.reboot",
1535 "org.freedesktop.login1.reboot-multiple-sessions",
1536 "org.freedesktop.login1.reboot-ignore-inhibit",
1542 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1543 Manager *m = userdata;
1545 return method_do_shutdown_or_sleep(
1547 SPECIAL_SUSPEND_TARGET,
1549 "org.freedesktop.login1.suspend",
1550 "org.freedesktop.login1.suspend-multiple-sessions",
1551 "org.freedesktop.login1.suspend-ignore-inhibit",
1557 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1558 Manager *m = userdata;
1560 return method_do_shutdown_or_sleep(
1562 SPECIAL_HIBERNATE_TARGET,
1564 "org.freedesktop.login1.hibernate",
1565 "org.freedesktop.login1.hibernate-multiple-sessions",
1566 "org.freedesktop.login1.hibernate-ignore-inhibit",
1572 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1573 Manager *m = userdata;
1575 return method_do_shutdown_or_sleep(
1577 SPECIAL_HYBRID_SLEEP_TARGET,
1579 "org.freedesktop.login1.hibernate",
1580 "org.freedesktop.login1.hibernate-multiple-sessions",
1581 "org.freedesktop.login1.hibernate-ignore-inhibit",
1583 method_hybrid_sleep,
1587 static int method_can_shutdown_or_sleep(
1589 sd_bus_message *message,
1592 const char *action_multiple_sessions,
1593 const char *action_ignore_inhibit,
1594 const char *sleep_verb,
1595 sd_bus_error *error) {
1597 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1598 bool multiple_sessions, challenge, blocked;
1599 const char *result = NULL;
1606 assert(w <= _INHIBIT_WHAT_MAX);
1608 assert(action_multiple_sessions);
1609 assert(action_ignore_inhibit);
1612 r = can_sleep(sleep_verb);
1616 return sd_bus_reply_method_return(message, "s", "na");
1619 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1623 r = sd_bus_creds_get_uid(creds, &uid);
1627 r = have_multiple_sessions(m, uid);
1631 multiple_sessions = r > 0;
1632 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1634 if (multiple_sessions) {
1635 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1642 result = "challenge";
1648 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1652 if (r > 0 && !result)
1654 else if (challenge && (!result || streq(result, "yes")))
1655 result = "challenge";
1660 if (!multiple_sessions && !blocked) {
1661 /* If neither inhibit nor multiple sessions
1662 * apply then just check the normal policy */
1664 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1671 result = "challenge";
1676 return sd_bus_reply_method_return(message, "s", result);
1679 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1680 Manager *m = userdata;
1682 return method_can_shutdown_or_sleep(
1685 "org.freedesktop.login1.power-off",
1686 "org.freedesktop.login1.power-off-multiple-sessions",
1687 "org.freedesktop.login1.power-off-ignore-inhibit",
1692 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1693 Manager *m = userdata;
1695 return method_can_shutdown_or_sleep(
1698 "org.freedesktop.login1.reboot",
1699 "org.freedesktop.login1.reboot-multiple-sessions",
1700 "org.freedesktop.login1.reboot-ignore-inhibit",
1705 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1706 Manager *m = userdata;
1708 return method_can_shutdown_or_sleep(
1711 "org.freedesktop.login1.suspend",
1712 "org.freedesktop.login1.suspend-multiple-sessions",
1713 "org.freedesktop.login1.suspend-ignore-inhibit",
1718 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1719 Manager *m = userdata;
1721 return method_can_shutdown_or_sleep(
1724 "org.freedesktop.login1.hibernate",
1725 "org.freedesktop.login1.hibernate-multiple-sessions",
1726 "org.freedesktop.login1.hibernate-ignore-inhibit",
1731 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1732 Manager *m = userdata;
1734 return method_can_shutdown_or_sleep(
1737 "org.freedesktop.login1.hibernate",
1738 "org.freedesktop.login1.hibernate-multiple-sessions",
1739 "org.freedesktop.login1.hibernate-ignore-inhibit",
1744 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1745 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1746 const char *who, *why, *what, *mode;
1747 _cleanup_free_ char *id = NULL;
1748 _cleanup_close_ int fifo_fd = -1;
1749 Manager *m = userdata;
1750 Inhibitor *i = NULL;
1761 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1765 w = inhibit_what_from_string(what);
1767 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1769 mm = inhibit_mode_from_string(mode);
1771 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1773 /* Delay is only supported for shutdown/sleep */
1774 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1775 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1777 /* Don't allow taking delay locks while we are already
1778 * executing the operation. We shouldn't create the impression
1779 * that the lock was successful if the machine is about to go
1780 * down/suspend any moment. */
1781 if (m->action_what & w)
1782 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1784 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1785 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1786 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1787 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1788 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1789 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1790 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1791 "org.freedesktop.login1.inhibit-handle-lid-switch",
1792 false, error, method_inhibit, m);
1796 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1798 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1802 r = sd_bus_creds_get_uid(creds, &uid);
1806 r = sd_bus_creds_get_pid(creds, &pid);
1814 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1817 } while (hashmap_get(m->inhibitors, id));
1819 r = manager_add_inhibitor(m, id, &i);
1827 i->why = strdup(why);
1828 i->who = strdup(who);
1830 if (!i->why || !i->who) {
1835 fifo_fd = inhibitor_create_fifo(i);
1843 return sd_bus_reply_method_return(message, "h", fifo_fd);
1852 const sd_bus_vtable manager_vtable[] = {
1853 SD_BUS_VTABLE_START(0),
1855 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1856 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1857 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1858 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1859 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1860 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1861 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1862 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1863 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1864 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1865 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1866 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1867 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1868 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1869 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1870 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1871 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1872 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1874 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1875 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1876 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1877 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1878 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1879 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1880 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1881 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1882 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1883 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1884 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1885 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1887 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1888 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1889 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1890 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1891 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1892 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1893 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1894 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1895 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1896 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1897 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1899 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1900 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1901 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1902 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1903 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1904 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1905 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1906 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1907 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1908 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1909 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1911 SD_BUS_SIGNAL("SessionNew", "so", 0),
1912 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1913 SD_BUS_SIGNAL("UserNew", "uo", 0),
1914 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1915 SD_BUS_SIGNAL("SeatNew", "so", 0),
1916 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1917 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1918 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1923 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1932 if (streq(result, "done"))
1933 r = session_send_create_reply(s, NULL);
1935 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1937 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1938 r = session_send_create_reply(s, &e);
1944 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1945 const char *path, *result, *unit;
1946 Manager *m = userdata;
1956 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1958 bus_log_parse_error(r);
1962 if (m->action_job && streq(m->action_job, path)) {
1963 log_info("Operation finished.");
1965 /* Tell people that they now may take a lock again */
1966 send_prepare_for(m, m->action_what, false);
1968 free(m->action_job);
1969 m->action_job = NULL;
1970 m->action_unit = NULL;
1975 session = hashmap_get(m->session_units, unit);
1978 if (streq_ptr(path, session->scope_job)) {
1979 free(session->scope_job);
1980 session->scope_job = NULL;
1983 session_jobs_reply(session, unit, result);
1985 session_save(session);
1986 session_add_to_gc_queue(session);
1989 user = hashmap_get(m->user_units, unit);
1992 if (streq_ptr(path, user->service_job)) {
1993 free(user->service_job);
1994 user->service_job = NULL;
1997 if (streq_ptr(path, user->slice_job)) {
1998 free(user->slice_job);
1999 user->slice_job = NULL;
2002 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2003 session_jobs_reply(session, unit, result);
2007 user_add_to_gc_queue(user);
2013 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2014 const char *path, *unit;
2015 Manager *m = userdata;
2024 r = sd_bus_message_read(message, "so", &unit, &path);
2026 bus_log_parse_error(r);
2030 session = hashmap_get(m->session_units, unit);
2032 session_add_to_gc_queue(session);
2034 user = hashmap_get(m->user_units, unit);
2036 user_add_to_gc_queue(user);
2041 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2042 _cleanup_free_ char *unit = NULL;
2043 Manager *m = userdata;
2053 path = sd_bus_message_get_path(message);
2057 r = unit_name_from_dbus_path(path, &unit);
2059 /* quietly ignore non-units paths */
2060 return r == -EINVAL ? 0 : r;
2062 session = hashmap_get(m->session_units, unit);
2064 session_add_to_gc_queue(session);
2066 user = hashmap_get(m->user_units, unit);
2068 user_add_to_gc_queue(user);
2073 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2074 Manager *m = userdata;
2081 r = sd_bus_message_read(message, "b", &b);
2083 bus_log_parse_error(r);
2090 /* systemd finished reloading, let's recheck all our sessions */
2091 log_debug("System manager has been reloaded, rechecking sessions...");
2093 HASHMAP_FOREACH(session, m->sessions, i)
2094 session_add_to_gc_queue(session);
2099 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2100 const char *name, *old, *new;
2101 Manager *m = userdata;
2109 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2111 bus_log_parse_error(r);
2115 if (isempty(old) || !isempty(new))
2118 key = set_remove(m->busnames, (char*) old);
2122 /* Drop all controllers owned by this name */
2126 HASHMAP_FOREACH(session, m->sessions, i)
2127 if (session_is_controller(session, old))
2128 session_drop_controller(session);
2133 int manager_send_changed(Manager *manager, const char *property, ...) {
2138 l = strv_from_stdarg_alloca(property);
2140 return sd_bus_emit_properties_changed_strv(
2142 "/org/freedesktop/login1",
2143 "org.freedesktop.login1.Manager",
2147 int manager_dispatch_delayed(Manager *manager) {
2148 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2149 Inhibitor *offending = NULL;
2154 if (manager->action_what == 0 || manager->action_job)
2157 /* Continue delay? */
2158 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2159 _cleanup_free_ char *comm = NULL, *u = NULL;
2161 get_process_comm(offending->pid, &comm);
2162 u = uid_to_name(offending->uid);
2164 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2167 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2168 (unsigned long) offending->uid, strna(u),
2169 (unsigned long) offending->pid, strna(comm));
2172 /* Actually do the operation */
2173 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2175 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2177 manager->action_unit = NULL;
2178 manager->action_what = 0;
2185 int manager_start_scope(
2190 const char *description,
2191 const char *after, const char *after2,
2192 sd_bus_error *error,
2195 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2202 r = sd_bus_message_new_method_call(
2205 "org.freedesktop.systemd1",
2206 "/org/freedesktop/systemd1",
2207 "org.freedesktop.systemd1.Manager",
2208 "StartTransientUnit");
2212 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2216 r = sd_bus_message_open_container(m, 'a', "(sv)");
2220 if (!isempty(slice)) {
2221 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2226 if (!isempty(description)) {
2227 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2232 if (!isempty(after)) {
2233 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2238 if (!isempty(after2)) {
2239 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2244 /* cgroup empty notification is not available in containers
2245 * currently. To make this less problematic, let's shorten the
2246 * stop timeout for sessions, so that we don't wait
2249 /* Make sure that the session shells are terminated with
2250 * SIGHUP since bash and friends tend to ignore SIGTERM */
2251 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2255 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2259 r = sd_bus_message_close_container(m);
2263 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2267 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2275 r = sd_bus_message_read(reply, "o", &j);
2289 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2290 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2296 r = sd_bus_call_method(
2298 "org.freedesktop.systemd1",
2299 "/org/freedesktop/systemd1",
2300 "org.freedesktop.systemd1.Manager",
2304 "ss", unit, "fail");
2312 r = sd_bus_message_read(reply, "o", &j);
2326 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2327 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2333 r = sd_bus_call_method(
2335 "org.freedesktop.systemd1",
2336 "/org/freedesktop/systemd1",
2337 "org.freedesktop.systemd1.Manager",
2341 "ss", unit, "fail");
2343 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2344 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2349 sd_bus_error_free(error);
2360 r = sd_bus_message_read(reply, "o", &j);
2374 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2375 _cleanup_free_ char *path = NULL;
2381 path = unit_dbus_path_from_name(scope);
2385 r = sd_bus_call_method(
2387 "org.freedesktop.systemd1",
2389 "org.freedesktop.systemd1.Scope",
2395 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2396 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2397 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2398 sd_bus_error_free(error);
2408 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2412 return sd_bus_call_method(
2414 "org.freedesktop.systemd1",
2415 "/org/freedesktop/systemd1",
2416 "org.freedesktop.systemd1.Manager",
2420 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2423 int manager_unit_is_active(Manager *manager, const char *unit) {
2424 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2425 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2426 _cleanup_free_ char *path = NULL;
2433 path = unit_dbus_path_from_name(unit);
2437 r = sd_bus_get_property(
2439 "org.freedesktop.systemd1",
2441 "org.freedesktop.systemd1.Unit",
2447 /* systemd might have droppped off momentarily, let's
2448 * not make this an error */
2449 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2450 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2453 /* If the unit is already unloaded then it's not
2455 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2456 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2462 r = sd_bus_message_read(reply, "s", &state);
2466 return !streq(state, "inactive") && !streq(state, "failed");
2469 int manager_job_is_active(Manager *manager, const char *path) {
2470 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2471 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2477 r = sd_bus_get_property(
2479 "org.freedesktop.systemd1",
2481 "org.freedesktop.systemd1.Job",
2487 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2488 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2491 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2497 /* We don't actually care about the state really. The fact
2498 * that we could read the job state is enough for us */