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/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
46 #include "utmp-wtmp.h"
48 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
49 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
58 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
62 r = sd_bus_creds_get_session(creds, &name);
67 session = hashmap_get(m->sessions, name);
69 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
83 if (uid == UID_INVALID) {
84 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
86 /* Note that we get the owner UID of the session, not the actual client UID here! */
87 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
91 r = sd_bus_creds_get_owner_uid(creds, &uid);
96 user = hashmap_get(m->users, UID_TO_PTR(uid));
98 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
115 r = manager_get_session_from_creds(m, message, NULL, error, &session);
119 seat = session->seat;
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
124 seat = hashmap_get(m->seats, name);
126 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
133 static int property_get_idle_hint(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
142 Manager *m = userdata;
148 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
151 static int property_get_idle_since_hint(
154 const char *interface,
155 const char *property,
156 sd_bus_message *reply,
158 sd_bus_error *error) {
160 Manager *m = userdata;
167 manager_get_idle_hint(m, &t);
169 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
172 static int property_get_inhibited(
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
179 sd_bus_error *error) {
181 Manager *m = userdata;
188 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
190 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
193 static int property_get_preparing(
196 const char *interface,
197 const char *property,
198 sd_bus_message *reply,
200 sd_bus_error *error) {
202 Manager *m = userdata;
209 if (streq(property, "PreparingForShutdown"))
210 b = !!(m->action_what & INHIBIT_SHUTDOWN);
212 b = !!(m->action_what & INHIBIT_SLEEP);
214 return sd_bus_message_append(reply, "b", b);
217 static int property_get_scheduled_shutdown(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 Manager *m = userdata;
233 r = sd_bus_message_open_container(reply, 'r', "st");
237 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
241 return sd_bus_message_close_container(reply);
244 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
246 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
247 _cleanup_free_ char *p = NULL;
248 Manager *m = userdata;
256 r = sd_bus_message_read(message, "s", &name);
260 r = manager_get_session_from_creds(m, message, name, error, &session);
264 p = session_bus_path(session);
268 return sd_bus_reply_method_return(message, "o", p);
271 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
272 _cleanup_free_ char *p = NULL;
273 Session *session = NULL;
274 Manager *m = userdata;
281 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
283 r = sd_bus_message_read(message, "u", &pid);
288 r = manager_get_session_from_creds(m, message, NULL, error, &session);
292 r = manager_get_session_by_pid(m, pid, &session);
297 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
300 p = session_bus_path(session);
304 return sd_bus_reply_method_return(message, "o", p);
307 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
308 _cleanup_free_ char *p = NULL;
309 Manager *m = userdata;
317 r = sd_bus_message_read(message, "u", &uid);
321 r = manager_get_user_from_creds(m, message, uid, error, &user);
325 p = user_bus_path(user);
329 return sd_bus_reply_method_return(message, "o", p);
332 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
333 _cleanup_free_ char *p = NULL;
334 Manager *m = userdata;
342 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
344 r = sd_bus_message_read(message, "u", &pid);
349 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
353 r = manager_get_user_by_pid(m, pid, &user);
357 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
360 p = user_bus_path(user);
364 return sd_bus_reply_method_return(message, "o", p);
367 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
368 _cleanup_free_ char *p = NULL;
369 Manager *m = userdata;
377 r = sd_bus_message_read(message, "s", &name);
381 r = manager_get_seat_from_creds(m, message, name, error, &seat);
385 p = seat_bus_path(seat);
389 return sd_bus_reply_method_return(message, "o", p);
392 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
394 Manager *m = userdata;
402 r = sd_bus_message_new_method_return(message, &reply);
406 r = sd_bus_message_open_container(reply, 'a', "(susso)");
410 HASHMAP_FOREACH(session, m->sessions, i) {
411 _cleanup_free_ char *p = NULL;
413 p = session_bus_path(session);
417 r = sd_bus_message_append(reply, "(susso)",
419 (uint32_t) session->user->uid,
421 session->seat ? session->seat->id : "",
427 r = sd_bus_message_close_container(reply);
431 return sd_bus_send(NULL, reply, NULL);
434 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
435 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
436 Manager *m = userdata;
444 r = sd_bus_message_new_method_return(message, &reply);
448 r = sd_bus_message_open_container(reply, 'a', "(uso)");
452 HASHMAP_FOREACH(user, m->users, i) {
453 _cleanup_free_ char *p = NULL;
455 p = user_bus_path(user);
459 r = sd_bus_message_append(reply, "(uso)",
460 (uint32_t) user->uid,
467 r = sd_bus_message_close_container(reply);
471 return sd_bus_send(NULL, reply, NULL);
474 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
475 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
476 Manager *m = userdata;
484 r = sd_bus_message_new_method_return(message, &reply);
488 r = sd_bus_message_open_container(reply, 'a', "(so)");
492 HASHMAP_FOREACH(seat, m->seats, i) {
493 _cleanup_free_ char *p = NULL;
495 p = seat_bus_path(seat);
499 r = sd_bus_message_append(reply, "(so)", seat->id, p);
504 r = sd_bus_message_close_container(reply);
508 return sd_bus_send(NULL, reply, NULL);
511 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
513 Manager *m = userdata;
514 Inhibitor *inhibitor;
521 r = sd_bus_message_new_method_return(message, &reply);
525 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
529 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
531 r = sd_bus_message_append(reply, "(ssssuu)",
532 strempty(inhibit_what_to_string(inhibitor->what)),
533 strempty(inhibitor->who),
534 strempty(inhibitor->why),
535 strempty(inhibit_mode_to_string(inhibitor->mode)),
536 (uint32_t) inhibitor->uid,
537 (uint32_t) inhibitor->pid);
542 r = sd_bus_message_close_container(reply);
546 return sd_bus_send(NULL, reply, NULL);
549 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
550 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
551 uint32_t uid, leader, audit_id = 0;
552 _cleanup_free_ char *id = NULL;
553 Session *session = NULL;
554 Manager *m = userdata;
566 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
571 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
574 t = _SESSION_TYPE_INVALID;
576 t = session_type_from_string(type);
578 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
582 c = _SESSION_CLASS_INVALID;
584 c = session_class_from_string(class);
586 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
589 if (isempty(desktop))
592 if (!string_is_safe(desktop))
593 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
599 seat = hashmap_get(m->seats, cseat);
601 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
604 if (tty_is_vc(tty)) {
609 else if (seat != m->seat0)
610 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);
612 v = vtnr_from_tty(tty);
614 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
618 else if (vtnr != (uint32_t) v)
619 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
621 } else if (tty_is_console(tty)) {
625 else if (seat != m->seat0)
626 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
629 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
633 if (seat_has_vts(seat)) {
634 if (!vtnr || vtnr > 63)
635 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
638 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
642 r = sd_bus_message_enter_container(message, 'a', "(sv)");
646 if (t == _SESSION_TYPE_INVALID) {
647 if (!isempty(display))
649 else if (!isempty(tty))
652 t = SESSION_UNSPECIFIED;
655 if (c == _SESSION_CLASS_INVALID) {
656 if (t == SESSION_UNSPECIFIED)
657 c = SESSION_BACKGROUND;
663 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
665 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
669 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
674 manager_get_session_by_pid(m, leader, &session);
676 _cleanup_free_ char *path = NULL;
677 _cleanup_close_ int fifo_fd = -1;
679 /* Session already exists, client is probably
680 * something like "su" which changes uid but is still
681 * the same session */
683 fifo_fd = session_create_fifo(session);
687 path = session_bus_path(session);
691 log_debug("Sending reply about an existing session: "
692 "id=%s object_path=%s uid=%u runtime_path=%s "
693 "session_fd=%d seat=%s vtnr=%u",
696 (uint32_t) session->user->uid,
697 session->user->runtime_path,
699 session->seat ? session->seat->id : "",
700 (uint32_t) session->vtnr);
702 return sd_bus_reply_method_return(
706 session->user->runtime_path,
708 (uint32_t) session->user->uid,
709 session->seat ? session->seat->id : "",
710 (uint32_t) session->vtnr,
714 audit_session_from_pid(leader, &audit_id);
716 /* Keep our session IDs and the audit session IDs in sync */
718 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
721 /* Wut? There's already a session by this name and we
722 * didn't find it above? Weird, then let's not trust
723 * the audit data and let's better register a new
725 if (hashmap_get(m->sessions, id)) {
726 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
739 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
742 } while (hashmap_get(m->sessions, id));
745 r = manager_add_user_by_uid(m, uid, &user);
749 r = manager_add_session(m, id, &session);
753 session_set_user(session, user);
755 session->leader = leader;
756 session->audit_id = audit_id;
759 session->remote = remote;
760 session->vtnr = vtnr;
763 session->tty = strdup(tty);
770 if (!isempty(display)) {
771 session->display = strdup(display);
772 if (!session->display) {
778 if (!isempty(remote_user)) {
779 session->remote_user = strdup(remote_user);
780 if (!session->remote_user) {
786 if (!isempty(remote_host)) {
787 session->remote_host = strdup(remote_host);
788 if (!session->remote_host) {
794 if (!isempty(service)) {
795 session->service = strdup(service);
796 if (!session->service) {
802 if (!isempty(desktop)) {
803 session->desktop = strdup(desktop);
804 if (!session->desktop) {
811 r = seat_attach_session(seat, session);
816 r = session_start(session);
820 session->create_message = sd_bus_message_ref(message);
822 /* Now, let's wait until the slice unit and stuff got
823 * created. We send the reply back from
824 * session_send_create_reply(). */
830 session_add_to_gc_queue(session);
833 user_add_to_gc_queue(user);
838 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
839 Manager *m = userdata;
847 r = sd_bus_message_read(message, "s", &name);
851 r = manager_get_session_from_creds(m, message, name, error, &session);
855 r = session_release(session);
859 return sd_bus_reply_method_return(message, NULL);
862 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
863 Manager *m = userdata;
871 r = sd_bus_message_read(message, "s", &name);
875 r = manager_get_session_from_creds(m, message, name, error, &session);
879 return bus_session_method_activate(message, session, error);
882 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
883 const char *session_name, *seat_name;
884 Manager *m = userdata;
892 /* Same as ActivateSession() but refuses to work if
893 * the seat doesn't match */
895 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
899 r = manager_get_session_from_creds(m, message, session_name, error, &session);
903 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
907 if (session->seat != seat)
908 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
910 r = session_activate(session);
914 return sd_bus_reply_method_return(message, NULL);
917 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
918 Manager *m = userdata;
926 r = sd_bus_message_read(message, "s", &name);
930 r = manager_get_session_from_creds(m, message, name, error, &session);
934 return bus_session_method_lock(message, session, error);
937 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
938 Manager *m = userdata;
944 r = bus_verify_polkit_async(
947 "org.freedesktop.login1.lock-sessions",
955 return 1; /* Will call us back */
957 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
961 return sd_bus_reply_method_return(message, NULL);
964 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
966 Manager *m = userdata;
973 r = sd_bus_message_read(message, "s", &name);
977 r = manager_get_session_from_creds(m, message, name, error, &session);
981 return bus_session_method_kill(message, session, error);
984 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
985 Manager *m = userdata;
993 r = sd_bus_message_read(message, "u", &uid);
997 r = manager_get_user_from_creds(m, message, uid, error, &user);
1001 return bus_user_method_kill(message, user, error);
1004 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1005 Manager *m = userdata;
1013 r = sd_bus_message_read(message, "s", &name);
1017 r = manager_get_session_from_creds(m, message, name, error, &session);
1021 return bus_session_method_terminate(message, session, error);
1024 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1025 Manager *m = userdata;
1033 r = sd_bus_message_read(message, "u", &uid);
1037 r = manager_get_user_from_creds(m, message, uid, error, &user);
1041 return bus_user_method_terminate(message, user, error);
1044 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1045 Manager *m = userdata;
1053 r = sd_bus_message_read(message, "s", &name);
1057 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1061 return bus_seat_method_terminate(message, seat, error);
1064 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1065 _cleanup_free_ char *cc = NULL;
1066 Manager *m = userdata;
1076 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1080 if (uid == UID_INVALID) {
1081 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1083 /* Note that we get the owner UID of the session, not the actual client UID here! */
1084 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1088 r = sd_bus_creds_get_owner_uid(creds, &uid);
1096 return errno ? -errno : -ENOENT;
1098 r = bus_verify_polkit_async(
1101 "org.freedesktop.login1.set-user-linger",
1104 &m->polkit_registry,
1109 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1111 mkdir_p_label("/var/lib/systemd", 0755);
1113 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1117 cc = cescape(pw->pw_name);
1121 path = strjoina("/var/lib/systemd/linger/", cc);
1129 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1136 if (r < 0 && errno != ENOENT)
1139 u = hashmap_get(m->users, UID_TO_PTR(uid));
1141 user_add_to_gc_queue(u);
1144 return sd_bus_reply_method_return(message, NULL);
1147 static int trigger_device(Manager *m, struct udev_device *d) {
1148 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1149 struct udev_list_entry *first, *item;
1154 e = udev_enumerate_new(m->udev);
1159 r = udev_enumerate_add_match_parent(e, d);
1164 r = udev_enumerate_scan_devices(e);
1168 first = udev_enumerate_get_list_entry(e);
1169 udev_list_entry_foreach(item, first) {
1170 _cleanup_free_ char *t = NULL;
1173 p = udev_list_entry_get_name(item);
1175 t = strappend(p, "/uevent");
1179 write_string_file(t, "change");
1185 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1186 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1187 _cleanup_free_ char *rule = NULL, *file = NULL;
1188 const char *id_for_seat;
1195 d = udev_device_new_from_syspath(m->udev, sysfs);
1199 if (!udev_device_has_tag(d, "seat"))
1202 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1206 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1209 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1212 mkdir_p_label("/etc/udev/rules.d", 0755);
1213 mac_selinux_init("/etc");
1214 r = write_string_file_atomic_label(file, rule);
1218 return trigger_device(m, d);
1221 static int flush_devices(Manager *m) {
1222 _cleanup_closedir_ DIR *d;
1226 d = opendir("/etc/udev/rules.d");
1228 if (errno != ENOENT)
1229 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1233 while ((de = readdir(d))) {
1235 if (!dirent_is_file(de))
1238 if (!startswith(de->d_name, "72-seat-"))
1241 if (!endswith(de->d_name, ".rules"))
1244 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1245 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1249 return trigger_device(m, NULL);
1252 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1253 const char *sysfs, *seat;
1254 Manager *m = userdata;
1260 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1264 if (!path_startswith(sysfs, "/sys"))
1265 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1267 if (!seat_name_is_valid(seat))
1268 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1270 r = bus_verify_polkit_async(
1273 "org.freedesktop.login1.attach-device",
1276 &m->polkit_registry,
1281 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1283 r = attach_device(m, seat, sysfs);
1287 return sd_bus_reply_method_return(message, NULL);
1290 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1291 Manager *m = userdata;
1297 r = sd_bus_message_read(message, "b", &interactive);
1301 r = bus_verify_polkit_async(
1304 "org.freedesktop.login1.flush-devices",
1307 &m->polkit_registry,
1312 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1314 r = flush_devices(m);
1318 return sd_bus_reply_method_return(message, NULL);
1321 static int have_multiple_sessions(
1330 /* Check for other users' sessions. Greeter sessions do not
1331 * count, and non-login sessions do not count either. */
1332 HASHMAP_FOREACH(session, m->sessions, i)
1333 if (session->class == SESSION_USER &&
1334 session->user->uid != uid)
1340 static int bus_manager_log_shutdown(
1343 const char *unit_name) {
1350 if (w != INHIBIT_SHUTDOWN)
1353 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1354 p = "MESSAGE=System is powering down.";
1355 q = "SHUTDOWN=power-off";
1356 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1357 p = "MESSAGE=System is halting.";
1358 q = "SHUTDOWN=halt";
1359 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1360 p = "MESSAGE=System is rebooting.";
1361 q = "SHUTDOWN=reboot";
1362 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1363 p = "MESSAGE=System is rebooting with kexec.";
1364 q = "SHUTDOWN=kexec";
1366 p = "MESSAGE=System is shutting down.";
1370 return log_struct(LOG_NOTICE,
1371 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1377 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1378 Manager *m = userdata;
1383 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1387 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1392 if (until <= now(CLOCK_MONOTONIC))
1395 /* We want to ignore the lid switch for a while after each
1396 * suspend, and after boot-up. Hence let's install a timer for
1397 * this. As long as the event source exists we ignore the lid
1400 if (m->lid_switch_ignore_event_source) {
1403 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1410 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1412 r = sd_event_add_time(
1414 &m->lid_switch_ignore_event_source,
1417 lid_switch_ignore_handler, m);
1422 static int execute_shutdown_or_sleep(
1425 const char *unit_name,
1426 sd_bus_error *error) {
1428 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1435 assert(w < _INHIBIT_WHAT_MAX);
1438 bus_manager_log_shutdown(m, w, unit_name);
1440 r = sd_bus_call_method(
1442 "org.freedesktop.systemd1",
1443 "/org/freedesktop/systemd1",
1444 "org.freedesktop.systemd1.Manager",
1448 "ss", unit_name, "replace-irreversibly");
1452 r = sd_bus_message_read(reply, "o", &p);
1460 m->action_unit = unit_name;
1461 free(m->action_job);
1465 /* Make sure the lid switch is ignored for a while */
1466 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1471 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1473 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1474 Inhibitor *offending = NULL;
1479 if (manager->action_what == 0 || manager->action_job)
1482 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1483 _cleanup_free_ char *comm = NULL, *u = NULL;
1488 (void) get_process_comm(offending->pid, &comm);
1489 u = uid_to_name(offending->uid);
1491 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1492 offending->uid, strna(u),
1493 offending->pid, strna(comm));
1496 /* Actually do the operation */
1497 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1499 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1501 manager->action_unit = NULL;
1502 manager->action_what = 0;
1509 static int manager_inhibit_timeout_handler(
1514 Manager *manager = userdata;
1518 assert(manager->inhibit_timeout_source == s);
1520 r = manager_dispatch_delayed(manager, true);
1521 return (r < 0) ? r : 0;
1524 static int delay_shutdown_or_sleep(
1527 const char *unit_name) {
1534 assert(w < _INHIBIT_WHAT_MAX);
1537 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1539 if (m->inhibit_timeout_source) {
1540 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1542 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1544 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1546 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1548 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1549 timeout_val, 0, manager_inhibit_timeout_handler, m);
1554 m->action_unit = unit_name;
1560 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1562 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1563 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1564 [INHIBIT_SLEEP] = "PrepareForSleep"
1567 int active = _active;
1571 assert(w < _INHIBIT_WHAT_MAX);
1572 assert(signal_name[w]);
1574 return sd_bus_emit_signal(m->bus,
1575 "/org/freedesktop/login1",
1576 "org.freedesktop.login1.Manager",
1582 int bus_manager_shutdown_or_sleep_now_or_later(
1584 const char *unit_name,
1586 sd_bus_error *error) {
1594 assert(w <= _INHIBIT_WHAT_MAX);
1595 assert(!m->action_job);
1597 /* Tell everybody to prepare for shutdown/sleep */
1598 send_prepare_for(m, w, true);
1601 m->inhibit_delay_max > 0 &&
1602 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1605 /* Shutdown is delayed, keep in mind what we
1606 * want to do, and start a timeout */
1607 r = delay_shutdown_or_sleep(m, w, unit_name);
1609 /* Shutdown is not delayed, execute it
1611 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1616 static int verify_shutdown_creds(
1618 sd_bus_message *message,
1622 const char *action_multiple_sessions,
1623 const char *action_ignore_inhibit,
1624 sd_bus_error *error) {
1626 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1627 bool multiple_sessions, blocked;
1634 assert(w <= _INHIBIT_WHAT_MAX);
1636 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1640 r = sd_bus_creds_get_euid(creds, &uid);
1644 r = have_multiple_sessions(m, uid);
1648 multiple_sessions = r > 0;
1649 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1651 if (multiple_sessions && action_multiple_sessions) {
1652 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1656 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1659 if (blocked && action_ignore_inhibit) {
1660 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1664 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1667 if (!multiple_sessions && !blocked && action) {
1668 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1672 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1678 static int method_do_shutdown_or_sleep(
1680 sd_bus_message *message,
1681 const char *unit_name,
1684 const char *action_multiple_sessions,
1685 const char *action_ignore_inhibit,
1686 const char *sleep_verb,
1687 sd_bus_error *error) {
1695 assert(w <= _INHIBIT_WHAT_MAX);
1697 r = sd_bus_message_read(message, "b", &interactive);
1701 /* Don't allow multiple jobs being executed at the same time */
1703 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1706 r = can_sleep(sleep_verb);
1711 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1714 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1715 action_ignore_inhibit, error);
1719 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1723 return sd_bus_reply_method_return(message, NULL);
1726 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727 Manager *m = userdata;
1729 return method_do_shutdown_or_sleep(
1731 SPECIAL_POWEROFF_TARGET,
1733 "org.freedesktop.login1.power-off",
1734 "org.freedesktop.login1.power-off-multiple-sessions",
1735 "org.freedesktop.login1.power-off-ignore-inhibit",
1740 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1741 Manager *m = userdata;
1743 return method_do_shutdown_or_sleep(
1745 SPECIAL_REBOOT_TARGET,
1747 "org.freedesktop.login1.reboot",
1748 "org.freedesktop.login1.reboot-multiple-sessions",
1749 "org.freedesktop.login1.reboot-ignore-inhibit",
1754 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1755 Manager *m = userdata;
1757 return method_do_shutdown_or_sleep(
1759 SPECIAL_SUSPEND_TARGET,
1761 "org.freedesktop.login1.suspend",
1762 "org.freedesktop.login1.suspend-multiple-sessions",
1763 "org.freedesktop.login1.suspend-ignore-inhibit",
1768 static int nologin_timeout_handler(
1773 Manager *m = userdata;
1776 log_info("Creating /run/nologin, blocking further logins...");
1778 r = write_string_file_atomic("/run/nologin", "System is going down.");
1780 log_error_errno(r, "Failed to create /run/nologin: %m");
1782 m->unlink_nologin = true;
1787 static int update_schedule_file(Manager *m) {
1790 _cleanup_fclose_ FILE *f = NULL;
1791 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1795 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1797 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1799 t = cescape(m->wall_message);
1803 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1805 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1807 (void) fchmod(fileno(f), 0644);
1813 m->scheduled_shutdown_timeout,
1814 m->enable_wall_messages,
1815 m->scheduled_shutdown_type);
1817 if (!isempty(m->wall_message))
1818 fprintf(f, "WALL_MESSAGE=%s\n", t);
1820 (void) fflush_and_check(f);
1822 if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1823 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1826 (void) unlink(temp_path);
1827 (void) unlink("/run/systemd/shutdown/scheduled");
1833 static int manager_scheduled_shutdown_handler(
1838 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1839 Manager *m = userdata;
1845 if (isempty(m->scheduled_shutdown_type))
1848 if (streq(m->scheduled_shutdown_type, "halt"))
1849 target = SPECIAL_HALT_TARGET;
1850 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1851 target = SPECIAL_POWEROFF_TARGET;
1853 target = SPECIAL_REBOOT_TARGET;
1855 r = execute_shutdown_or_sleep(m, 0, target, &error);
1857 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1862 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1863 Manager *m = userdata;
1864 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1865 const char *action_multiple_sessions = NULL;
1866 const char *action_ignore_inhibit = NULL;
1867 const char *action = NULL;
1875 r = sd_bus_message_read(message, "st", &type, &elapse);
1879 if (streq(type, "reboot")) {
1880 action = "org.freedesktop.login1.reboot";
1881 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1882 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1883 } else if (streq(type, "halt")) {
1884 action = "org.freedesktop.login1.halt";
1885 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1886 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1887 } else if (streq(type, "poweroff")) {
1888 action = "org.freedesktop.login1.poweroff";
1889 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1890 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1892 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1894 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1895 action, action_multiple_sessions, action_ignore_inhibit, error);
1899 if (m->scheduled_shutdown_timeout_source) {
1900 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1902 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1904 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1906 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1908 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1909 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1911 return log_error_errno(r, "sd_event_add_time() failed: %m");
1914 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1916 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1920 if (m->nologin_timeout_source) {
1921 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1923 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1925 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1927 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1929 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1930 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1932 return log_error_errno(r, "sd_event_add_time() failed: %m");
1935 m->scheduled_shutdown_timeout = elapse;
1937 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1941 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1942 (void) sd_bus_creds_get_tty(creds, &tty);
1944 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1946 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1951 r = manager_setup_wall_message_timer(m);
1955 if (!isempty(type)) {
1956 r = update_schedule_file(m);
1960 (void) unlink("/run/systemd/shutdown/scheduled");
1962 return sd_bus_reply_method_return(message, NULL);
1965 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1966 Manager *m = userdata;
1972 cancelled = m->scheduled_shutdown_type != NULL;
1974 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1975 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1976 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1977 free(m->scheduled_shutdown_type);
1978 m->scheduled_shutdown_type = NULL;
1979 m->scheduled_shutdown_timeout = 0;
1981 if (m->unlink_nologin) {
1982 (void) unlink("/run/nologin");
1983 m->unlink_nologin = false;
1987 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1988 const char *tty = NULL;
1992 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1994 (void) sd_bus_creds_get_uid(creds, &uid);
1995 (void) sd_bus_creds_get_tty(creds, &tty);
1998 utmp_wall("The system shutdown has been cancelled",
1999 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2002 return sd_bus_reply_method_return(message, "b", cancelled);
2005 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2006 Manager *m = userdata;
2008 return method_do_shutdown_or_sleep(
2010 SPECIAL_HIBERNATE_TARGET,
2012 "org.freedesktop.login1.hibernate",
2013 "org.freedesktop.login1.hibernate-multiple-sessions",
2014 "org.freedesktop.login1.hibernate-ignore-inhibit",
2019 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2020 Manager *m = userdata;
2022 return method_do_shutdown_or_sleep(
2024 SPECIAL_HYBRID_SLEEP_TARGET,
2026 "org.freedesktop.login1.hibernate",
2027 "org.freedesktop.login1.hibernate-multiple-sessions",
2028 "org.freedesktop.login1.hibernate-ignore-inhibit",
2033 static int method_can_shutdown_or_sleep(
2035 sd_bus_message *message,
2038 const char *action_multiple_sessions,
2039 const char *action_ignore_inhibit,
2040 const char *sleep_verb,
2041 sd_bus_error *error) {
2043 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2044 bool multiple_sessions, challenge, blocked;
2045 const char *result = NULL;
2052 assert(w <= _INHIBIT_WHAT_MAX);
2054 assert(action_multiple_sessions);
2055 assert(action_ignore_inhibit);
2058 r = can_sleep(sleep_verb);
2062 return sd_bus_reply_method_return(message, "s", "na");
2065 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2069 r = sd_bus_creds_get_euid(creds, &uid);
2073 r = have_multiple_sessions(m, uid);
2077 multiple_sessions = r > 0;
2078 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2080 if (multiple_sessions) {
2081 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2088 result = "challenge";
2094 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2098 if (r > 0 && !result)
2100 else if (challenge && (!result || streq(result, "yes")))
2101 result = "challenge";
2106 if (!multiple_sessions && !blocked) {
2107 /* If neither inhibit nor multiple sessions
2108 * apply then just check the normal policy */
2110 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2117 result = "challenge";
2122 return sd_bus_reply_method_return(message, "s", result);
2125 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2126 Manager *m = userdata;
2128 return method_can_shutdown_or_sleep(
2131 "org.freedesktop.login1.power-off",
2132 "org.freedesktop.login1.power-off-multiple-sessions",
2133 "org.freedesktop.login1.power-off-ignore-inhibit",
2138 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2139 Manager *m = userdata;
2141 return method_can_shutdown_or_sleep(
2144 "org.freedesktop.login1.reboot",
2145 "org.freedesktop.login1.reboot-multiple-sessions",
2146 "org.freedesktop.login1.reboot-ignore-inhibit",
2151 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2152 Manager *m = userdata;
2154 return method_can_shutdown_or_sleep(
2157 "org.freedesktop.login1.suspend",
2158 "org.freedesktop.login1.suspend-multiple-sessions",
2159 "org.freedesktop.login1.suspend-ignore-inhibit",
2164 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2165 Manager *m = userdata;
2167 return method_can_shutdown_or_sleep(
2170 "org.freedesktop.login1.hibernate",
2171 "org.freedesktop.login1.hibernate-multiple-sessions",
2172 "org.freedesktop.login1.hibernate-ignore-inhibit",
2177 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2178 Manager *m = userdata;
2180 return method_can_shutdown_or_sleep(
2183 "org.freedesktop.login1.hibernate",
2184 "org.freedesktop.login1.hibernate-multiple-sessions",
2185 "org.freedesktop.login1.hibernate-ignore-inhibit",
2190 static int property_get_reboot_to_firmware_setup(
2193 const char *interface,
2194 const char *property,
2195 sd_bus_message *reply,
2197 sd_bus_error *error) {
2204 r = efi_get_reboot_to_firmware();
2205 if (r < 0 && r != -EOPNOTSUPP)
2208 return sd_bus_message_append(reply, "b", r > 0);
2211 static int method_set_reboot_to_firmware_setup(
2212 sd_bus_message *message,
2214 sd_bus_error *error) {
2217 Manager *m = userdata;
2222 r = sd_bus_message_read(message, "b", &b);
2226 r = bus_verify_polkit_async(message,
2228 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2231 &m->polkit_registry,
2236 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2238 r = efi_set_reboot_to_firmware(b);
2242 return sd_bus_reply_method_return(message, NULL);
2245 static int method_can_reboot_to_firmware_setup(
2246 sd_bus_message *message,
2248 sd_bus_error *error) {
2253 Manager *m = userdata;
2258 r = efi_reboot_to_firmware_supported();
2259 if (r == -EOPNOTSUPP)
2260 return sd_bus_reply_method_return(message, "s", "na");
2264 r = bus_test_polkit(message,
2266 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2276 result = "challenge";
2280 return sd_bus_reply_method_return(message, "s", result);
2283 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2284 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2285 const char *who, *why, *what, *mode;
2286 _cleanup_free_ char *id = NULL;
2287 _cleanup_close_ int fifo_fd = -1;
2288 Manager *m = userdata;
2289 Inhibitor *i = NULL;
2299 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2303 w = inhibit_what_from_string(what);
2305 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2307 mm = inhibit_mode_from_string(mode);
2309 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2311 /* Delay is only supported for shutdown/sleep */
2312 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2313 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2315 /* Don't allow taking delay locks while we are already
2316 * executing the operation. We shouldn't create the impression
2317 * that the lock was successful if the machine is about to go
2318 * down/suspend any moment. */
2319 if (m->action_what & w)
2320 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2322 r = bus_verify_polkit_async(
2325 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2326 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2327 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2328 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2329 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2330 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2331 "org.freedesktop.login1.inhibit-handle-lid-switch",
2334 &m->polkit_registry,
2339 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2341 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2345 r = sd_bus_creds_get_euid(creds, &uid);
2349 r = sd_bus_creds_get_pid(creds, &pid);
2357 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2360 } while (hashmap_get(m->inhibitors, id));
2362 r = manager_add_inhibitor(m, id, &i);
2370 i->why = strdup(why);
2371 i->who = strdup(who);
2373 if (!i->why || !i->who) {
2378 fifo_fd = inhibitor_create_fifo(i);
2386 return sd_bus_reply_method_return(message, "h", fifo_fd);
2395 const sd_bus_vtable manager_vtable[] = {
2396 SD_BUS_VTABLE_START(0),
2398 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2399 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2401 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2402 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2403 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2404 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2405 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2406 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2407 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2408 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2409 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2410 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2411 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2412 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2413 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2414 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2415 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2416 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2417 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2418 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2419 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2420 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2421 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2422 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2424 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2425 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2426 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2427 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2428 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2429 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2430 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2431 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2432 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2433 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2434 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2435 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2436 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2437 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2438 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2439 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2440 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2441 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2442 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2443 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2444 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2445 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2446 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2447 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2448 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2449 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2450 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2451 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2452 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2453 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2454 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2455 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2456 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_SIGNAL("SessionNew", "so", 0),
2466 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2467 SD_BUS_SIGNAL("UserNew", "uo", 0),
2468 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2469 SD_BUS_SIGNAL("SeatNew", "so", 0),
2470 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2471 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2472 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2477 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2486 if (streq(result, "done"))
2487 r = session_send_create_reply(s, NULL);
2489 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2491 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2492 r = session_send_create_reply(s, &e);
2498 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2499 const char *path, *result, *unit;
2500 Manager *m = userdata;
2509 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2511 bus_log_parse_error(r);
2515 if (m->action_job && streq(m->action_job, path)) {
2516 log_info("Operation finished.");
2518 /* Tell people that they now may take a lock again */
2519 send_prepare_for(m, m->action_what, false);
2521 free(m->action_job);
2522 m->action_job = NULL;
2523 m->action_unit = NULL;
2528 session = hashmap_get(m->session_units, unit);
2531 if (streq_ptr(path, session->scope_job)) {
2532 free(session->scope_job);
2533 session->scope_job = NULL;
2536 session_jobs_reply(session, unit, result);
2538 session_save(session);
2539 user_save(session->user);
2540 session_add_to_gc_queue(session);
2543 user = hashmap_get(m->user_units, unit);
2546 if (streq_ptr(path, user->service_job)) {
2547 free(user->service_job);
2548 user->service_job = NULL;
2551 if (streq_ptr(path, user->slice_job)) {
2552 free(user->slice_job);
2553 user->slice_job = NULL;
2556 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2557 session_jobs_reply(session, unit, result);
2561 user_add_to_gc_queue(user);
2567 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2568 const char *path, *unit;
2569 Manager *m = userdata;
2577 r = sd_bus_message_read(message, "so", &unit, &path);
2579 bus_log_parse_error(r);
2583 session = hashmap_get(m->session_units, unit);
2585 session_add_to_gc_queue(session);
2587 user = hashmap_get(m->user_units, unit);
2589 user_add_to_gc_queue(user);
2594 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2595 _cleanup_free_ char *unit = NULL;
2596 Manager *m = userdata;
2605 path = sd_bus_message_get_path(message);
2609 r = unit_name_from_dbus_path(path, &unit);
2610 if (r == -EINVAL) /* not a unit */
2615 session = hashmap_get(m->session_units, unit);
2617 session_add_to_gc_queue(session);
2619 user = hashmap_get(m->user_units, unit);
2621 user_add_to_gc_queue(user);
2626 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627 Manager *m = userdata;
2635 r = sd_bus_message_read(message, "b", &b);
2637 bus_log_parse_error(r);
2644 /* systemd finished reloading, let's recheck all our sessions */
2645 log_debug("System manager has been reloaded, rechecking sessions...");
2647 HASHMAP_FOREACH(session, m->sessions, i)
2648 session_add_to_gc_queue(session);
2653 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2654 const char *name, *old, *new;
2655 Manager *m = userdata;
2664 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2666 bus_log_parse_error(r);
2670 if (isempty(old) || !isempty(new))
2673 key = set_remove(m->busnames, (char*) old);
2677 /* Drop all controllers owned by this name */
2681 HASHMAP_FOREACH(session, m->sessions, i)
2682 if (session_is_controller(session, old))
2683 session_drop_controller(session);
2688 int manager_send_changed(Manager *manager, const char *property, ...) {
2693 l = strv_from_stdarg_alloca(property);
2695 return sd_bus_emit_properties_changed_strv(
2697 "/org/freedesktop/login1",
2698 "org.freedesktop.login1.Manager",
2702 int manager_start_scope(
2707 const char *description,
2708 const char *after, const char *after2,
2709 sd_bus_error *error,
2712 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2719 r = sd_bus_message_new_method_call(
2722 "org.freedesktop.systemd1",
2723 "/org/freedesktop/systemd1",
2724 "org.freedesktop.systemd1.Manager",
2725 "StartTransientUnit");
2729 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2733 r = sd_bus_message_open_container(m, 'a', "(sv)");
2737 if (!isempty(slice)) {
2738 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2743 if (!isempty(description)) {
2744 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2749 if (!isempty(after)) {
2750 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2755 if (!isempty(after2)) {
2756 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2761 /* cgroup empty notification is not available in containers
2762 * currently. To make this less problematic, let's shorten the
2763 * stop timeout for sessions, so that we don't wait
2766 /* Make sure that the session shells are terminated with
2767 * SIGHUP since bash and friends tend to ignore SIGTERM */
2768 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2772 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2776 r = sd_bus_message_close_container(m);
2780 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2784 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2792 r = sd_bus_message_read(reply, "o", &j);
2806 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2807 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2813 r = sd_bus_call_method(
2815 "org.freedesktop.systemd1",
2816 "/org/freedesktop/systemd1",
2817 "org.freedesktop.systemd1.Manager",
2821 "ss", unit, "fail");
2829 r = sd_bus_message_read(reply, "o", &j);
2843 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2844 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2850 r = sd_bus_call_method(
2852 "org.freedesktop.systemd1",
2853 "/org/freedesktop/systemd1",
2854 "org.freedesktop.systemd1.Manager",
2858 "ss", unit, "fail");
2860 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2861 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2866 sd_bus_error_free(error);
2877 r = sd_bus_message_read(reply, "o", &j);
2891 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2892 _cleanup_free_ char *path = NULL;
2898 path = unit_dbus_path_from_name(scope);
2902 r = sd_bus_call_method(
2904 "org.freedesktop.systemd1",
2906 "org.freedesktop.systemd1.Scope",
2912 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2913 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2914 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2915 sd_bus_error_free(error);
2925 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2929 return sd_bus_call_method(
2931 "org.freedesktop.systemd1",
2932 "/org/freedesktop/systemd1",
2933 "org.freedesktop.systemd1.Manager",
2937 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2940 int manager_unit_is_active(Manager *manager, const char *unit) {
2941 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2942 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2943 _cleanup_free_ char *path = NULL;
2950 path = unit_dbus_path_from_name(unit);
2954 r = sd_bus_get_property(
2956 "org.freedesktop.systemd1",
2958 "org.freedesktop.systemd1.Unit",
2964 /* systemd might have droppped off momentarily, let's
2965 * not make this an error */
2966 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2967 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2970 /* If the unit is already unloaded then it's not
2972 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2973 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2979 r = sd_bus_message_read(reply, "s", &state);
2983 return !streq(state, "inactive") && !streq(state, "failed");
2986 int manager_job_is_active(Manager *manager, const char *path) {
2987 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2988 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2994 r = sd_bus_get_property(
2996 "org.freedesktop.systemd1",
2998 "org.freedesktop.systemd1.Job",
3004 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3005 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3008 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3014 /* We don't actually care about the state really. The fact
3015 * that we could read the job state is enough for us */