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);
737 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
740 } while (hashmap_get(m->sessions, id));
743 r = manager_add_user_by_uid(m, uid, &user);
747 r = manager_add_session(m, id, &session);
751 session_set_user(session, user);
753 session->leader = leader;
754 session->audit_id = audit_id;
757 session->remote = remote;
758 session->vtnr = vtnr;
761 session->tty = strdup(tty);
768 if (!isempty(display)) {
769 session->display = strdup(display);
770 if (!session->display) {
776 if (!isempty(remote_user)) {
777 session->remote_user = strdup(remote_user);
778 if (!session->remote_user) {
784 if (!isempty(remote_host)) {
785 session->remote_host = strdup(remote_host);
786 if (!session->remote_host) {
792 if (!isempty(service)) {
793 session->service = strdup(service);
794 if (!session->service) {
800 if (!isempty(desktop)) {
801 session->desktop = strdup(desktop);
802 if (!session->desktop) {
809 r = seat_attach_session(seat, session);
814 r = session_start(session);
818 session->create_message = sd_bus_message_ref(message);
820 /* Now, let's wait until the slice unit and stuff got
821 * created. We send the reply back from
822 * session_send_create_reply(). */
828 session_add_to_gc_queue(session);
831 user_add_to_gc_queue(user);
836 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
837 Manager *m = userdata;
845 r = sd_bus_message_read(message, "s", &name);
849 r = manager_get_session_from_creds(m, message, name, error, &session);
853 r = session_release(session);
857 return sd_bus_reply_method_return(message, NULL);
860 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
861 Manager *m = userdata;
869 r = sd_bus_message_read(message, "s", &name);
873 r = manager_get_session_from_creds(m, message, name, error, &session);
877 return bus_session_method_activate(message, session, error);
880 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
881 const char *session_name, *seat_name;
882 Manager *m = userdata;
890 /* Same as ActivateSession() but refuses to work if
891 * the seat doesn't match */
893 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
897 r = manager_get_session_from_creds(m, message, session_name, error, &session);
901 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
905 if (session->seat != seat)
906 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
908 r = session_activate(session);
912 return sd_bus_reply_method_return(message, NULL);
915 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
916 Manager *m = userdata;
924 r = sd_bus_message_read(message, "s", &name);
928 r = manager_get_session_from_creds(m, message, name, error, &session);
932 return bus_session_method_lock(message, session, error);
935 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
936 Manager *m = userdata;
942 r = bus_verify_polkit_async(
945 "org.freedesktop.login1.lock-sessions",
953 return 1; /* Will call us back */
955 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
959 return sd_bus_reply_method_return(message, NULL);
962 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
964 Manager *m = userdata;
971 r = sd_bus_message_read(message, "s", &name);
975 r = manager_get_session_from_creds(m, message, name, error, &session);
979 return bus_session_method_kill(message, session, error);
982 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
983 Manager *m = userdata;
991 r = sd_bus_message_read(message, "u", &uid);
995 r = manager_get_user_from_creds(m, message, uid, error, &user);
999 return bus_user_method_kill(message, user, error);
1002 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1003 Manager *m = userdata;
1011 r = sd_bus_message_read(message, "s", &name);
1015 r = manager_get_session_from_creds(m, message, name, error, &session);
1019 return bus_session_method_terminate(message, session, error);
1022 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1023 Manager *m = userdata;
1031 r = sd_bus_message_read(message, "u", &uid);
1035 r = manager_get_user_from_creds(m, message, uid, error, &user);
1039 return bus_user_method_terminate(message, user, error);
1042 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1043 Manager *m = userdata;
1051 r = sd_bus_message_read(message, "s", &name);
1055 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1059 return bus_seat_method_terminate(message, seat, error);
1062 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1063 _cleanup_free_ char *cc = NULL;
1064 Manager *m = userdata;
1074 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1078 if (uid == UID_INVALID) {
1079 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1081 /* Note that we get the owner UID of the session, not the actual client UID here! */
1082 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1086 r = sd_bus_creds_get_owner_uid(creds, &uid);
1094 return errno ? -errno : -ENOENT;
1096 r = bus_verify_polkit_async(
1099 "org.freedesktop.login1.set-user-linger",
1102 &m->polkit_registry,
1107 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1109 mkdir_p_label("/var/lib/systemd", 0755);
1111 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1115 cc = cescape(pw->pw_name);
1119 path = strjoina("/var/lib/systemd/linger/", cc);
1127 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1134 if (r < 0 && errno != ENOENT)
1137 u = hashmap_get(m->users, UID_TO_PTR(uid));
1139 user_add_to_gc_queue(u);
1142 return sd_bus_reply_method_return(message, NULL);
1145 static int trigger_device(Manager *m, struct udev_device *d) {
1146 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1147 struct udev_list_entry *first, *item;
1152 e = udev_enumerate_new(m->udev);
1157 r = udev_enumerate_add_match_parent(e, d);
1162 r = udev_enumerate_scan_devices(e);
1166 first = udev_enumerate_get_list_entry(e);
1167 udev_list_entry_foreach(item, first) {
1168 _cleanup_free_ char *t = NULL;
1171 p = udev_list_entry_get_name(item);
1173 t = strappend(p, "/uevent");
1177 write_string_file(t, "change");
1183 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1184 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1185 _cleanup_free_ char *rule = NULL, *file = NULL;
1186 const char *id_for_seat;
1193 d = udev_device_new_from_syspath(m->udev, sysfs);
1197 if (!udev_device_has_tag(d, "seat"))
1200 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1204 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1207 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1210 mkdir_p_label("/etc/udev/rules.d", 0755);
1211 mac_selinux_init("/etc");
1212 r = write_string_file_atomic_label(file, rule);
1216 return trigger_device(m, d);
1219 static int flush_devices(Manager *m) {
1220 _cleanup_closedir_ DIR *d;
1224 d = opendir("/etc/udev/rules.d");
1226 if (errno != ENOENT)
1227 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1231 while ((de = readdir(d))) {
1233 if (!dirent_is_file(de))
1236 if (!startswith(de->d_name, "72-seat-"))
1239 if (!endswith(de->d_name, ".rules"))
1242 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1243 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1247 return trigger_device(m, NULL);
1250 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1251 const char *sysfs, *seat;
1252 Manager *m = userdata;
1258 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1262 if (!path_startswith(sysfs, "/sys"))
1263 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1265 if (!seat_name_is_valid(seat))
1266 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1268 r = bus_verify_polkit_async(
1271 "org.freedesktop.login1.attach-device",
1274 &m->polkit_registry,
1279 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1281 r = attach_device(m, seat, sysfs);
1285 return sd_bus_reply_method_return(message, NULL);
1288 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1289 Manager *m = userdata;
1295 r = sd_bus_message_read(message, "b", &interactive);
1299 r = bus_verify_polkit_async(
1302 "org.freedesktop.login1.flush-devices",
1305 &m->polkit_registry,
1310 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1312 r = flush_devices(m);
1316 return sd_bus_reply_method_return(message, NULL);
1319 static int have_multiple_sessions(
1328 /* Check for other users' sessions. Greeter sessions do not
1329 * count, and non-login sessions do not count either. */
1330 HASHMAP_FOREACH(session, m->sessions, i)
1331 if (session->class == SESSION_USER &&
1332 session->user->uid != uid)
1338 static int bus_manager_log_shutdown(
1341 const char *unit_name) {
1348 if (w != INHIBIT_SHUTDOWN)
1351 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1352 p = "MESSAGE=System is powering down.";
1353 q = "SHUTDOWN=power-off";
1354 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1355 p = "MESSAGE=System is halting.";
1356 q = "SHUTDOWN=halt";
1357 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1358 p = "MESSAGE=System is rebooting.";
1359 q = "SHUTDOWN=reboot";
1360 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1361 p = "MESSAGE=System is rebooting with kexec.";
1362 q = "SHUTDOWN=kexec";
1364 p = "MESSAGE=System is shutting down.";
1368 if (!isempty(m->wall_message))
1369 p = strjoina(p, " (", m->wall_message, ")");
1371 return log_struct(LOG_NOTICE,
1372 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1378 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1379 Manager *m = userdata;
1384 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1388 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1393 if (until <= now(CLOCK_MONOTONIC))
1396 /* We want to ignore the lid switch for a while after each
1397 * suspend, and after boot-up. Hence let's install a timer for
1398 * this. As long as the event source exists we ignore the lid
1401 if (m->lid_switch_ignore_event_source) {
1404 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1411 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1413 r = sd_event_add_time(
1415 &m->lid_switch_ignore_event_source,
1418 lid_switch_ignore_handler, m);
1423 static int execute_shutdown_or_sleep(
1426 const char *unit_name,
1427 sd_bus_error *error) {
1429 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1436 assert(w < _INHIBIT_WHAT_MAX);
1439 bus_manager_log_shutdown(m, w, unit_name);
1441 r = sd_bus_call_method(
1443 "org.freedesktop.systemd1",
1444 "/org/freedesktop/systemd1",
1445 "org.freedesktop.systemd1.Manager",
1449 "ss", unit_name, "replace-irreversibly");
1453 r = sd_bus_message_read(reply, "o", &p);
1461 m->action_unit = unit_name;
1462 free(m->action_job);
1466 /* Make sure the lid switch is ignored for a while */
1467 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1472 static int manager_inhibit_timeout_handler(
1477 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1478 Inhibitor *offending = NULL;
1479 Manager *manager = userdata;
1483 assert(manager->inhibit_timeout_source == s);
1485 if (manager->action_what == 0 || manager->action_job)
1488 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1489 _cleanup_free_ char *comm = NULL, *u = NULL;
1491 (void) get_process_comm(offending->pid, &comm);
1492 u = uid_to_name(offending->uid);
1494 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1495 offending->uid, strna(u),
1496 offending->pid, strna(comm));
1499 /* Actually do the operation */
1500 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1502 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1504 manager->action_unit = NULL;
1505 manager->action_what = 0;
1511 static int delay_shutdown_or_sleep(
1514 const char *unit_name) {
1521 assert(w < _INHIBIT_WHAT_MAX);
1524 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1526 if (m->inhibit_timeout_source) {
1527 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1529 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1531 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1533 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1535 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1536 timeout_val, 0, manager_inhibit_timeout_handler, m);
1541 m->action_unit = unit_name;
1547 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1549 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1550 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1551 [INHIBIT_SLEEP] = "PrepareForSleep"
1554 int active = _active;
1558 assert(w < _INHIBIT_WHAT_MAX);
1559 assert(signal_name[w]);
1561 return sd_bus_emit_signal(m->bus,
1562 "/org/freedesktop/login1",
1563 "org.freedesktop.login1.Manager",
1569 int bus_manager_shutdown_or_sleep_now_or_later(
1571 const char *unit_name,
1573 sd_bus_error *error) {
1581 assert(w <= _INHIBIT_WHAT_MAX);
1582 assert(!m->action_job);
1584 /* Tell everybody to prepare for shutdown/sleep */
1585 send_prepare_for(m, w, true);
1588 m->inhibit_delay_max > 0 &&
1589 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1592 /* Shutdown is delayed, keep in mind what we
1593 * want to do, and start a timeout */
1594 r = delay_shutdown_or_sleep(m, w, unit_name);
1596 /* Shutdown is not delayed, execute it
1598 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1603 static int verify_shutdown_creds(
1605 sd_bus_message *message,
1609 const char *action_multiple_sessions,
1610 const char *action_ignore_inhibit,
1611 sd_bus_error *error) {
1613 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1614 bool multiple_sessions, blocked;
1621 assert(w <= _INHIBIT_WHAT_MAX);
1623 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1627 r = sd_bus_creds_get_euid(creds, &uid);
1631 r = have_multiple_sessions(m, uid);
1635 multiple_sessions = r > 0;
1636 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1638 if (multiple_sessions && action_multiple_sessions) {
1639 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1643 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1646 if (blocked && action_ignore_inhibit) {
1647 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1651 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1654 if (!multiple_sessions && !blocked && action) {
1655 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1659 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1665 static int method_do_shutdown_or_sleep(
1667 sd_bus_message *message,
1668 const char *unit_name,
1671 const char *action_multiple_sessions,
1672 const char *action_ignore_inhibit,
1673 const char *sleep_verb,
1674 sd_bus_error *error) {
1682 assert(w <= _INHIBIT_WHAT_MAX);
1684 r = sd_bus_message_read(message, "b", &interactive);
1688 /* Don't allow multiple jobs being executed at the same time */
1690 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1693 r = can_sleep(sleep_verb);
1698 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1701 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1702 action_ignore_inhibit, error);
1706 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1710 return sd_bus_reply_method_return(message, NULL);
1713 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1714 Manager *m = userdata;
1716 return method_do_shutdown_or_sleep(
1718 SPECIAL_POWEROFF_TARGET,
1720 "org.freedesktop.login1.power-off",
1721 "org.freedesktop.login1.power-off-multiple-sessions",
1722 "org.freedesktop.login1.power-off-ignore-inhibit",
1727 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1728 Manager *m = userdata;
1730 return method_do_shutdown_or_sleep(
1732 SPECIAL_REBOOT_TARGET,
1734 "org.freedesktop.login1.reboot",
1735 "org.freedesktop.login1.reboot-multiple-sessions",
1736 "org.freedesktop.login1.reboot-ignore-inhibit",
1741 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1742 Manager *m = userdata;
1744 return method_do_shutdown_or_sleep(
1746 SPECIAL_SUSPEND_TARGET,
1748 "org.freedesktop.login1.suspend",
1749 "org.freedesktop.login1.suspend-multiple-sessions",
1750 "org.freedesktop.login1.suspend-ignore-inhibit",
1755 static int nologin_timeout_handler(
1760 Manager *m = userdata;
1763 log_info("Creating /run/nologin, blocking further logins...");
1765 r = write_string_file_atomic("/run/nologin", "System is going down.");
1767 log_error_errno(r, "Failed to create /run/nologin: %m");
1769 m->unlink_nologin = true;
1774 static int update_schedule_file(Manager *m) {
1777 _cleanup_fclose_ FILE *f = NULL;
1778 _cleanup_free_ char *t = NULL, *temp_path = NULL;
1782 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1784 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1786 if (!isempty(m->wall_message)) {
1787 t = cescape(m->wall_message);
1792 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1794 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1796 (void) fchmod(fileno(f), 0644);
1802 m->scheduled_shutdown_timeout,
1803 m->enable_wall_messages,
1804 m->scheduled_shutdown_type);
1807 fprintf(f, "WALL_MESSAGE=%s\n", t);
1809 r = fflush_and_check(f);
1813 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1821 (void) unlink(temp_path);
1822 (void) unlink("/run/systemd/shutdown/scheduled");
1824 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1827 static int manager_scheduled_shutdown_handler(
1832 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1833 Manager *m = userdata;
1839 if (isempty(m->scheduled_shutdown_type))
1842 if (streq(m->scheduled_shutdown_type, "halt"))
1843 target = SPECIAL_HALT_TARGET;
1844 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1845 target = SPECIAL_POWEROFF_TARGET;
1847 target = SPECIAL_REBOOT_TARGET;
1849 r = execute_shutdown_or_sleep(m, 0, target, &error);
1851 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1856 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1857 Manager *m = userdata;
1858 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1859 const char *action_multiple_sessions = NULL;
1860 const char *action_ignore_inhibit = NULL;
1861 const char *action = NULL;
1869 r = sd_bus_message_read(message, "st", &type, &elapse);
1873 if (streq(type, "reboot")) {
1874 action = "org.freedesktop.login1.reboot";
1875 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1876 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1877 } else if (streq(type, "halt")) {
1878 action = "org.freedesktop.login1.halt";
1879 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1880 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1881 } else if (streq(type, "poweroff")) {
1882 action = "org.freedesktop.login1.poweroff";
1883 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1884 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1886 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1888 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1889 action, action_multiple_sessions, action_ignore_inhibit, error);
1893 if (m->scheduled_shutdown_timeout_source) {
1894 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1896 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1898 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1900 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1902 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1903 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1905 return log_error_errno(r, "sd_event_add_time() failed: %m");
1908 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1910 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1914 if (m->nologin_timeout_source) {
1915 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1917 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1919 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1921 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1923 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1924 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1926 return log_error_errno(r, "sd_event_add_time() failed: %m");
1929 m->scheduled_shutdown_timeout = elapse;
1931 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1935 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1936 (void) sd_bus_creds_get_tty(creds, &tty);
1938 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1940 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1945 r = manager_setup_wall_message_timer(m);
1949 if (!isempty(type)) {
1950 r = update_schedule_file(m);
1954 (void) unlink("/run/systemd/shutdown/scheduled");
1956 return sd_bus_reply_method_return(message, NULL);
1959 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1960 Manager *m = userdata;
1966 cancelled = m->scheduled_shutdown_type != NULL;
1968 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1969 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1970 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1971 free(m->scheduled_shutdown_type);
1972 m->scheduled_shutdown_type = NULL;
1973 m->scheduled_shutdown_timeout = 0;
1976 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1977 const char *tty = NULL;
1981 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1983 (void) sd_bus_creds_get_uid(creds, &uid);
1984 (void) sd_bus_creds_get_tty(creds, &tty);
1987 utmp_wall("The system shutdown has been cancelled",
1988 lookup_uid(uid), tty, logind_wall_tty_filter, m);
1991 return sd_bus_reply_method_return(message, "b", cancelled);
1994 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1995 Manager *m = userdata;
1997 return method_do_shutdown_or_sleep(
1999 SPECIAL_HIBERNATE_TARGET,
2001 "org.freedesktop.login1.hibernate",
2002 "org.freedesktop.login1.hibernate-multiple-sessions",
2003 "org.freedesktop.login1.hibernate-ignore-inhibit",
2008 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2009 Manager *m = userdata;
2011 return method_do_shutdown_or_sleep(
2013 SPECIAL_HYBRID_SLEEP_TARGET,
2015 "org.freedesktop.login1.hibernate",
2016 "org.freedesktop.login1.hibernate-multiple-sessions",
2017 "org.freedesktop.login1.hibernate-ignore-inhibit",
2022 static int method_can_shutdown_or_sleep(
2024 sd_bus_message *message,
2027 const char *action_multiple_sessions,
2028 const char *action_ignore_inhibit,
2029 const char *sleep_verb,
2030 sd_bus_error *error) {
2032 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2033 bool multiple_sessions, challenge, blocked;
2034 const char *result = NULL;
2041 assert(w <= _INHIBIT_WHAT_MAX);
2043 assert(action_multiple_sessions);
2044 assert(action_ignore_inhibit);
2047 r = can_sleep(sleep_verb);
2051 return sd_bus_reply_method_return(message, "s", "na");
2054 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2058 r = sd_bus_creds_get_euid(creds, &uid);
2062 r = have_multiple_sessions(m, uid);
2066 multiple_sessions = r > 0;
2067 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2069 if (multiple_sessions) {
2070 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2077 result = "challenge";
2083 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2087 if (r > 0 && !result)
2089 else if (challenge && (!result || streq(result, "yes")))
2090 result = "challenge";
2095 if (!multiple_sessions && !blocked) {
2096 /* If neither inhibit nor multiple sessions
2097 * apply then just check the normal policy */
2099 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2106 result = "challenge";
2111 return sd_bus_reply_method_return(message, "s", result);
2114 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2115 Manager *m = userdata;
2117 return method_can_shutdown_or_sleep(
2120 "org.freedesktop.login1.power-off",
2121 "org.freedesktop.login1.power-off-multiple-sessions",
2122 "org.freedesktop.login1.power-off-ignore-inhibit",
2127 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2128 Manager *m = userdata;
2130 return method_can_shutdown_or_sleep(
2133 "org.freedesktop.login1.reboot",
2134 "org.freedesktop.login1.reboot-multiple-sessions",
2135 "org.freedesktop.login1.reboot-ignore-inhibit",
2140 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2141 Manager *m = userdata;
2143 return method_can_shutdown_or_sleep(
2146 "org.freedesktop.login1.suspend",
2147 "org.freedesktop.login1.suspend-multiple-sessions",
2148 "org.freedesktop.login1.suspend-ignore-inhibit",
2153 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2154 Manager *m = userdata;
2156 return method_can_shutdown_or_sleep(
2159 "org.freedesktop.login1.hibernate",
2160 "org.freedesktop.login1.hibernate-multiple-sessions",
2161 "org.freedesktop.login1.hibernate-ignore-inhibit",
2166 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2167 Manager *m = userdata;
2169 return method_can_shutdown_or_sleep(
2172 "org.freedesktop.login1.hibernate",
2173 "org.freedesktop.login1.hibernate-multiple-sessions",
2174 "org.freedesktop.login1.hibernate-ignore-inhibit",
2179 static int property_get_reboot_to_firmware_setup(
2182 const char *interface,
2183 const char *property,
2184 sd_bus_message *reply,
2186 sd_bus_error *error) {
2193 r = efi_get_reboot_to_firmware();
2194 if (r < 0 && r != -EOPNOTSUPP)
2197 return sd_bus_message_append(reply, "b", r > 0);
2200 static int method_set_reboot_to_firmware_setup(
2201 sd_bus_message *message,
2203 sd_bus_error *error) {
2206 Manager *m = userdata;
2211 r = sd_bus_message_read(message, "b", &b);
2215 r = bus_verify_polkit_async(message,
2217 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2220 &m->polkit_registry,
2225 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2227 r = efi_set_reboot_to_firmware(b);
2231 return sd_bus_reply_method_return(message, NULL);
2234 static int method_can_reboot_to_firmware_setup(
2235 sd_bus_message *message,
2237 sd_bus_error *error) {
2242 Manager *m = userdata;
2247 r = efi_reboot_to_firmware_supported();
2248 if (r == -EOPNOTSUPP)
2249 return sd_bus_reply_method_return(message, "s", "na");
2253 r = bus_test_polkit(message,
2255 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2265 result = "challenge";
2269 return sd_bus_reply_method_return(message, "s", result);
2272 static int method_set_wall_message(
2273 sd_bus_message *message,
2275 sd_bus_error *error) {
2278 Manager *m = userdata;
2280 int enable_wall_messages;
2285 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2289 r = bus_verify_polkit_async(message,
2291 "org.freedesktop.login1.set-wall-message",
2294 &m->polkit_registry,
2299 return 1; /* Will call us back */
2301 if (isempty(wall_message))
2302 m->wall_message = mfree(m->wall_message);
2304 r = free_and_strdup(&m->wall_message, wall_message);
2309 m->enable_wall_messages = enable_wall_messages;
2311 return sd_bus_reply_method_return(message, NULL);
2314 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2315 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2316 const char *who, *why, *what, *mode;
2317 _cleanup_free_ char *id = NULL;
2318 _cleanup_close_ int fifo_fd = -1;
2319 Manager *m = userdata;
2320 Inhibitor *i = NULL;
2330 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2334 w = inhibit_what_from_string(what);
2336 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2338 mm = inhibit_mode_from_string(mode);
2340 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2342 /* Delay is only supported for shutdown/sleep */
2343 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2344 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2346 /* Don't allow taking delay locks while we are already
2347 * executing the operation. We shouldn't create the impression
2348 * that the lock was successful if the machine is about to go
2349 * down/suspend any moment. */
2350 if (m->action_what & w)
2351 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2353 r = bus_verify_polkit_async(
2356 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2357 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2358 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2359 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2360 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2361 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2362 "org.freedesktop.login1.inhibit-handle-lid-switch",
2365 &m->polkit_registry,
2370 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2372 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2376 r = sd_bus_creds_get_euid(creds, &uid);
2380 r = sd_bus_creds_get_pid(creds, &pid);
2387 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2390 } while (hashmap_get(m->inhibitors, id));
2392 r = manager_add_inhibitor(m, id, &i);
2400 i->why = strdup(why);
2401 i->who = strdup(who);
2403 if (!i->why || !i->who) {
2408 fifo_fd = inhibitor_create_fifo(i);
2416 return sd_bus_reply_method_return(message, "h", fifo_fd);
2425 const sd_bus_vtable manager_vtable[] = {
2426 SD_BUS_VTABLE_START(0),
2428 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2429 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2431 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2432 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2433 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2434 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2435 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2436 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2437 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2438 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2439 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2440 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2441 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2442 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2443 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2444 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2445 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2446 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2447 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2448 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2449 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2450 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2451 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2452 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2454 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2455 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2456 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2457 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2458 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2459 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2460 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2461 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2462 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2463 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2464 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2465 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2466 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2467 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2473 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2474 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2475 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2483 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2485 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2487 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2488 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2490 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2491 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_SIGNAL("SessionNew", "so", 0),
2497 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2498 SD_BUS_SIGNAL("UserNew", "uo", 0),
2499 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2500 SD_BUS_SIGNAL("SeatNew", "so", 0),
2501 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2502 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2503 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2508 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2517 if (streq(result, "done"))
2518 r = session_send_create_reply(s, NULL);
2520 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2522 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2523 r = session_send_create_reply(s, &e);
2529 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2530 const char *path, *result, *unit;
2531 Manager *m = userdata;
2540 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2542 bus_log_parse_error(r);
2546 if (m->action_job && streq(m->action_job, path)) {
2547 log_info("Operation finished.");
2549 /* Tell people that they now may take a lock again */
2550 send_prepare_for(m, m->action_what, false);
2552 m->action_job = mfree(m->action_job);
2553 m->action_unit = NULL;
2558 session = hashmap_get(m->session_units, unit);
2561 if (streq_ptr(path, session->scope_job))
2562 session->scope_job = mfree(session->scope_job);
2564 session_jobs_reply(session, unit, result);
2566 session_save(session);
2567 session_add_to_gc_queue(session);
2570 user = hashmap_get(m->user_units, unit);
2573 if (streq_ptr(path, user->service_job))
2574 user->service_job = mfree(user->service_job);
2576 if (streq_ptr(path, user->slice_job))
2577 user->slice_job = mfree(user->slice_job);
2579 LIST_FOREACH(sessions_by_user, session, user->sessions)
2580 session_jobs_reply(session, unit, result);
2583 user_add_to_gc_queue(user);
2589 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2590 const char *path, *unit;
2591 Manager *m = userdata;
2599 r = sd_bus_message_read(message, "so", &unit, &path);
2601 bus_log_parse_error(r);
2605 session = hashmap_get(m->session_units, unit);
2607 session_add_to_gc_queue(session);
2609 user = hashmap_get(m->user_units, unit);
2611 user_add_to_gc_queue(user);
2616 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2617 _cleanup_free_ char *unit = NULL;
2618 Manager *m = userdata;
2627 path = sd_bus_message_get_path(message);
2631 r = unit_name_from_dbus_path(path, &unit);
2632 if (r == -EINVAL) /* not a unit */
2639 session = hashmap_get(m->session_units, unit);
2641 session_add_to_gc_queue(session);
2643 user = hashmap_get(m->user_units, unit);
2645 user_add_to_gc_queue(user);
2650 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2651 Manager *m = userdata;
2659 r = sd_bus_message_read(message, "b", &b);
2661 bus_log_parse_error(r);
2668 /* systemd finished reloading, let's recheck all our sessions */
2669 log_debug("System manager has been reloaded, rechecking sessions...");
2671 HASHMAP_FOREACH(session, m->sessions, i)
2672 session_add_to_gc_queue(session);
2677 int manager_send_changed(Manager *manager, const char *property, ...) {
2682 l = strv_from_stdarg_alloca(property);
2684 return sd_bus_emit_properties_changed_strv(
2686 "/org/freedesktop/login1",
2687 "org.freedesktop.login1.Manager",
2691 int manager_start_scope(
2696 const char *description,
2697 const char *after, const char *after2,
2698 sd_bus_error *error,
2701 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2708 r = sd_bus_message_new_method_call(
2711 "org.freedesktop.systemd1",
2712 "/org/freedesktop/systemd1",
2713 "org.freedesktop.systemd1.Manager",
2714 "StartTransientUnit");
2718 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2722 r = sd_bus_message_open_container(m, 'a', "(sv)");
2726 if (!isempty(slice)) {
2727 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2732 if (!isempty(description)) {
2733 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2738 if (!isempty(after)) {
2739 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2744 if (!isempty(after2)) {
2745 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2750 /* cgroup empty notification is not available in containers
2751 * currently. To make this less problematic, let's shorten the
2752 * stop timeout for sessions, so that we don't wait
2755 /* Make sure that the session shells are terminated with
2756 * SIGHUP since bash and friends tend to ignore SIGTERM */
2757 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2761 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2765 r = sd_bus_message_close_container(m);
2769 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2773 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2781 r = sd_bus_message_read(reply, "o", &j);
2795 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2796 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2802 r = sd_bus_call_method(
2804 "org.freedesktop.systemd1",
2805 "/org/freedesktop/systemd1",
2806 "org.freedesktop.systemd1.Manager",
2810 "ss", unit, "fail");
2818 r = sd_bus_message_read(reply, "o", &j);
2832 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2833 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2839 r = sd_bus_call_method(
2841 "org.freedesktop.systemd1",
2842 "/org/freedesktop/systemd1",
2843 "org.freedesktop.systemd1.Manager",
2847 "ss", unit, "fail");
2849 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2850 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2855 sd_bus_error_free(error);
2866 r = sd_bus_message_read(reply, "o", &j);
2880 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2881 _cleanup_free_ char *path = NULL;
2887 path = unit_dbus_path_from_name(scope);
2891 r = sd_bus_call_method(
2893 "org.freedesktop.systemd1",
2895 "org.freedesktop.systemd1.Scope",
2901 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2902 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2903 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2904 sd_bus_error_free(error);
2914 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2918 return sd_bus_call_method(
2920 "org.freedesktop.systemd1",
2921 "/org/freedesktop/systemd1",
2922 "org.freedesktop.systemd1.Manager",
2926 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2929 int manager_unit_is_active(Manager *manager, const char *unit) {
2930 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2931 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2932 _cleanup_free_ char *path = NULL;
2939 path = unit_dbus_path_from_name(unit);
2943 r = sd_bus_get_property(
2945 "org.freedesktop.systemd1",
2947 "org.freedesktop.systemd1.Unit",
2953 /* systemd might have droppped off momentarily, let's
2954 * not make this an error */
2955 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2956 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2959 /* If the unit is already unloaded then it's not
2961 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2962 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2968 r = sd_bus_message_read(reply, "s", &state);
2972 return !streq(state, "inactive") && !streq(state, "failed");
2975 int manager_job_is_active(Manager *manager, const char *path) {
2976 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2977 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2983 r = sd_bus_get_property(
2985 "org.freedesktop.systemd1",
2987 "org.freedesktop.systemd1.Job",
2993 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2994 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2997 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3003 /* We don't actually care about the state really. The fact
3004 * that we could read the job state is enough for us */