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 /* 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 return sd_bus_reply_method_return(message, NULL);
866 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
867 Manager *m = userdata;
875 r = sd_bus_message_read(message, "s", &name);
879 r = manager_get_session_from_creds(m, message, name, error, &session);
883 return bus_session_method_activate(message, session, error);
886 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
887 const char *session_name, *seat_name;
888 Manager *m = userdata;
896 /* Same as ActivateSession() but refuses to work if
897 * the seat doesn't match */
899 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
903 r = manager_get_session_from_creds(m, message, session_name, error, &session);
907 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
911 if (session->seat != seat)
912 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
914 r = session_activate(session);
918 return sd_bus_reply_method_return(message, NULL);
921 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
922 Manager *m = userdata;
930 r = sd_bus_message_read(message, "s", &name);
934 r = manager_get_session_from_creds(m, message, name, error, &session);
938 return bus_session_method_lock(message, session, error);
941 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
942 Manager *m = userdata;
948 r = bus_verify_polkit_async(
951 "org.freedesktop.login1.lock-sessions",
960 return 1; /* Will call us back */
962 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
966 return sd_bus_reply_method_return(message, NULL);
969 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
971 Manager *m = userdata;
978 r = sd_bus_message_read(message, "s", &name);
982 r = manager_get_session_from_creds(m, message, name, error, &session);
986 return bus_session_method_kill(message, session, error);
989 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
990 Manager *m = userdata;
998 r = sd_bus_message_read(message, "u", &uid);
1002 r = manager_get_user_from_creds(m, message, uid, error, &user);
1006 return bus_user_method_kill(message, user, error);
1009 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1010 Manager *m = userdata;
1018 r = sd_bus_message_read(message, "s", &name);
1022 r = manager_get_session_from_creds(m, message, name, error, &session);
1026 return bus_session_method_terminate(message, session, error);
1029 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1030 Manager *m = userdata;
1038 r = sd_bus_message_read(message, "u", &uid);
1042 r = manager_get_user_from_creds(m, message, uid, error, &user);
1046 return bus_user_method_terminate(message, user, error);
1049 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1050 Manager *m = userdata;
1058 r = sd_bus_message_read(message, "s", &name);
1062 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1066 return bus_seat_method_terminate(message, seat, error);
1069 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1070 _cleanup_free_ char *cc = NULL;
1071 Manager *m = userdata;
1081 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1085 if (uid == UID_INVALID) {
1086 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1088 /* Note that we get the owner UID of the session, not the actual client UID here! */
1089 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1093 r = sd_bus_creds_get_owner_uid(creds, &uid);
1101 return errno ? -errno : -ENOENT;
1103 r = bus_verify_polkit_async(
1106 "org.freedesktop.login1.set-user-linger",
1110 &m->polkit_registry,
1115 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1117 mkdir_p_label("/var/lib/systemd", 0755);
1119 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1123 cc = cescape(pw->pw_name);
1127 path = strjoina("/var/lib/systemd/linger/", cc);
1135 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1142 if (r < 0 && errno != ENOENT)
1145 u = hashmap_get(m->users, UID_TO_PTR(uid));
1147 user_add_to_gc_queue(u);
1150 return sd_bus_reply_method_return(message, NULL);
1153 static int trigger_device(Manager *m, struct udev_device *d) {
1154 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1155 struct udev_list_entry *first, *item;
1160 e = udev_enumerate_new(m->udev);
1165 r = udev_enumerate_add_match_parent(e, d);
1170 r = udev_enumerate_scan_devices(e);
1174 first = udev_enumerate_get_list_entry(e);
1175 udev_list_entry_foreach(item, first) {
1176 _cleanup_free_ char *t = NULL;
1179 p = udev_list_entry_get_name(item);
1181 t = strappend(p, "/uevent");
1185 write_string_file(t, "change");
1191 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1192 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1193 _cleanup_free_ char *rule = NULL, *file = NULL;
1194 const char *id_for_seat;
1201 d = udev_device_new_from_syspath(m->udev, sysfs);
1205 if (!udev_device_has_tag(d, "seat"))
1208 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1212 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1215 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1218 mkdir_p_label("/etc/udev/rules.d", 0755);
1219 mac_selinux_init("/etc");
1220 r = write_string_file_atomic_label(file, rule);
1224 return trigger_device(m, d);
1227 static int flush_devices(Manager *m) {
1228 _cleanup_closedir_ DIR *d;
1232 d = opendir("/etc/udev/rules.d");
1234 if (errno != ENOENT)
1235 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1239 while ((de = readdir(d))) {
1241 if (!dirent_is_file(de))
1244 if (!startswith(de->d_name, "72-seat-"))
1247 if (!endswith(de->d_name, ".rules"))
1250 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1251 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1255 return trigger_device(m, NULL);
1258 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1259 const char *sysfs, *seat;
1260 Manager *m = userdata;
1266 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1270 if (!path_startswith(sysfs, "/sys"))
1271 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1273 if (!seat_name_is_valid(seat))
1274 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1276 r = bus_verify_polkit_async(
1279 "org.freedesktop.login1.attach-device",
1283 &m->polkit_registry,
1288 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1290 r = attach_device(m, seat, sysfs);
1294 return sd_bus_reply_method_return(message, NULL);
1297 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1298 Manager *m = userdata;
1304 r = sd_bus_message_read(message, "b", &interactive);
1308 r = bus_verify_polkit_async(
1311 "org.freedesktop.login1.flush-devices",
1315 &m->polkit_registry,
1320 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1322 r = flush_devices(m);
1326 return sd_bus_reply_method_return(message, NULL);
1329 static int have_multiple_sessions(
1338 /* Check for other users' sessions. Greeter sessions do not
1339 * count, and non-login sessions do not count either. */
1340 HASHMAP_FOREACH(session, m->sessions, i)
1341 if (session->class == SESSION_USER &&
1342 session->user->uid != uid)
1348 static int bus_manager_log_shutdown(
1351 HandleAction action) {
1357 if (w != INHIBIT_SHUTDOWN)
1361 case HANDLE_POWEROFF:
1362 p = "MESSAGE=System is powering down.";
1363 q = "SHUTDOWN=power-off";
1366 p = "MESSAGE=System is halting.";
1367 q = "SHUTDOWN=halt";
1370 p = "MESSAGE=System is rebooting.";
1371 q = "SHUTDOWN=reboot";
1374 p = "MESSAGE=System is rebooting with kexec.";
1375 q = "SHUTDOWN=kexec";
1378 p = "MESSAGE=System is shutting down.";
1382 if (!isempty(m->wall_message))
1383 p = strjoina(p, " (", m->wall_message, ")");
1385 return log_struct(LOG_NOTICE,
1386 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1392 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1393 Manager *m = userdata;
1398 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1402 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1407 if (until <= now(CLOCK_MONOTONIC))
1410 /* We want to ignore the lid switch for a while after each
1411 * suspend, and after boot-up. Hence let's install a timer for
1412 * this. As long as the event source exists we ignore the lid
1415 if (m->lid_switch_ignore_event_source) {
1418 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1425 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1427 r = sd_event_add_time(
1429 &m->lid_switch_ignore_event_source,
1432 lid_switch_ignore_handler, m);
1437 static int execute_shutdown_or_sleep(
1440 HandleAction action,
1441 sd_bus_error *error) {
1443 /// elogind does not need these, we do it ourselves
1445 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1453 assert(w < _INHIBIT_WHAT_MAX);
1455 bus_manager_log_shutdown(m, w, action);
1457 /// elogind does it directly without depending on systemd running the system
1459 r = sd_bus_call_method(
1461 "org.freedesktop.systemd1",
1462 "/org/freedesktop/systemd1",
1463 "org.freedesktop.systemd1.Manager",
1467 "ss", NULL, "replace-irreversibly");
1469 r = shutdown_or_sleep(m, action);
1474 /// elogind neither needs a dbus reply, nor supports systemd action jobs
1476 r = sd_bus_message_read(reply, "o", &p);
1484 m->action_unit = unit_name;
1485 free(m->action_job);
1490 /* Make sure the lid switch is ignored for a while */
1491 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1496 static int manager_inhibit_timeout_handler(
1501 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1502 Inhibitor *offending = NULL;
1503 Manager *manager = userdata;
1507 assert(manager->inhibit_timeout_source == s);
1509 if (manager->action_what == 0)
1512 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1513 _cleanup_free_ char *comm = NULL, *u = NULL;
1515 (void) get_process_comm(offending->pid, &comm);
1516 u = uid_to_name(offending->uid);
1518 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1519 offending->uid, strna(u),
1520 offending->pid, strna(comm));
1523 /* Actually do the operation */
1524 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
1526 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1528 manager->pending_action = HANDLE_IGNORE;
1529 manager->action_what = 0;
1535 static int delay_shutdown_or_sleep(
1538 HandleAction action) {
1545 assert(w < _INHIBIT_WHAT_MAX);
1547 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1549 if (m->inhibit_timeout_source) {
1550 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1552 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1554 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1556 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1558 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1559 timeout_val, 0, manager_inhibit_timeout_handler, m);
1564 m->pending_action = action;
1570 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1572 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1573 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1574 [INHIBIT_SLEEP] = "PrepareForSleep"
1577 int active = _active;
1581 assert(w < _INHIBIT_WHAT_MAX);
1582 assert(signal_name[w]);
1584 return sd_bus_emit_signal(m->bus,
1585 "/org/freedesktop/login1",
1586 "org.freedesktop.login1.Manager",
1592 int bus_manager_shutdown_or_sleep_now_or_later(
1594 HandleAction action,
1596 sd_bus_error *error) {
1603 assert(w <= _INHIBIT_WHAT_MAX);
1605 /* Tell everybody to prepare for shutdown/sleep */
1606 send_prepare_for(m, w, true);
1609 m->inhibit_delay_max > 0 &&
1610 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1613 /* Shutdown is delayed, keep in mind what we
1614 * want to do, and start a timeout */
1615 r = delay_shutdown_or_sleep(m, w, action);
1617 /* Shutdown is not delayed, execute it
1619 r = execute_shutdown_or_sleep(m, w, action, error);
1624 static int verify_shutdown_creds(
1626 sd_bus_message *message,
1630 const char *action_multiple_sessions,
1631 const char *action_ignore_inhibit,
1632 sd_bus_error *error) {
1634 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1635 bool multiple_sessions, blocked;
1642 assert(w <= _INHIBIT_WHAT_MAX);
1644 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1648 r = sd_bus_creds_get_euid(creds, &uid);
1652 r = have_multiple_sessions(m, uid);
1656 multiple_sessions = r > 0;
1657 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1659 if (multiple_sessions && action_multiple_sessions) {
1660 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1664 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1667 if (blocked && action_ignore_inhibit) {
1668 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, 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 (!multiple_sessions && !blocked && action) {
1676 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, 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 */
1686 static int method_do_shutdown_or_sleep(
1688 sd_bus_message *message,
1689 HandleAction sleep_action,
1692 const char *action_multiple_sessions,
1693 const char *action_ignore_inhibit,
1694 const char *sleep_verb,
1695 sd_bus_error *error) {
1702 assert(w <= _INHIBIT_WHAT_MAX);
1704 r = sd_bus_message_read(message, "b", &interactive);
1708 /* Don't allow multiple jobs being executed at the same time */
1710 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1713 r = can_sleep(sleep_verb);
1718 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1721 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1722 action_ignore_inhibit, error);
1726 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1730 return sd_bus_reply_method_return(message, NULL);
1733 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1734 Manager *m = userdata;
1736 return method_do_shutdown_or_sleep(
1740 "org.freedesktop.login1.power-off",
1741 "org.freedesktop.login1.power-off-multiple-sessions",
1742 "org.freedesktop.login1.power-off-ignore-inhibit",
1747 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1748 Manager *m = userdata;
1750 return method_do_shutdown_or_sleep(
1754 "org.freedesktop.login1.reboot",
1755 "org.freedesktop.login1.reboot-multiple-sessions",
1756 "org.freedesktop.login1.reboot-ignore-inhibit",
1761 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1762 Manager *m = userdata;
1764 return method_do_shutdown_or_sleep(
1768 "org.freedesktop.login1.suspend",
1769 "org.freedesktop.login1.suspend-multiple-sessions",
1770 "org.freedesktop.login1.suspend-ignore-inhibit",
1775 static int nologin_timeout_handler(
1780 Manager *m = userdata;
1783 log_info("Creating /run/nologin, blocking further logins...");
1785 r = write_string_file_atomic("/run/nologin", "System is going down.");
1787 log_error_errno(r, "Failed to create /run/nologin: %m");
1789 m->unlink_nologin = true;
1794 static int update_schedule_file(Manager *m) {
1795 _cleanup_free_ char *temp_path = NULL;
1796 _cleanup_fclose_ FILE *f = NULL;
1801 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1803 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1805 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1807 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1809 (void) fchmod(fileno(f), 0644);
1815 m->scheduled_shutdown_timeout,
1816 m->enable_wall_messages,
1817 m->scheduled_shutdown_type);
1819 if (!isempty(m->wall_message)) {
1820 _cleanup_free_ char *t;
1822 t = cescape(m->wall_message);
1828 fprintf(f, "WALL_MESSAGE=%s\n", t);
1831 r = fflush_and_check(f);
1835 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1843 (void) unlink(temp_path);
1844 (void) unlink("/run/systemd/shutdown/scheduled");
1846 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1849 static int manager_scheduled_shutdown_handler(
1854 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1855 Manager *m = userdata;
1856 HandleAction action;
1861 if (isempty(m->scheduled_shutdown_type))
1864 if (streq(m->scheduled_shutdown_type, "halt"))
1865 action = HANDLE_HALT;
1866 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1867 action = HANDLE_POWEROFF;
1869 action = HANDLE_REBOOT;
1871 r = execute_shutdown_or_sleep(m, 0, action, &error);
1873 return log_error_errno(r, "Unable to execute transition to %s: %m", m->scheduled_shutdown_type);
1878 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1879 Manager *m = userdata;
1880 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1881 const char *action_multiple_sessions = NULL;
1882 const char *action_ignore_inhibit = NULL;
1883 const char *action = NULL;
1891 r = sd_bus_message_read(message, "st", &type, &elapse);
1895 if (streq(type, "reboot")) {
1896 action = "org.freedesktop.login1.reboot";
1897 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1898 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1899 } else if (streq(type, "halt")) {
1900 action = "org.freedesktop.login1.halt";
1901 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1902 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1903 } else if (streq(type, "poweroff")) {
1904 action = "org.freedesktop.login1.poweroff";
1905 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1906 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1908 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1910 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1911 action, action_multiple_sessions, action_ignore_inhibit, error);
1915 if (m->scheduled_shutdown_timeout_source) {
1916 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1918 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1920 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1922 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1924 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1925 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1927 return log_error_errno(r, "sd_event_add_time() failed: %m");
1930 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1932 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1936 if (m->nologin_timeout_source) {
1937 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1939 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1941 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1943 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1945 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1946 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1948 return log_error_errno(r, "sd_event_add_time() failed: %m");
1951 m->scheduled_shutdown_timeout = elapse;
1953 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1957 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1958 (void) sd_bus_creds_get_tty(creds, &tty);
1960 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1962 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1967 r = manager_setup_wall_message_timer(m);
1971 if (!isempty(type)) {
1972 r = update_schedule_file(m);
1976 (void) unlink("/run/systemd/shutdown/scheduled");
1978 return sd_bus_reply_method_return(message, NULL);
1981 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1982 Manager *m = userdata;
1988 cancelled = m->scheduled_shutdown_type != NULL;
1990 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1991 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1992 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1993 free(m->scheduled_shutdown_type);
1994 m->scheduled_shutdown_type = NULL;
1995 m->scheduled_shutdown_timeout = 0;
1998 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1999 const char *tty = NULL;
2003 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2005 (void) sd_bus_creds_get_uid(creds, &uid);
2006 (void) sd_bus_creds_get_tty(creds, &tty);
2009 utmp_wall("The system shutdown has been cancelled",
2010 lookup_uid(uid), tty, logind_wall_tty_filter, m);
2013 return sd_bus_reply_method_return(message, "b", cancelled);
2016 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2017 Manager *m = userdata;
2019 return method_do_shutdown_or_sleep(
2023 "org.freedesktop.login1.hibernate",
2024 "org.freedesktop.login1.hibernate-multiple-sessions",
2025 "org.freedesktop.login1.hibernate-ignore-inhibit",
2030 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2031 Manager *m = userdata;
2033 return method_do_shutdown_or_sleep(
2035 HANDLE_HYBRID_SLEEP,
2037 "org.freedesktop.login1.hibernate",
2038 "org.freedesktop.login1.hibernate-multiple-sessions",
2039 "org.freedesktop.login1.hibernate-ignore-inhibit",
2044 static int method_can_shutdown_or_sleep(
2046 sd_bus_message *message,
2049 const char *action_multiple_sessions,
2050 const char *action_ignore_inhibit,
2051 const char *sleep_verb,
2052 sd_bus_error *error) {
2054 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2055 bool multiple_sessions, challenge, blocked;
2056 const char *result = NULL;
2063 assert(w <= _INHIBIT_WHAT_MAX);
2065 assert(action_multiple_sessions);
2066 assert(action_ignore_inhibit);
2069 r = can_sleep(sleep_verb);
2073 return sd_bus_reply_method_return(message, "s", "na");
2076 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2080 r = sd_bus_creds_get_euid(creds, &uid);
2084 r = have_multiple_sessions(m, uid);
2088 multiple_sessions = r > 0;
2089 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2091 if (multiple_sessions) {
2092 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2099 result = "challenge";
2105 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2109 if (r > 0 && !result)
2111 else if (challenge && (!result || streq(result, "yes")))
2112 result = "challenge";
2117 if (!multiple_sessions && !blocked) {
2118 /* If neither inhibit nor multiple sessions
2119 * apply then just check the normal policy */
2121 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2128 result = "challenge";
2133 return sd_bus_reply_method_return(message, "s", result);
2136 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2137 Manager *m = userdata;
2139 return method_can_shutdown_or_sleep(
2142 "org.freedesktop.login1.power-off",
2143 "org.freedesktop.login1.power-off-multiple-sessions",
2144 "org.freedesktop.login1.power-off-ignore-inhibit",
2149 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2150 Manager *m = userdata;
2152 return method_can_shutdown_or_sleep(
2155 "org.freedesktop.login1.reboot",
2156 "org.freedesktop.login1.reboot-multiple-sessions",
2157 "org.freedesktop.login1.reboot-ignore-inhibit",
2162 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2163 Manager *m = userdata;
2165 return method_can_shutdown_or_sleep(
2168 "org.freedesktop.login1.suspend",
2169 "org.freedesktop.login1.suspend-multiple-sessions",
2170 "org.freedesktop.login1.suspend-ignore-inhibit",
2175 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2176 Manager *m = userdata;
2178 return method_can_shutdown_or_sleep(
2181 "org.freedesktop.login1.hibernate",
2182 "org.freedesktop.login1.hibernate-multiple-sessions",
2183 "org.freedesktop.login1.hibernate-ignore-inhibit",
2188 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2189 Manager *m = userdata;
2191 return method_can_shutdown_or_sleep(
2194 "org.freedesktop.login1.hibernate",
2195 "org.freedesktop.login1.hibernate-multiple-sessions",
2196 "org.freedesktop.login1.hibernate-ignore-inhibit",
2201 static int property_get_reboot_to_firmware_setup(
2204 const char *interface,
2205 const char *property,
2206 sd_bus_message *reply,
2208 sd_bus_error *error) {
2215 r = efi_get_reboot_to_firmware();
2216 if (r < 0 && r != -EOPNOTSUPP)
2219 return sd_bus_message_append(reply, "b", r > 0);
2222 static int method_set_reboot_to_firmware_setup(
2223 sd_bus_message *message,
2225 sd_bus_error *error) {
2228 Manager *m = userdata;
2233 r = sd_bus_message_read(message, "b", &b);
2237 r = bus_verify_polkit_async(message,
2239 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2243 &m->polkit_registry,
2248 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2250 r = efi_set_reboot_to_firmware(b);
2254 return sd_bus_reply_method_return(message, NULL);
2257 static int method_can_reboot_to_firmware_setup(
2258 sd_bus_message *message,
2260 sd_bus_error *error) {
2265 Manager *m = userdata;
2270 r = efi_reboot_to_firmware_supported();
2271 if (r == -EOPNOTSUPP)
2272 return sd_bus_reply_method_return(message, "s", "na");
2276 r = bus_test_polkit(message,
2278 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2289 result = "challenge";
2293 return sd_bus_reply_method_return(message, "s", result);
2296 static int method_set_wall_message(
2297 sd_bus_message *message,
2299 sd_bus_error *error) {
2302 Manager *m = userdata;
2304 int enable_wall_messages;
2309 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2313 r = bus_verify_polkit_async(message,
2315 "org.freedesktop.login1.set-wall-message",
2319 &m->polkit_registry,
2324 return 1; /* Will call us back */
2326 if (isempty(wall_message))
2327 m->wall_message = mfree(m->wall_message);
2329 r = free_and_strdup(&m->wall_message, wall_message);
2334 m->enable_wall_messages = enable_wall_messages;
2336 return sd_bus_reply_method_return(message, NULL);
2339 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2340 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2341 const char *who, *why, *what, *mode;
2342 _cleanup_free_ char *id = NULL;
2343 _cleanup_close_ int fifo_fd = -1;
2344 Manager *m = userdata;
2345 Inhibitor *i = NULL;
2355 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2359 w = inhibit_what_from_string(what);
2361 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2363 mm = inhibit_mode_from_string(mode);
2365 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2367 /* Delay is only supported for shutdown/sleep */
2368 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2369 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2371 /* Don't allow taking delay locks while we are already
2372 * executing the operation. We shouldn't create the impression
2373 * that the lock was successful if the machine is about to go
2374 * down/suspend any moment. */
2375 if (m->action_what & w)
2376 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2378 r = bus_verify_polkit_async(
2381 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2382 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2383 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2384 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2385 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2386 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2387 "org.freedesktop.login1.inhibit-handle-lid-switch",
2391 &m->polkit_registry,
2396 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2398 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2402 r = sd_bus_creds_get_euid(creds, &uid);
2406 r = sd_bus_creds_get_pid(creds, &pid);
2413 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2416 } while (hashmap_get(m->inhibitors, id));
2418 r = manager_add_inhibitor(m, id, &i);
2426 i->why = strdup(why);
2427 i->who = strdup(who);
2429 if (!i->why || !i->who) {
2434 fifo_fd = inhibitor_create_fifo(i);
2442 return sd_bus_reply_method_return(message, "h", fifo_fd);
2451 const sd_bus_vtable manager_vtable[] = {
2452 SD_BUS_VTABLE_START(0),
2454 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2455 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2457 // SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2458 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2459 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2460 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2461 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2462 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2463 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2464 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2465 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2466 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2467 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2468 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2469 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2470 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2471 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2472 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2473 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2474 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2475 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2476 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2477 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2478 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2480 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2483 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2485 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2487 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2488 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2490 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2491 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2498 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2499 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2500 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2501 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2502 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2503 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2504 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2505 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2506 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2507 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2508 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2509 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2510 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2511 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2512 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2513 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2514 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2515 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2516 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2517 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2518 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2519 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2520 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2522 SD_BUS_SIGNAL("SessionNew", "so", 0),
2523 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2524 SD_BUS_SIGNAL("UserNew", "uo", 0),
2525 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2526 SD_BUS_SIGNAL("SeatNew", "so", 0),
2527 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2528 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2529 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2534 /// UNNEEDED by elogind
2536 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2545 if (streq(result, "done"))
2546 r = session_send_create_reply(s, NULL);
2548 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2550 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2551 r = session_send_create_reply(s, &e);
2557 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2558 const char *path, *result, *unit;
2559 Manager *m = userdata;
2568 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2570 bus_log_parse_error(r);
2574 if (m->action_job && streq(m->action_job, path)) {
2575 log_info("Operation finished.");
2577 /* Tell people that they now may take a lock again */
2578 send_prepare_for(m, m->action_what, false);
2580 m->action_job = mfree(m->action_job);
2581 m->action_unit = NULL;
2586 session = hashmap_get(m->session_units, unit);
2589 if (streq_ptr(path, session->scope_job))
2590 session->scope_job = mfree(session->scope_job);
2592 session_jobs_reply(session, unit, result);
2594 session_save(session);
2595 session_add_to_gc_queue(session);
2598 user = hashmap_get(m->user_units, unit);
2601 if (streq_ptr(path, user->service_job))
2602 user->service_job = mfree(user->service_job);
2604 if (streq_ptr(path, user->slice_job))
2605 user->slice_job = mfree(user->slice_job);
2607 LIST_FOREACH(sessions_by_user, session, user->sessions)
2608 session_jobs_reply(session, unit, result);
2611 user_add_to_gc_queue(user);
2618 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2619 const char *path, *unit;
2620 Manager *m = userdata;
2628 r = sd_bus_message_read(message, "so", &unit, &path);
2630 bus_log_parse_error(r);
2634 session = hashmap_get(m->session_units, unit);
2636 session_add_to_gc_queue(session);
2638 user = hashmap_get(m->user_units, unit);
2640 user_add_to_gc_queue(user);
2645 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2646 _cleanup_free_ char *unit = NULL;
2647 Manager *m = userdata;
2656 path = sd_bus_message_get_path(message);
2660 r = unit_name_from_dbus_path(path, &unit);
2661 if (r == -EINVAL) /* not a unit */
2668 session = hashmap_get(m->session_units, unit);
2670 session_add_to_gc_queue(session);
2672 user = hashmap_get(m->user_units, unit);
2674 user_add_to_gc_queue(user);
2679 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2680 Manager *m = userdata;
2688 r = sd_bus_message_read(message, "b", &b);
2690 bus_log_parse_error(r);
2697 /* systemd finished reloading, let's recheck all our sessions */
2698 log_debug("System manager has been reloaded, rechecking sessions...");
2700 HASHMAP_FOREACH(session, m->sessions, i)
2701 session_add_to_gc_queue(session);
2706 int manager_send_changed(Manager *manager, const char *property, ...) {
2711 l = strv_from_stdarg_alloca(property);
2713 return sd_bus_emit_properties_changed_strv(
2715 "/org/freedesktop/login1",
2716 "org.freedesktop.login1.Manager",
2720 /// UNNEEDED by elogind
2722 int manager_start_scope(
2727 const char *description,
2728 const char *after, const char *after2,
2729 sd_bus_error *error,
2732 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2739 r = sd_bus_message_new_method_call(
2742 "org.freedesktop.systemd1",
2743 "/org/freedesktop/systemd1",
2744 "org.freedesktop.systemd1.Manager",
2745 "StartTransientUnit");
2749 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2753 r = sd_bus_message_open_container(m, 'a', "(sv)");
2757 if (!isempty(slice)) {
2758 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2763 if (!isempty(description)) {
2764 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2769 if (!isempty(after)) {
2770 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2775 if (!isempty(after2)) {
2776 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2781 /* cgroup empty notification is not available in containers
2782 * currently. To make this less problematic, let's shorten the
2783 * stop timeout for sessions, so that we don't wait
2786 /* Make sure that the session shells are terminated with
2787 * SIGHUP since bash and friends tend to ignore SIGTERM */
2788 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2792 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2796 r = sd_bus_message_close_container(m);
2800 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2804 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2812 r = sd_bus_message_read(reply, "o", &j);
2826 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2827 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2833 r = sd_bus_call_method(
2835 "org.freedesktop.systemd1",
2836 "/org/freedesktop/systemd1",
2837 "org.freedesktop.systemd1.Manager",
2841 "ss", unit, "fail");
2849 r = sd_bus_message_read(reply, "o", &j);
2863 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2864 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2870 r = sd_bus_call_method(
2872 "org.freedesktop.systemd1",
2873 "/org/freedesktop/systemd1",
2874 "org.freedesktop.systemd1.Manager",
2878 "ss", unit, "fail");
2880 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2881 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2886 sd_bus_error_free(error);
2897 r = sd_bus_message_read(reply, "o", &j);
2911 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2912 _cleanup_free_ char *path = NULL;
2918 path = unit_dbus_path_from_name(scope);
2922 r = sd_bus_call_method(
2924 "org.freedesktop.systemd1",
2926 "org.freedesktop.systemd1.Scope",
2932 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2933 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2934 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2935 sd_bus_error_free(error);
2945 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2949 return sd_bus_call_method(
2951 "org.freedesktop.systemd1",
2952 "/org/freedesktop/systemd1",
2953 "org.freedesktop.systemd1.Manager",
2957 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2960 int manager_unit_is_active(Manager *manager, const char *unit) {
2961 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2962 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2963 _cleanup_free_ char *path = NULL;
2970 path = unit_dbus_path_from_name(unit);
2974 r = sd_bus_get_property(
2976 "org.freedesktop.systemd1",
2978 "org.freedesktop.systemd1.Unit",
2984 /* systemd might have droppped off momentarily, let's
2985 * not make this an error */
2986 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2987 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2990 /* If the unit is already unloaded then it's not
2992 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2993 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2999 r = sd_bus_message_read(reply, "s", &state);
3003 return !streq(state, "inactive") && !streq(state, "failed");
3006 int manager_job_is_active(Manager *manager, const char *path) {
3007 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3008 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3014 r = sd_bus_get_property(
3016 "org.freedesktop.systemd1",
3018 "org.freedesktop.systemd1.Job",
3024 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3025 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3028 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3034 /* We don't actually care about the state really. The fact
3035 * that we could read the job state is enough for us */