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);
1486 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1487 action_ignore_inhibit, interactive, error, method, m);
1492 if (!multiple_sessions && !blocked) {
1493 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1494 action, interactive, error, method, m);
1499 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1503 return sd_bus_reply_method_return(message, NULL);
1506 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1507 Manager *m = userdata;
1509 return method_do_shutdown_or_sleep(
1511 SPECIAL_POWEROFF_TARGET,
1513 "org.freedesktop.login1.power-off",
1514 "org.freedesktop.login1.power-off-multiple-sessions",
1515 "org.freedesktop.login1.power-off-ignore-inhibit",
1521 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1522 Manager *m = userdata;
1524 return method_do_shutdown_or_sleep(
1526 SPECIAL_REBOOT_TARGET,
1528 "org.freedesktop.login1.reboot",
1529 "org.freedesktop.login1.reboot-multiple-sessions",
1530 "org.freedesktop.login1.reboot-ignore-inhibit",
1536 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1537 Manager *m = userdata;
1539 return method_do_shutdown_or_sleep(
1541 SPECIAL_SUSPEND_TARGET,
1543 "org.freedesktop.login1.suspend",
1544 "org.freedesktop.login1.suspend-multiple-sessions",
1545 "org.freedesktop.login1.suspend-ignore-inhibit",
1551 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1552 Manager *m = userdata;
1554 return method_do_shutdown_or_sleep(
1556 SPECIAL_HIBERNATE_TARGET,
1558 "org.freedesktop.login1.hibernate",
1559 "org.freedesktop.login1.hibernate-multiple-sessions",
1560 "org.freedesktop.login1.hibernate-ignore-inhibit",
1566 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1567 Manager *m = userdata;
1569 return method_do_shutdown_or_sleep(
1571 SPECIAL_HYBRID_SLEEP_TARGET,
1573 "org.freedesktop.login1.hibernate",
1574 "org.freedesktop.login1.hibernate-multiple-sessions",
1575 "org.freedesktop.login1.hibernate-ignore-inhibit",
1577 method_hybrid_sleep,
1581 static int method_can_shutdown_or_sleep(
1583 sd_bus_message *message,
1586 const char *action_multiple_sessions,
1587 const char *action_ignore_inhibit,
1588 const char *sleep_verb,
1589 sd_bus_error *error) {
1591 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1592 bool multiple_sessions, challenge, blocked;
1593 const char *result = NULL;
1600 assert(w <= _INHIBIT_WHAT_MAX);
1602 assert(action_multiple_sessions);
1603 assert(action_ignore_inhibit);
1606 r = can_sleep(sleep_verb);
1610 return sd_bus_reply_method_return(message, "s", "na");
1613 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1617 r = sd_bus_creds_get_uid(creds, &uid);
1621 r = have_multiple_sessions(m, uid);
1625 multiple_sessions = r > 0;
1626 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1628 if (multiple_sessions) {
1629 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1636 result = "challenge";
1642 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1646 if (r > 0 && !result)
1648 else if (challenge && (!result || streq(result, "yes")))
1649 result = "challenge";
1654 if (!multiple_sessions && !blocked) {
1655 /* If neither inhibit nor multiple sessions
1656 * apply then just check the normal policy */
1658 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1665 result = "challenge";
1670 return sd_bus_reply_method_return(message, "s", result);
1673 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1674 Manager *m = userdata;
1676 return method_can_shutdown_or_sleep(
1679 "org.freedesktop.login1.power-off",
1680 "org.freedesktop.login1.power-off-multiple-sessions",
1681 "org.freedesktop.login1.power-off-ignore-inhibit",
1686 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1687 Manager *m = userdata;
1689 return method_can_shutdown_or_sleep(
1692 "org.freedesktop.login1.reboot",
1693 "org.freedesktop.login1.reboot-multiple-sessions",
1694 "org.freedesktop.login1.reboot-ignore-inhibit",
1699 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1700 Manager *m = userdata;
1702 return method_can_shutdown_or_sleep(
1705 "org.freedesktop.login1.suspend",
1706 "org.freedesktop.login1.suspend-multiple-sessions",
1707 "org.freedesktop.login1.suspend-ignore-inhibit",
1712 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1713 Manager *m = userdata;
1715 return method_can_shutdown_or_sleep(
1718 "org.freedesktop.login1.hibernate",
1719 "org.freedesktop.login1.hibernate-multiple-sessions",
1720 "org.freedesktop.login1.hibernate-ignore-inhibit",
1725 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1726 Manager *m = userdata;
1728 return method_can_shutdown_or_sleep(
1731 "org.freedesktop.login1.hibernate",
1732 "org.freedesktop.login1.hibernate-multiple-sessions",
1733 "org.freedesktop.login1.hibernate-ignore-inhibit",
1738 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1739 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1740 const char *who, *why, *what, *mode;
1741 _cleanup_free_ char *id = NULL;
1742 _cleanup_close_ int fifo_fd = -1;
1743 Manager *m = userdata;
1744 Inhibitor *i = NULL;
1755 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1759 w = inhibit_what_from_string(what);
1761 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1763 mm = inhibit_mode_from_string(mode);
1765 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1767 /* Delay is only supported for shutdown/sleep */
1768 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1769 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1771 /* Don't allow taking delay locks while we are already
1772 * executing the operation. We shouldn't create the impression
1773 * that the lock was successful if the machine is about to go
1774 * down/suspend any moment. */
1775 if (m->action_what & w)
1776 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1778 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1779 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1780 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1781 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1782 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1783 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1784 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1785 "org.freedesktop.login1.inhibit-handle-lid-switch",
1786 false, error, method_inhibit, m);
1790 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1792 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1796 r = sd_bus_creds_get_uid(creds, &uid);
1800 r = sd_bus_creds_get_pid(creds, &pid);
1808 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1811 } while (hashmap_get(m->inhibitors, id));
1813 r = manager_add_inhibitor(m, id, &i);
1821 i->why = strdup(why);
1822 i->who = strdup(who);
1824 if (!i->why || !i->who) {
1829 fifo_fd = inhibitor_create_fifo(i);
1837 return sd_bus_reply_method_return(message, "h", fifo_fd);
1846 const sd_bus_vtable manager_vtable[] = {
1847 SD_BUS_VTABLE_START(0),
1849 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1850 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1851 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1852 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1853 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1854 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1855 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1856 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1857 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1858 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1859 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1860 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1861 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1862 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1863 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1864 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1865 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1866 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1868 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1869 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1870 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1871 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1872 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1873 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1874 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1875 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1876 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1877 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1878 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1879 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1880 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1881 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1882 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1883 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1884 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1885 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1886 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1887 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1888 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1889 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1890 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1893 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1894 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1895 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1896 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1897 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1899 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1900 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1901 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1902 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1903 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1905 SD_BUS_SIGNAL("SessionNew", "so", 0),
1906 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1907 SD_BUS_SIGNAL("UserNew", "uo", 0),
1908 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1909 SD_BUS_SIGNAL("SeatNew", "so", 0),
1910 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1911 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1912 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1917 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1926 if (streq(result, "done"))
1927 r = session_send_create_reply(s, NULL);
1929 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1931 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1932 r = session_send_create_reply(s, &e);
1938 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1939 const char *path, *result, *unit;
1940 Manager *m = userdata;
1950 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1952 bus_log_parse_error(r);
1956 if (m->action_job && streq(m->action_job, path)) {
1957 log_info("Operation finished.");
1959 /* Tell people that they now may take a lock again */
1960 send_prepare_for(m, m->action_what, false);
1962 free(m->action_job);
1963 m->action_job = NULL;
1964 m->action_unit = NULL;
1969 session = hashmap_get(m->session_units, unit);
1972 if (streq_ptr(path, session->scope_job)) {
1973 free(session->scope_job);
1974 session->scope_job = NULL;
1977 session_jobs_reply(session, unit, result);
1979 session_save(session);
1980 session_add_to_gc_queue(session);
1983 user = hashmap_get(m->user_units, unit);
1986 if (streq_ptr(path, user->service_job)) {
1987 free(user->service_job);
1988 user->service_job = NULL;
1991 if (streq_ptr(path, user->slice_job)) {
1992 free(user->slice_job);
1993 user->slice_job = NULL;
1996 LIST_FOREACH(sessions_by_user, session, user->sessions) {
1997 session_jobs_reply(session, unit, result);
2001 user_add_to_gc_queue(user);
2007 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2008 const char *path, *unit;
2009 Manager *m = userdata;
2018 r = sd_bus_message_read(message, "so", &unit, &path);
2020 bus_log_parse_error(r);
2024 session = hashmap_get(m->session_units, unit);
2026 session_add_to_gc_queue(session);
2028 user = hashmap_get(m->user_units, unit);
2030 user_add_to_gc_queue(user);
2035 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2036 _cleanup_free_ char *unit = NULL;
2037 Manager *m = userdata;
2047 path = sd_bus_message_get_path(message);
2051 r = unit_name_from_dbus_path(path, &unit);
2053 /* quietly ignore non-units paths */
2054 return r == -EINVAL ? 0 : r;
2056 session = hashmap_get(m->session_units, unit);
2058 session_add_to_gc_queue(session);
2060 user = hashmap_get(m->user_units, unit);
2062 user_add_to_gc_queue(user);
2067 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2068 Manager *m = userdata;
2075 r = sd_bus_message_read(message, "b", &b);
2077 bus_log_parse_error(r);
2084 /* systemd finished reloading, let's recheck all our sessions */
2085 log_debug("System manager has been reloaded, rechecking sessions...");
2087 HASHMAP_FOREACH(session, m->sessions, i)
2088 session_add_to_gc_queue(session);
2093 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2094 const char *name, *old, *new;
2095 Manager *m = userdata;
2103 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2105 bus_log_parse_error(r);
2109 if (isempty(old) || !isempty(new))
2112 key = set_remove(m->busnames, (char*) old);
2116 /* Drop all controllers owned by this name */
2120 HASHMAP_FOREACH(session, m->sessions, i)
2121 if (session_is_controller(session, old))
2122 session_drop_controller(session);
2127 int manager_send_changed(Manager *manager, const char *property, ...) {
2132 l = strv_from_stdarg_alloca(property);
2134 return sd_bus_emit_properties_changed_strv(
2136 "/org/freedesktop/login1",
2137 "org.freedesktop.login1.Manager",
2141 int manager_dispatch_delayed(Manager *manager) {
2142 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2143 Inhibitor *offending = NULL;
2148 if (manager->action_what == 0 || manager->action_job)
2151 /* Continue delay? */
2152 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2153 _cleanup_free_ char *comm = NULL, *u = NULL;
2155 get_process_comm(offending->pid, &comm);
2156 u = uid_to_name(offending->uid);
2158 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2161 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2162 (unsigned long) offending->uid, strna(u),
2163 (unsigned long) offending->pid, strna(comm));
2166 /* Actually do the operation */
2167 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2169 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2171 manager->action_unit = NULL;
2172 manager->action_what = 0;
2179 int manager_start_scope(
2184 const char *description,
2185 const char *after, const char *after2,
2186 sd_bus_error *error,
2189 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2196 r = sd_bus_message_new_method_call(
2199 "org.freedesktop.systemd1",
2200 "/org/freedesktop/systemd1",
2201 "org.freedesktop.systemd1.Manager",
2202 "StartTransientUnit");
2206 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2210 r = sd_bus_message_open_container(m, 'a', "(sv)");
2214 if (!isempty(slice)) {
2215 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2220 if (!isempty(description)) {
2221 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2226 if (!isempty(after)) {
2227 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2232 if (!isempty(after2)) {
2233 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2238 /* cgroup empty notification is not available in containers
2239 * currently. To make this less problematic, let's shorten the
2240 * stop timeout for sessions, so that we don't wait
2243 /* Make sure that the session shells are terminated with
2244 * SIGHUP since bash and friends tend to ignore SIGTERM */
2245 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2249 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2253 r = sd_bus_message_close_container(m);
2257 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2261 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2269 r = sd_bus_message_read(reply, "o", &j);
2283 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2284 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2290 r = sd_bus_call_method(
2292 "org.freedesktop.systemd1",
2293 "/org/freedesktop/systemd1",
2294 "org.freedesktop.systemd1.Manager",
2298 "ss", unit, "fail");
2306 r = sd_bus_message_read(reply, "o", &j);
2320 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2321 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2327 r = sd_bus_call_method(
2329 "org.freedesktop.systemd1",
2330 "/org/freedesktop/systemd1",
2331 "org.freedesktop.systemd1.Manager",
2335 "ss", unit, "fail");
2337 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2338 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2343 sd_bus_error_free(error);
2354 r = sd_bus_message_read(reply, "o", &j);
2368 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2369 _cleanup_free_ char *path = NULL;
2375 path = unit_dbus_path_from_name(scope);
2379 r = sd_bus_call_method(
2381 "org.freedesktop.systemd1",
2383 "org.freedesktop.systemd1.Scope",
2389 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2390 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2391 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2392 sd_bus_error_free(error);
2402 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2406 return sd_bus_call_method(
2408 "org.freedesktop.systemd1",
2409 "/org/freedesktop/systemd1",
2410 "org.freedesktop.systemd1.Manager",
2414 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2417 int manager_unit_is_active(Manager *manager, const char *unit) {
2418 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2419 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2420 _cleanup_free_ char *path = NULL;
2427 path = unit_dbus_path_from_name(unit);
2431 r = sd_bus_get_property(
2433 "org.freedesktop.systemd1",
2435 "org.freedesktop.systemd1.Unit",
2441 /* systemd might have droppped off momentarily, let's
2442 * not make this an error */
2443 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2444 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2447 /* If the unit is already unloaded then it's not
2449 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2450 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2456 r = sd_bus_message_read(reply, "s", &state);
2460 return !streq(state, "inactive") && !streq(state, "failed");
2463 int manager_job_is_active(Manager *manager, const char *path) {
2464 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2465 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2471 r = sd_bus_get_property(
2473 "org.freedesktop.systemd1",
2475 "org.freedesktop.systemd1.Job",
2481 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2482 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2485 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2491 /* We don't actually care about the state really. The fact
2492 * that we could read the job state is enough for us */