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"
31 // #include "special.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 /* Here upstream systemd starts cgroups and the user systemd,
821 and arranges to reply asynchronously. We reply
824 r = session_send_create_reply(session, NULL);
828 session_save(session);
834 session_add_to_gc_queue(session);
837 user_add_to_gc_queue(user);
842 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
843 Manager *m = userdata;
851 r = sd_bus_message_read(message, "s", &name);
855 r = manager_get_session_from_creds(m, message, name, error, &session);
859 r = session_release(session);
863 session_add_to_gc_queue(session);
865 return sd_bus_reply_method_return(message, NULL);
868 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
869 Manager *m = userdata;
877 r = sd_bus_message_read(message, "s", &name);
881 r = manager_get_session_from_creds(m, message, name, error, &session);
885 return bus_session_method_activate(message, session, error);
888 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
889 const char *session_name, *seat_name;
890 Manager *m = userdata;
898 /* Same as ActivateSession() but refuses to work if
899 * the seat doesn't match */
901 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
905 r = manager_get_session_from_creds(m, message, session_name, error, &session);
909 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
913 if (session->seat != seat)
914 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
916 r = session_activate(session);
920 return sd_bus_reply_method_return(message, NULL);
923 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
924 Manager *m = userdata;
932 r = sd_bus_message_read(message, "s", &name);
936 r = manager_get_session_from_creds(m, message, name, error, &session);
940 return bus_session_method_lock(message, session, error);
943 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
944 Manager *m = userdata;
950 r = bus_verify_polkit_async(
953 "org.freedesktop.login1.lock-sessions",
962 return 1; /* Will call us back */
964 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
968 return sd_bus_reply_method_return(message, NULL);
971 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
973 Manager *m = userdata;
980 r = sd_bus_message_read(message, "s", &name);
984 r = manager_get_session_from_creds(m, message, name, error, &session);
988 return bus_session_method_kill(message, session, error);
991 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
992 Manager *m = userdata;
1000 r = sd_bus_message_read(message, "u", &uid);
1004 r = manager_get_user_from_creds(m, message, uid, error, &user);
1008 return bus_user_method_kill(message, user, error);
1011 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1012 Manager *m = userdata;
1020 r = sd_bus_message_read(message, "s", &name);
1024 r = manager_get_session_from_creds(m, message, name, error, &session);
1028 return bus_session_method_terminate(message, session, error);
1031 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1032 Manager *m = userdata;
1040 r = sd_bus_message_read(message, "u", &uid);
1044 r = manager_get_user_from_creds(m, message, uid, error, &user);
1048 return bus_user_method_terminate(message, user, error);
1051 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1052 Manager *m = userdata;
1060 r = sd_bus_message_read(message, "s", &name);
1064 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1068 return bus_seat_method_terminate(message, seat, error);
1071 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1072 _cleanup_free_ char *cc = NULL;
1073 Manager *m = userdata;
1083 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1087 if (uid == UID_INVALID) {
1088 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1090 /* Note that we get the owner UID of the session, not the actual client UID here! */
1091 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1095 r = sd_bus_creds_get_owner_uid(creds, &uid);
1103 return errno ? -errno : -ENOENT;
1105 r = bus_verify_polkit_async(
1108 "org.freedesktop.login1.set-user-linger",
1112 &m->polkit_registry,
1117 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1119 mkdir_p_label("/var/lib/systemd", 0755);
1121 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1125 cc = cescape(pw->pw_name);
1129 path = strjoina("/var/lib/systemd/linger/", cc);
1137 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1144 if (r < 0 && errno != ENOENT)
1147 u = hashmap_get(m->users, UID_TO_PTR(uid));
1149 user_add_to_gc_queue(u);
1152 return sd_bus_reply_method_return(message, NULL);
1155 static int trigger_device(Manager *m, struct udev_device *d) {
1156 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1157 struct udev_list_entry *first, *item;
1162 e = udev_enumerate_new(m->udev);
1167 r = udev_enumerate_add_match_parent(e, d);
1172 r = udev_enumerate_scan_devices(e);
1176 first = udev_enumerate_get_list_entry(e);
1177 udev_list_entry_foreach(item, first) {
1178 _cleanup_free_ char *t = NULL;
1181 p = udev_list_entry_get_name(item);
1183 t = strappend(p, "/uevent");
1187 write_string_file(t, "change");
1193 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1194 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1195 _cleanup_free_ char *rule = NULL, *file = NULL;
1196 const char *id_for_seat;
1203 d = udev_device_new_from_syspath(m->udev, sysfs);
1207 if (!udev_device_has_tag(d, "seat"))
1210 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1214 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1217 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1220 mkdir_p_label("/etc/udev/rules.d", 0755);
1221 mac_selinux_init("/etc");
1222 r = write_string_file_atomic_label(file, rule);
1226 return trigger_device(m, d);
1229 static int flush_devices(Manager *m) {
1230 _cleanup_closedir_ DIR *d;
1234 d = opendir("/etc/udev/rules.d");
1236 if (errno != ENOENT)
1237 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1241 while ((de = readdir(d))) {
1243 if (!dirent_is_file(de))
1246 if (!startswith(de->d_name, "72-seat-"))
1249 if (!endswith(de->d_name, ".rules"))
1252 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1253 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1257 return trigger_device(m, NULL);
1260 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261 const char *sysfs, *seat;
1262 Manager *m = userdata;
1268 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1272 if (!path_startswith(sysfs, "/sys"))
1273 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1275 if (!seat_name_is_valid(seat))
1276 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1278 r = bus_verify_polkit_async(
1281 "org.freedesktop.login1.attach-device",
1285 &m->polkit_registry,
1290 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1292 r = attach_device(m, seat, sysfs);
1296 return sd_bus_reply_method_return(message, NULL);
1299 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1300 Manager *m = userdata;
1306 r = sd_bus_message_read(message, "b", &interactive);
1310 r = bus_verify_polkit_async(
1313 "org.freedesktop.login1.flush-devices",
1317 &m->polkit_registry,
1322 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1324 r = flush_devices(m);
1328 return sd_bus_reply_method_return(message, NULL);
1331 static int have_multiple_sessions(
1340 /* Check for other users' sessions. Greeter sessions do not
1341 * count, and non-login sessions do not count either. */
1342 HASHMAP_FOREACH(session, m->sessions, i)
1343 if (session->class == SESSION_USER &&
1344 session->user->uid != uid)
1350 static int bus_manager_log_shutdown(
1353 HandleAction action) {
1359 if (w != INHIBIT_SHUTDOWN)
1363 case HANDLE_POWEROFF:
1364 p = "MESSAGE=System is powering down.";
1365 q = "SHUTDOWN=power-off";
1368 p = "MESSAGE=System is halting.";
1369 q = "SHUTDOWN=halt";
1372 p = "MESSAGE=System is rebooting.";
1373 q = "SHUTDOWN=reboot";
1376 p = "MESSAGE=System is rebooting with kexec.";
1377 q = "SHUTDOWN=kexec";
1380 p = "MESSAGE=System is shutting down.";
1384 if (!isempty(m->wall_message))
1385 p = strjoina(p, " (", m->wall_message, ")");
1387 return log_struct(LOG_NOTICE,
1388 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1394 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1395 Manager *m = userdata;
1400 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1404 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1409 if (until <= now(CLOCK_MONOTONIC))
1412 /* We want to ignore the lid switch for a while after each
1413 * suspend, and after boot-up. Hence let's install a timer for
1414 * this. As long as the event source exists we ignore the lid
1417 if (m->lid_switch_ignore_event_source) {
1420 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1427 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1429 r = sd_event_add_time(
1431 &m->lid_switch_ignore_event_source,
1434 lid_switch_ignore_handler, m);
1439 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1441 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1442 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1443 [INHIBIT_SLEEP] = "PrepareForSleep"
1446 int active = _active;
1450 assert(w < _INHIBIT_WHAT_MAX);
1451 assert(signal_name[w]);
1453 return sd_bus_emit_signal(m->bus,
1454 "/org/freedesktop/login1",
1455 "org.freedesktop.login1.Manager",
1461 static int execute_shutdown_or_sleep(
1464 HandleAction action,
1465 sd_bus_error *error) {
1467 /// elogind does not need these, we do it ourselves
1469 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1477 assert(w < _INHIBIT_WHAT_MAX);
1479 bus_manager_log_shutdown(m, w, action);
1481 /// elogind does it directly without depending on systemd running the system
1483 r = sd_bus_call_method(
1485 "org.freedesktop.systemd1",
1486 "/org/freedesktop/systemd1",
1487 "org.freedesktop.systemd1.Manager",
1491 "ss", NULL, "replace-irreversibly");
1493 r = shutdown_or_sleep(m, action);
1498 /// elogind neither needs a dbus reply, nor supports systemd action jobs
1500 r = sd_bus_message_read(reply, "o", &p);
1508 m->action_unit = unit_name;
1509 free(m->action_job);
1514 if (w == INHIBIT_SLEEP)
1515 /* And we're back. */
1516 send_prepare_for(m, w, false);
1520 /* Make sure the lid switch is ignored for a while */
1521 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1526 static int manager_inhibit_timeout_handler(
1531 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1532 Inhibitor *offending = NULL;
1533 Manager *manager = userdata;
1537 assert(manager->inhibit_timeout_source == s);
1539 if (manager->action_what == 0)
1542 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1543 _cleanup_free_ char *comm = NULL, *u = NULL;
1545 (void) get_process_comm(offending->pid, &comm);
1546 u = uid_to_name(offending->uid);
1548 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1549 offending->uid, strna(u),
1550 offending->pid, strna(comm));
1553 /* Actually do the operation */
1554 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
1556 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1558 manager->pending_action = HANDLE_IGNORE;
1559 manager->action_what = 0;
1565 static int delay_shutdown_or_sleep(
1568 HandleAction action) {
1575 assert(w < _INHIBIT_WHAT_MAX);
1577 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1579 if (m->inhibit_timeout_source) {
1580 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1582 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1584 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1586 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1588 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1589 timeout_val, 0, manager_inhibit_timeout_handler, m);
1594 m->pending_action = action;
1600 int bus_manager_shutdown_or_sleep_now_or_later(
1602 HandleAction action,
1604 sd_bus_error *error) {
1611 assert(w <= _INHIBIT_WHAT_MAX);
1613 /* Tell everybody to prepare for shutdown/sleep */
1614 send_prepare_for(m, w, true);
1617 m->inhibit_delay_max > 0 &&
1618 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1621 /* Shutdown is delayed, keep in mind what we
1622 * want to do, and start a timeout */
1623 r = delay_shutdown_or_sleep(m, w, action);
1625 /* Shutdown is not delayed, execute it
1627 r = execute_shutdown_or_sleep(m, w, action, error);
1632 static int verify_shutdown_creds(
1634 sd_bus_message *message,
1638 const char *action_multiple_sessions,
1639 const char *action_ignore_inhibit,
1640 sd_bus_error *error) {
1642 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1643 bool multiple_sessions, blocked;
1650 assert(w <= _INHIBIT_WHAT_MAX);
1652 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1656 r = sd_bus_creds_get_euid(creds, &uid);
1660 r = have_multiple_sessions(m, uid);
1664 multiple_sessions = r > 0;
1665 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1667 if (multiple_sessions && action_multiple_sessions) {
1668 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, 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 */
1675 if (blocked && action_ignore_inhibit) {
1676 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1680 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1683 if (!multiple_sessions && !blocked && action) {
1684 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1688 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1694 static int method_do_shutdown_or_sleep(
1696 sd_bus_message *message,
1697 HandleAction sleep_action,
1700 const char *action_multiple_sessions,
1701 const char *action_ignore_inhibit,
1702 const char *sleep_verb,
1703 sd_bus_error *error) {
1710 assert(w <= _INHIBIT_WHAT_MAX);
1712 r = sd_bus_message_read(message, "b", &interactive);
1716 /* Don't allow multiple jobs being executed at the same time */
1718 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1721 r = can_sleep(sleep_verb);
1726 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1729 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1730 action_ignore_inhibit, error);
1734 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1738 return sd_bus_reply_method_return(message, NULL);
1741 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1742 Manager *m = userdata;
1744 return method_do_shutdown_or_sleep(
1748 "org.freedesktop.login1.power-off",
1749 "org.freedesktop.login1.power-off-multiple-sessions",
1750 "org.freedesktop.login1.power-off-ignore-inhibit",
1755 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1756 Manager *m = userdata;
1758 return method_do_shutdown_or_sleep(
1762 "org.freedesktop.login1.reboot",
1763 "org.freedesktop.login1.reboot-multiple-sessions",
1764 "org.freedesktop.login1.reboot-ignore-inhibit",
1769 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1770 Manager *m = userdata;
1772 return method_do_shutdown_or_sleep(
1776 "org.freedesktop.login1.suspend",
1777 "org.freedesktop.login1.suspend-multiple-sessions",
1778 "org.freedesktop.login1.suspend-ignore-inhibit",
1783 static int nologin_timeout_handler(
1788 Manager *m = userdata;
1791 log_info("Creating /run/nologin, blocking further logins...");
1793 r = write_string_file_atomic("/run/nologin", "System is going down.");
1795 log_error_errno(r, "Failed to create /run/nologin: %m");
1797 m->unlink_nologin = true;
1802 static int update_schedule_file(Manager *m) {
1803 _cleanup_free_ char *temp_path = NULL;
1804 _cleanup_fclose_ FILE *f = NULL;
1809 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1811 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1813 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1815 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1817 (void) fchmod(fileno(f), 0644);
1823 m->scheduled_shutdown_timeout,
1824 m->enable_wall_messages,
1825 m->scheduled_shutdown_type);
1827 if (!isempty(m->wall_message)) {
1828 _cleanup_free_ char *t;
1830 t = cescape(m->wall_message);
1836 fprintf(f, "WALL_MESSAGE=%s\n", t);
1839 r = fflush_and_check(f);
1843 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1851 (void) unlink(temp_path);
1852 (void) unlink("/run/systemd/shutdown/scheduled");
1854 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1857 static int manager_scheduled_shutdown_handler(
1862 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1863 Manager *m = userdata;
1864 HandleAction action;
1869 if (isempty(m->scheduled_shutdown_type))
1872 if (streq(m->scheduled_shutdown_type, "halt"))
1873 action = HANDLE_HALT;
1874 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1875 action = HANDLE_POWEROFF;
1877 action = HANDLE_REBOOT;
1879 r = execute_shutdown_or_sleep(m, 0, action, &error);
1881 return log_error_errno(r, "Unable to execute transition to %s: %m", m->scheduled_shutdown_type);
1886 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1887 Manager *m = userdata;
1888 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1889 const char *action_multiple_sessions = NULL;
1890 const char *action_ignore_inhibit = NULL;
1891 const char *action = NULL;
1899 r = sd_bus_message_read(message, "st", &type, &elapse);
1903 if (streq(type, "reboot")) {
1904 action = "org.freedesktop.login1.reboot";
1905 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1906 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1907 } else if (streq(type, "halt")) {
1908 action = "org.freedesktop.login1.halt";
1909 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1910 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1911 } else if (streq(type, "poweroff")) {
1912 action = "org.freedesktop.login1.poweroff";
1913 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1914 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1916 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1918 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1919 action, action_multiple_sessions, action_ignore_inhibit, error);
1923 if (m->scheduled_shutdown_timeout_source) {
1924 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1926 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1928 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1930 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1932 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1933 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1935 return log_error_errno(r, "sd_event_add_time() failed: %m");
1938 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1940 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1944 if (m->nologin_timeout_source) {
1945 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1947 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1949 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1951 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1953 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1954 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1956 return log_error_errno(r, "sd_event_add_time() failed: %m");
1959 m->scheduled_shutdown_timeout = elapse;
1961 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1965 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1966 (void) sd_bus_creds_get_tty(creds, &tty);
1968 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1970 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1975 r = manager_setup_wall_message_timer(m);
1979 if (!isempty(type)) {
1980 r = update_schedule_file(m);
1984 (void) unlink("/run/systemd/shutdown/scheduled");
1986 return sd_bus_reply_method_return(message, NULL);
1989 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1990 Manager *m = userdata;
1996 cancelled = m->scheduled_shutdown_type != NULL;
1998 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1999 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
2000 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
2001 free(m->scheduled_shutdown_type);
2002 m->scheduled_shutdown_type = NULL;
2003 m->scheduled_shutdown_timeout = 0;
2006 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2007 const char *tty = NULL;
2011 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2013 (void) sd_bus_creds_get_uid(creds, &uid);
2014 (void) sd_bus_creds_get_tty(creds, &tty);
2017 utmp_wall("The system shutdown has been cancelled",
2018 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2021 return sd_bus_reply_method_return(message, "b", cancelled);
2024 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2025 Manager *m = userdata;
2027 return method_do_shutdown_or_sleep(
2031 "org.freedesktop.login1.hibernate",
2032 "org.freedesktop.login1.hibernate-multiple-sessions",
2033 "org.freedesktop.login1.hibernate-ignore-inhibit",
2038 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2039 Manager *m = userdata;
2041 return method_do_shutdown_or_sleep(
2043 HANDLE_HYBRID_SLEEP,
2045 "org.freedesktop.login1.hibernate",
2046 "org.freedesktop.login1.hibernate-multiple-sessions",
2047 "org.freedesktop.login1.hibernate-ignore-inhibit",
2052 static int method_can_shutdown_or_sleep(
2054 sd_bus_message *message,
2057 const char *action_multiple_sessions,
2058 const char *action_ignore_inhibit,
2059 const char *sleep_verb,
2060 sd_bus_error *error) {
2062 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2063 bool multiple_sessions, challenge, blocked;
2064 const char *result = NULL;
2071 assert(w <= _INHIBIT_WHAT_MAX);
2073 assert(action_multiple_sessions);
2074 assert(action_ignore_inhibit);
2077 r = can_sleep(sleep_verb);
2081 return sd_bus_reply_method_return(message, "s", "na");
2084 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2088 r = sd_bus_creds_get_euid(creds, &uid);
2092 r = have_multiple_sessions(m, uid);
2096 multiple_sessions = r > 0;
2097 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2099 if (multiple_sessions) {
2100 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2107 result = "challenge";
2113 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2117 if (r > 0 && !result)
2119 else if (challenge && (!result || streq(result, "yes")))
2120 result = "challenge";
2125 if (!multiple_sessions && !blocked) {
2126 /* If neither inhibit nor multiple sessions
2127 * apply then just check the normal policy */
2129 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2136 result = "challenge";
2141 return sd_bus_reply_method_return(message, "s", result);
2144 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2145 Manager *m = userdata;
2147 return method_can_shutdown_or_sleep(
2150 "org.freedesktop.login1.power-off",
2151 "org.freedesktop.login1.power-off-multiple-sessions",
2152 "org.freedesktop.login1.power-off-ignore-inhibit",
2157 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2158 Manager *m = userdata;
2160 return method_can_shutdown_or_sleep(
2163 "org.freedesktop.login1.reboot",
2164 "org.freedesktop.login1.reboot-multiple-sessions",
2165 "org.freedesktop.login1.reboot-ignore-inhibit",
2170 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2171 Manager *m = userdata;
2173 return method_can_shutdown_or_sleep(
2176 "org.freedesktop.login1.suspend",
2177 "org.freedesktop.login1.suspend-multiple-sessions",
2178 "org.freedesktop.login1.suspend-ignore-inhibit",
2183 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2184 Manager *m = userdata;
2186 return method_can_shutdown_or_sleep(
2189 "org.freedesktop.login1.hibernate",
2190 "org.freedesktop.login1.hibernate-multiple-sessions",
2191 "org.freedesktop.login1.hibernate-ignore-inhibit",
2196 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2197 Manager *m = userdata;
2199 return method_can_shutdown_or_sleep(
2202 "org.freedesktop.login1.hibernate",
2203 "org.freedesktop.login1.hibernate-multiple-sessions",
2204 "org.freedesktop.login1.hibernate-ignore-inhibit",
2209 static int property_get_reboot_to_firmware_setup(
2212 const char *interface,
2213 const char *property,
2214 sd_bus_message *reply,
2216 sd_bus_error *error) {
2223 r = efi_get_reboot_to_firmware();
2224 if (r < 0 && r != -EOPNOTSUPP)
2227 return sd_bus_message_append(reply, "b", r > 0);
2230 static int method_set_reboot_to_firmware_setup(
2231 sd_bus_message *message,
2233 sd_bus_error *error) {
2236 Manager *m = userdata;
2241 r = sd_bus_message_read(message, "b", &b);
2245 r = bus_verify_polkit_async(message,
2247 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2251 &m->polkit_registry,
2256 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2258 r = efi_set_reboot_to_firmware(b);
2262 return sd_bus_reply_method_return(message, NULL);
2265 static int method_can_reboot_to_firmware_setup(
2266 sd_bus_message *message,
2268 sd_bus_error *error) {
2273 Manager *m = userdata;
2278 r = efi_reboot_to_firmware_supported();
2279 if (r == -EOPNOTSUPP)
2280 return sd_bus_reply_method_return(message, "s", "na");
2284 r = bus_test_polkit(message,
2286 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2297 result = "challenge";
2301 return sd_bus_reply_method_return(message, "s", result);
2304 static int method_set_wall_message(
2305 sd_bus_message *message,
2307 sd_bus_error *error) {
2310 Manager *m = userdata;
2312 int enable_wall_messages;
2317 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2321 r = bus_verify_polkit_async(message,
2323 "org.freedesktop.login1.set-wall-message",
2327 &m->polkit_registry,
2332 return 1; /* Will call us back */
2334 if (isempty(wall_message))
2335 m->wall_message = mfree(m->wall_message);
2337 r = free_and_strdup(&m->wall_message, wall_message);
2342 m->enable_wall_messages = enable_wall_messages;
2344 return sd_bus_reply_method_return(message, NULL);
2347 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2348 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2349 const char *who, *why, *what, *mode;
2350 _cleanup_free_ char *id = NULL;
2351 _cleanup_close_ int fifo_fd = -1;
2352 Manager *m = userdata;
2353 Inhibitor *i = NULL;
2363 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2367 w = inhibit_what_from_string(what);
2369 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2371 mm = inhibit_mode_from_string(mode);
2373 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2375 /* Delay is only supported for shutdown/sleep */
2376 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2377 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2379 /* Don't allow taking delay locks while we are already
2380 * executing the operation. We shouldn't create the impression
2381 * that the lock was successful if the machine is about to go
2382 * down/suspend any moment. */
2383 if (m->action_what & w)
2384 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2386 r = bus_verify_polkit_async(
2389 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2390 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2391 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2392 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2393 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2394 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2395 "org.freedesktop.login1.inhibit-handle-lid-switch",
2399 &m->polkit_registry,
2404 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2406 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2410 r = sd_bus_creds_get_euid(creds, &uid);
2414 r = sd_bus_creds_get_pid(creds, &pid);
2421 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2424 } while (hashmap_get(m->inhibitors, id));
2426 r = manager_add_inhibitor(m, id, &i);
2434 i->why = strdup(why);
2435 i->who = strdup(who);
2437 if (!i->why || !i->who) {
2442 fifo_fd = inhibitor_create_fifo(i);
2450 return sd_bus_reply_method_return(message, "h", fifo_fd);
2459 const sd_bus_vtable manager_vtable[] = {
2460 SD_BUS_VTABLE_START(0),
2462 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2463 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2465 // SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2466 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2467 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2468 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2469 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2470 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2471 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2472 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2473 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2474 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2475 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2476 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2477 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2478 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2479 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2480 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2481 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2482 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2483 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2484 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2485 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2486 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2488 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2490 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2491 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2498 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2499 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2500 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2501 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2502 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2503 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2504 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2505 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2506 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2507 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2508 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2509 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2510 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2511 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2512 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2513 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2514 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2515 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2516 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2517 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2518 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2519 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2520 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2521 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2522 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2523 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2524 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2525 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2526 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2527 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2528 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2530 SD_BUS_SIGNAL("SessionNew", "so", 0),
2531 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2532 SD_BUS_SIGNAL("UserNew", "uo", 0),
2533 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2534 SD_BUS_SIGNAL("SeatNew", "so", 0),
2535 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2536 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2537 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2542 /// UNNEEDED by elogind
2544 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2553 if (streq(result, "done"))
2554 r = session_send_create_reply(s, NULL);
2556 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2558 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2559 r = session_send_create_reply(s, &e);
2565 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2566 const char *path, *result, *unit;
2567 Manager *m = userdata;
2576 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2578 bus_log_parse_error(r);
2582 if (m->action_job && streq(m->action_job, path)) {
2583 log_info("Operation finished.");
2585 /* Tell people that they now may take a lock again */
2586 send_prepare_for(m, m->action_what, false);
2588 m->action_job = mfree(m->action_job);
2589 m->action_unit = NULL;
2594 session = hashmap_get(m->session_units, unit);
2597 if (streq_ptr(path, session->scope_job))
2598 session->scope_job = mfree(session->scope_job);
2600 session_jobs_reply(session, unit, result);
2602 session_save(session);
2603 session_add_to_gc_queue(session);
2606 user = hashmap_get(m->user_units, unit);
2609 if (streq_ptr(path, user->service_job))
2610 user->service_job = mfree(user->service_job);
2612 if (streq_ptr(path, user->slice_job))
2613 user->slice_job = mfree(user->slice_job);
2615 LIST_FOREACH(sessions_by_user, session, user->sessions)
2616 session_jobs_reply(session, unit, result);
2619 user_add_to_gc_queue(user);
2626 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627 const char *path, *unit;
2628 Manager *m = userdata;
2636 r = sd_bus_message_read(message, "so", &unit, &path);
2638 bus_log_parse_error(r);
2642 session = hashmap_get(m->session_units, unit);
2644 session_add_to_gc_queue(session);
2646 user = hashmap_get(m->user_units, unit);
2648 user_add_to_gc_queue(user);
2653 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2654 _cleanup_free_ char *unit = NULL;
2655 Manager *m = userdata;
2664 path = sd_bus_message_get_path(message);
2668 r = unit_name_from_dbus_path(path, &unit);
2669 if (r == -EINVAL) /* not a unit */
2676 session = hashmap_get(m->session_units, unit);
2678 session_add_to_gc_queue(session);
2680 user = hashmap_get(m->user_units, unit);
2682 user_add_to_gc_queue(user);
2687 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2688 Manager *m = userdata;
2696 r = sd_bus_message_read(message, "b", &b);
2698 bus_log_parse_error(r);
2705 /* systemd finished reloading, let's recheck all our sessions */
2706 log_debug("System manager has been reloaded, rechecking sessions...");
2708 HASHMAP_FOREACH(session, m->sessions, i)
2709 session_add_to_gc_queue(session);
2714 int manager_send_changed(Manager *manager, const char *property, ...) {
2719 l = strv_from_stdarg_alloca(property);
2721 return sd_bus_emit_properties_changed_strv(
2723 "/org/freedesktop/login1",
2724 "org.freedesktop.login1.Manager",
2728 /// UNNEEDED by elogind
2730 int manager_start_scope(
2735 const char *description,
2736 const char *after, const char *after2,
2737 sd_bus_error *error,
2740 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2747 r = sd_bus_message_new_method_call(
2750 "org.freedesktop.systemd1",
2751 "/org/freedesktop/systemd1",
2752 "org.freedesktop.systemd1.Manager",
2753 "StartTransientUnit");
2757 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2761 r = sd_bus_message_open_container(m, 'a', "(sv)");
2765 if (!isempty(slice)) {
2766 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2771 if (!isempty(description)) {
2772 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2777 if (!isempty(after)) {
2778 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2783 if (!isempty(after2)) {
2784 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2789 /* cgroup empty notification is not available in containers
2790 * currently. To make this less problematic, let's shorten the
2791 * stop timeout for sessions, so that we don't wait
2794 /* Make sure that the session shells are terminated with
2795 * SIGHUP since bash and friends tend to ignore SIGTERM */
2796 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2800 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2804 r = sd_bus_message_close_container(m);
2808 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2812 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2820 r = sd_bus_message_read(reply, "o", &j);
2834 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2835 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2841 r = sd_bus_call_method(
2843 "org.freedesktop.systemd1",
2844 "/org/freedesktop/systemd1",
2845 "org.freedesktop.systemd1.Manager",
2849 "ss", unit, "fail");
2857 r = sd_bus_message_read(reply, "o", &j);
2871 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2872 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2878 r = sd_bus_call_method(
2880 "org.freedesktop.systemd1",
2881 "/org/freedesktop/systemd1",
2882 "org.freedesktop.systemd1.Manager",
2886 "ss", unit, "fail");
2888 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2889 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2894 sd_bus_error_free(error);
2905 r = sd_bus_message_read(reply, "o", &j);
2919 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2920 _cleanup_free_ char *path = NULL;
2926 path = unit_dbus_path_from_name(scope);
2930 r = sd_bus_call_method(
2932 "org.freedesktop.systemd1",
2934 "org.freedesktop.systemd1.Scope",
2940 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2941 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2942 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2943 sd_bus_error_free(error);
2953 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2957 return sd_bus_call_method(
2959 "org.freedesktop.systemd1",
2960 "/org/freedesktop/systemd1",
2961 "org.freedesktop.systemd1.Manager",
2965 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2968 int manager_unit_is_active(Manager *manager, const char *unit) {
2969 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2970 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2971 _cleanup_free_ char *path = NULL;
2978 path = unit_dbus_path_from_name(unit);
2982 r = sd_bus_get_property(
2984 "org.freedesktop.systemd1",
2986 "org.freedesktop.systemd1.Unit",
2992 /* systemd might have droppped off momentarily, let's
2993 * not make this an error */
2994 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2995 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2998 /* If the unit is already unloaded then it's not
3000 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
3001 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
3007 r = sd_bus_message_read(reply, "s", &state);
3011 return !streq(state, "inactive") && !streq(state, "failed");
3014 int manager_job_is_active(Manager *manager, const char *path) {
3015 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3016 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3022 r = sd_bus_get_property(
3024 "org.freedesktop.systemd1",
3026 "org.freedesktop.systemd1.Job",
3032 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3033 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3036 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3042 /* We don't actually care about the state really. The fact
3043 * that we could read the job state is enough for us */