1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
46 #include "utmp-wtmp.h"
48 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
49 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
58 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
62 r = sd_bus_creds_get_session(creds, &name);
67 session = hashmap_get(m->sessions, name);
69 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
83 if (uid == UID_INVALID) {
84 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
86 /* Note that we get the owner UID of the session, not the actual client UID here! */
87 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
91 r = sd_bus_creds_get_owner_uid(creds, &uid);
96 user = hashmap_get(m->users, UID_TO_PTR(uid));
98 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
115 r = manager_get_session_from_creds(m, message, NULL, error, &session);
119 seat = session->seat;
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
124 seat = hashmap_get(m->seats, name);
126 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
133 static int property_get_idle_hint(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
142 Manager *m = userdata;
148 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
151 static int property_get_idle_since_hint(
154 const char *interface,
155 const char *property,
156 sd_bus_message *reply,
158 sd_bus_error *error) {
160 Manager *m = userdata;
167 manager_get_idle_hint(m, &t);
169 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
172 static int property_get_inhibited(
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
179 sd_bus_error *error) {
181 Manager *m = userdata;
188 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
190 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
193 static int property_get_preparing(
196 const char *interface,
197 const char *property,
198 sd_bus_message *reply,
200 sd_bus_error *error) {
202 Manager *m = userdata;
209 if (streq(property, "PreparingForShutdown"))
210 b = !!(m->action_what & INHIBIT_SHUTDOWN);
212 b = !!(m->action_what & INHIBIT_SLEEP);
214 return sd_bus_message_append(reply, "b", b);
217 static int property_get_scheduled_shutdown(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 Manager *m = userdata;
233 r = sd_bus_message_open_container(reply, 'r', "st");
237 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
241 return sd_bus_message_close_container(reply);
244 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
246 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
247 _cleanup_free_ char *p = NULL;
248 Manager *m = userdata;
256 r = sd_bus_message_read(message, "s", &name);
260 r = manager_get_session_from_creds(m, message, name, error, &session);
264 p = session_bus_path(session);
268 return sd_bus_reply_method_return(message, "o", p);
271 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
272 _cleanup_free_ char *p = NULL;
273 Session *session = NULL;
274 Manager *m = userdata;
281 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
283 r = sd_bus_message_read(message, "u", &pid);
288 r = manager_get_session_from_creds(m, message, NULL, error, &session);
292 r = manager_get_session_by_pid(m, pid, &session);
297 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
300 p = session_bus_path(session);
304 return sd_bus_reply_method_return(message, "o", p);
307 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
308 _cleanup_free_ char *p = NULL;
309 Manager *m = userdata;
317 r = sd_bus_message_read(message, "u", &uid);
321 r = manager_get_user_from_creds(m, message, uid, error, &user);
325 p = user_bus_path(user);
329 return sd_bus_reply_method_return(message, "o", p);
332 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
333 _cleanup_free_ char *p = NULL;
334 Manager *m = userdata;
342 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
344 r = sd_bus_message_read(message, "u", &pid);
349 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
353 r = manager_get_user_by_pid(m, pid, &user);
357 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
360 p = user_bus_path(user);
364 return sd_bus_reply_method_return(message, "o", p);
367 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
368 _cleanup_free_ char *p = NULL;
369 Manager *m = userdata;
377 r = sd_bus_message_read(message, "s", &name);
381 r = manager_get_seat_from_creds(m, message, name, error, &seat);
385 p = seat_bus_path(seat);
389 return sd_bus_reply_method_return(message, "o", p);
392 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
394 Manager *m = userdata;
402 r = sd_bus_message_new_method_return(message, &reply);
406 r = sd_bus_message_open_container(reply, 'a', "(susso)");
410 HASHMAP_FOREACH(session, m->sessions, i) {
411 _cleanup_free_ char *p = NULL;
413 p = session_bus_path(session);
417 r = sd_bus_message_append(reply, "(susso)",
419 (uint32_t) session->user->uid,
421 session->seat ? session->seat->id : "",
427 r = sd_bus_message_close_container(reply);
431 return sd_bus_send(NULL, reply, NULL);
434 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
435 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
436 Manager *m = userdata;
444 r = sd_bus_message_new_method_return(message, &reply);
448 r = sd_bus_message_open_container(reply, 'a', "(uso)");
452 HASHMAP_FOREACH(user, m->users, i) {
453 _cleanup_free_ char *p = NULL;
455 p = user_bus_path(user);
459 r = sd_bus_message_append(reply, "(uso)",
460 (uint32_t) user->uid,
467 r = sd_bus_message_close_container(reply);
471 return sd_bus_send(NULL, reply, NULL);
474 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
475 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
476 Manager *m = userdata;
484 r = sd_bus_message_new_method_return(message, &reply);
488 r = sd_bus_message_open_container(reply, 'a', "(so)");
492 HASHMAP_FOREACH(seat, m->seats, i) {
493 _cleanup_free_ char *p = NULL;
495 p = seat_bus_path(seat);
499 r = sd_bus_message_append(reply, "(so)", seat->id, p);
504 r = sd_bus_message_close_container(reply);
508 return sd_bus_send(NULL, reply, NULL);
511 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
513 Manager *m = userdata;
514 Inhibitor *inhibitor;
521 r = sd_bus_message_new_method_return(message, &reply);
525 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
529 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
531 r = sd_bus_message_append(reply, "(ssssuu)",
532 strempty(inhibit_what_to_string(inhibitor->what)),
533 strempty(inhibitor->who),
534 strempty(inhibitor->why),
535 strempty(inhibit_mode_to_string(inhibitor->mode)),
536 (uint32_t) inhibitor->uid,
537 (uint32_t) inhibitor->pid);
542 r = sd_bus_message_close_container(reply);
546 return sd_bus_send(NULL, reply, NULL);
549 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
550 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
551 uint32_t uid, leader, audit_id = 0;
552 _cleanup_free_ char *id = NULL;
553 Session *session = NULL;
554 Manager *m = userdata;
566 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
571 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
574 t = _SESSION_TYPE_INVALID;
576 t = session_type_from_string(type);
578 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
582 c = _SESSION_CLASS_INVALID;
584 c = session_class_from_string(class);
586 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
589 if (isempty(desktop))
592 if (!string_is_safe(desktop))
593 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
599 seat = hashmap_get(m->seats, cseat);
601 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
604 if (tty_is_vc(tty)) {
609 else if (seat != m->seat0)
610 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
612 v = vtnr_from_tty(tty);
614 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
618 else if (vtnr != (uint32_t) v)
619 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
621 } else if (tty_is_console(tty)) {
625 else if (seat != m->seat0)
626 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
629 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
633 if (seat_has_vts(seat)) {
634 if (!vtnr || vtnr > 63)
635 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
638 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
642 r = sd_bus_message_enter_container(message, 'a', "(sv)");
646 if (t == _SESSION_TYPE_INVALID) {
647 if (!isempty(display))
649 else if (!isempty(tty))
652 t = SESSION_UNSPECIFIED;
655 if (c == _SESSION_CLASS_INVALID) {
656 if (t == SESSION_UNSPECIFIED)
657 c = SESSION_BACKGROUND;
663 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
665 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
669 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
674 manager_get_session_by_pid(m, leader, &session);
676 _cleanup_free_ char *path = NULL;
677 _cleanup_close_ int fifo_fd = -1;
679 /* Session already exists, client is probably
680 * something like "su" which changes uid but is still
681 * the same session */
683 fifo_fd = session_create_fifo(session);
687 path = session_bus_path(session);
691 log_debug("Sending reply about an existing session: "
692 "id=%s object_path=%s uid=%u runtime_path=%s "
693 "session_fd=%d seat=%s vtnr=%u",
696 (uint32_t) session->user->uid,
697 session->user->runtime_path,
699 session->seat ? session->seat->id : "",
700 (uint32_t) session->vtnr);
702 return sd_bus_reply_method_return(
706 session->user->runtime_path,
708 (uint32_t) session->user->uid,
709 session->seat ? session->seat->id : "",
710 (uint32_t) session->vtnr,
714 audit_session_from_pid(leader, &audit_id);
716 /* Keep our session IDs and the audit session IDs in sync */
718 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
721 /* Wut? There's already a session by this name and we
722 * didn't find it above? Weird, then let's not trust
723 * the audit data and let's better register a new
725 if (hashmap_get(m->sessions, id)) {
726 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
737 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
740 } while (hashmap_get(m->sessions, id));
743 r = manager_add_user_by_uid(m, uid, &user);
747 r = manager_add_session(m, id, &session);
751 session_set_user(session, user);
753 session->leader = leader;
754 session->audit_id = audit_id;
757 session->remote = remote;
758 session->vtnr = vtnr;
761 session->tty = strdup(tty);
768 if (!isempty(display)) {
769 session->display = strdup(display);
770 if (!session->display) {
776 if (!isempty(remote_user)) {
777 session->remote_user = strdup(remote_user);
778 if (!session->remote_user) {
784 if (!isempty(remote_host)) {
785 session->remote_host = strdup(remote_host);
786 if (!session->remote_host) {
792 if (!isempty(service)) {
793 session->service = strdup(service);
794 if (!session->service) {
800 if (!isempty(desktop)) {
801 session->desktop = strdup(desktop);
802 if (!session->desktop) {
809 r = seat_attach_session(seat, session);
814 r = session_start(session);
818 session->create_message = sd_bus_message_ref(message);
820 /* Now, let's wait until the slice unit and stuff got
821 * created. We send the reply back from
822 * session_send_create_reply(). */
828 session_add_to_gc_queue(session);
831 user_add_to_gc_queue(user);
836 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
837 Manager *m = userdata;
845 r = sd_bus_message_read(message, "s", &name);
849 r = manager_get_session_from_creds(m, message, name, error, &session);
853 r = session_release(session);
857 return sd_bus_reply_method_return(message, NULL);
860 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
861 Manager *m = userdata;
869 r = sd_bus_message_read(message, "s", &name);
873 r = manager_get_session_from_creds(m, message, name, error, &session);
877 return bus_session_method_activate(message, session, error);
880 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
881 const char *session_name, *seat_name;
882 Manager *m = userdata;
890 /* Same as ActivateSession() but refuses to work if
891 * the seat doesn't match */
893 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
897 r = manager_get_session_from_creds(m, message, session_name, error, &session);
901 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
905 if (session->seat != seat)
906 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
908 r = session_activate(session);
912 return sd_bus_reply_method_return(message, NULL);
915 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
916 Manager *m = userdata;
924 r = sd_bus_message_read(message, "s", &name);
928 r = manager_get_session_from_creds(m, message, name, error, &session);
932 return bus_session_method_lock(message, session, error);
935 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
936 Manager *m = userdata;
942 r = bus_verify_polkit_async(
945 "org.freedesktop.login1.lock-sessions",
954 return 1; /* Will call us back */
956 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
960 return sd_bus_reply_method_return(message, NULL);
963 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
965 Manager *m = userdata;
972 r = sd_bus_message_read(message, "s", &name);
976 r = manager_get_session_from_creds(m, message, name, error, &session);
980 return bus_session_method_kill(message, session, error);
983 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
984 Manager *m = userdata;
992 r = sd_bus_message_read(message, "u", &uid);
996 r = manager_get_user_from_creds(m, message, uid, error, &user);
1000 return bus_user_method_kill(message, user, error);
1003 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1004 Manager *m = userdata;
1012 r = sd_bus_message_read(message, "s", &name);
1016 r = manager_get_session_from_creds(m, message, name, error, &session);
1020 return bus_session_method_terminate(message, session, error);
1023 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1024 Manager *m = userdata;
1032 r = sd_bus_message_read(message, "u", &uid);
1036 r = manager_get_user_from_creds(m, message, uid, error, &user);
1040 return bus_user_method_terminate(message, user, error);
1043 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1044 Manager *m = userdata;
1052 r = sd_bus_message_read(message, "s", &name);
1056 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1060 return bus_seat_method_terminate(message, seat, error);
1063 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1064 _cleanup_free_ char *cc = NULL;
1065 Manager *m = userdata;
1075 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1079 if (uid == UID_INVALID) {
1080 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1082 /* Note that we get the owner UID of the session, not the actual client UID here! */
1083 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1087 r = sd_bus_creds_get_owner_uid(creds, &uid);
1095 return errno ? -errno : -ENOENT;
1097 r = bus_verify_polkit_async(
1100 "org.freedesktop.login1.set-user-linger",
1104 &m->polkit_registry,
1109 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1111 mkdir_p_label("/var/lib/systemd", 0755);
1113 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1117 cc = cescape(pw->pw_name);
1121 path = strjoina("/var/lib/systemd/linger/", cc);
1129 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1136 if (r < 0 && errno != ENOENT)
1139 u = hashmap_get(m->users, UID_TO_PTR(uid));
1141 user_add_to_gc_queue(u);
1144 return sd_bus_reply_method_return(message, NULL);
1147 static int trigger_device(Manager *m, struct udev_device *d) {
1148 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1149 struct udev_list_entry *first, *item;
1154 e = udev_enumerate_new(m->udev);
1159 r = udev_enumerate_add_match_parent(e, d);
1164 r = udev_enumerate_scan_devices(e);
1168 first = udev_enumerate_get_list_entry(e);
1169 udev_list_entry_foreach(item, first) {
1170 _cleanup_free_ char *t = NULL;
1173 p = udev_list_entry_get_name(item);
1175 t = strappend(p, "/uevent");
1179 write_string_file(t, "change");
1185 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1186 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1187 _cleanup_free_ char *rule = NULL, *file = NULL;
1188 const char *id_for_seat;
1195 d = udev_device_new_from_syspath(m->udev, sysfs);
1199 if (!udev_device_has_tag(d, "seat"))
1202 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1206 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1209 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1212 mkdir_p_label("/etc/udev/rules.d", 0755);
1213 mac_selinux_init("/etc");
1214 r = write_string_file_atomic_label(file, rule);
1218 return trigger_device(m, d);
1221 static int flush_devices(Manager *m) {
1222 _cleanup_closedir_ DIR *d;
1226 d = opendir("/etc/udev/rules.d");
1228 if (errno != ENOENT)
1229 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1233 while ((de = readdir(d))) {
1235 if (!dirent_is_file(de))
1238 if (!startswith(de->d_name, "72-seat-"))
1241 if (!endswith(de->d_name, ".rules"))
1244 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1245 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1249 return trigger_device(m, NULL);
1252 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1253 const char *sysfs, *seat;
1254 Manager *m = userdata;
1260 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1264 if (!path_startswith(sysfs, "/sys"))
1265 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1267 if (!seat_name_is_valid(seat))
1268 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1270 r = bus_verify_polkit_async(
1273 "org.freedesktop.login1.attach-device",
1277 &m->polkit_registry,
1282 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1284 r = attach_device(m, seat, sysfs);
1288 return sd_bus_reply_method_return(message, NULL);
1291 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1292 Manager *m = userdata;
1298 r = sd_bus_message_read(message, "b", &interactive);
1302 r = bus_verify_polkit_async(
1305 "org.freedesktop.login1.flush-devices",
1309 &m->polkit_registry,
1314 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1316 r = flush_devices(m);
1320 return sd_bus_reply_method_return(message, NULL);
1323 static int have_multiple_sessions(
1332 /* Check for other users' sessions. Greeter sessions do not
1333 * count, and non-login sessions do not count either. */
1334 HASHMAP_FOREACH(session, m->sessions, i)
1335 if (session->class == SESSION_USER &&
1336 session->user->uid != uid)
1342 static int bus_manager_log_shutdown(
1345 const char *unit_name) {
1352 if (w != INHIBIT_SHUTDOWN)
1355 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1356 p = "MESSAGE=System is powering down.";
1357 q = "SHUTDOWN=power-off";
1358 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1359 p = "MESSAGE=System is halting.";
1360 q = "SHUTDOWN=halt";
1361 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1362 p = "MESSAGE=System is rebooting.";
1363 q = "SHUTDOWN=reboot";
1364 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1365 p = "MESSAGE=System is rebooting with kexec.";
1366 q = "SHUTDOWN=kexec";
1368 p = "MESSAGE=System is shutting down.";
1372 if (!isempty(m->wall_message))
1373 p = strjoina(p, " (", m->wall_message, ")");
1375 return log_struct(LOG_NOTICE,
1376 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1382 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1383 Manager *m = userdata;
1388 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1392 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1397 if (until <= now(CLOCK_MONOTONIC))
1400 /* We want to ignore the lid switch for a while after each
1401 * suspend, and after boot-up. Hence let's install a timer for
1402 * this. As long as the event source exists we ignore the lid
1405 if (m->lid_switch_ignore_event_source) {
1408 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1415 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1417 r = sd_event_add_time(
1419 &m->lid_switch_ignore_event_source,
1422 lid_switch_ignore_handler, m);
1427 static int execute_shutdown_or_sleep(
1430 const char *unit_name,
1431 sd_bus_error *error) {
1433 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1440 assert(w < _INHIBIT_WHAT_MAX);
1443 bus_manager_log_shutdown(m, w, unit_name);
1445 r = sd_bus_call_method(
1447 "org.freedesktop.systemd1",
1448 "/org/freedesktop/systemd1",
1449 "org.freedesktop.systemd1.Manager",
1453 "ss", unit_name, "replace-irreversibly");
1457 r = sd_bus_message_read(reply, "o", &p);
1465 m->action_unit = unit_name;
1466 free(m->action_job);
1470 /* Make sure the lid switch is ignored for a while */
1471 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1476 static int manager_inhibit_timeout_handler(
1481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1482 Inhibitor *offending = NULL;
1483 Manager *manager = userdata;
1487 assert(manager->inhibit_timeout_source == s);
1489 if (manager->action_what == 0 || manager->action_job)
1492 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1493 _cleanup_free_ char *comm = NULL, *u = NULL;
1495 (void) get_process_comm(offending->pid, &comm);
1496 u = uid_to_name(offending->uid);
1498 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1499 offending->uid, strna(u),
1500 offending->pid, strna(comm));
1503 /* Actually do the operation */
1504 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1506 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1508 manager->action_unit = NULL;
1509 manager->action_what = 0;
1515 static int delay_shutdown_or_sleep(
1518 const char *unit_name) {
1525 assert(w < _INHIBIT_WHAT_MAX);
1528 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1530 if (m->inhibit_timeout_source) {
1531 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1533 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1535 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1537 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1539 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1540 timeout_val, 0, manager_inhibit_timeout_handler, m);
1545 m->action_unit = unit_name;
1551 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1553 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1554 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1555 [INHIBIT_SLEEP] = "PrepareForSleep"
1558 int active = _active;
1562 assert(w < _INHIBIT_WHAT_MAX);
1563 assert(signal_name[w]);
1565 return sd_bus_emit_signal(m->bus,
1566 "/org/freedesktop/login1",
1567 "org.freedesktop.login1.Manager",
1573 int bus_manager_shutdown_or_sleep_now_or_later(
1575 const char *unit_name,
1577 sd_bus_error *error) {
1585 assert(w <= _INHIBIT_WHAT_MAX);
1586 assert(!m->action_job);
1588 /* Tell everybody to prepare for shutdown/sleep */
1589 send_prepare_for(m, w, true);
1592 m->inhibit_delay_max > 0 &&
1593 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1596 /* Shutdown is delayed, keep in mind what we
1597 * want to do, and start a timeout */
1598 r = delay_shutdown_or_sleep(m, w, unit_name);
1600 /* Shutdown is not delayed, execute it
1602 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1607 static int verify_shutdown_creds(
1609 sd_bus_message *message,
1613 const char *action_multiple_sessions,
1614 const char *action_ignore_inhibit,
1615 sd_bus_error *error) {
1617 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1618 bool multiple_sessions, blocked;
1625 assert(w <= _INHIBIT_WHAT_MAX);
1627 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1631 r = sd_bus_creds_get_euid(creds, &uid);
1635 r = have_multiple_sessions(m, uid);
1639 multiple_sessions = r > 0;
1640 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1642 if (multiple_sessions && action_multiple_sessions) {
1643 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1647 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1650 if (blocked && action_ignore_inhibit) {
1651 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1655 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1658 if (!multiple_sessions && !blocked && action) {
1659 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1663 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1669 static int method_do_shutdown_or_sleep(
1671 sd_bus_message *message,
1672 const char *unit_name,
1675 const char *action_multiple_sessions,
1676 const char *action_ignore_inhibit,
1677 const char *sleep_verb,
1678 sd_bus_error *error) {
1686 assert(w <= _INHIBIT_WHAT_MAX);
1688 r = sd_bus_message_read(message, "b", &interactive);
1692 /* Don't allow multiple jobs being executed at the same time */
1694 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1697 r = can_sleep(sleep_verb);
1702 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1705 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1706 action_ignore_inhibit, error);
1710 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1714 return sd_bus_reply_method_return(message, NULL);
1717 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1718 Manager *m = userdata;
1720 return method_do_shutdown_or_sleep(
1722 SPECIAL_POWEROFF_TARGET,
1724 "org.freedesktop.login1.power-off",
1725 "org.freedesktop.login1.power-off-multiple-sessions",
1726 "org.freedesktop.login1.power-off-ignore-inhibit",
1731 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1732 Manager *m = userdata;
1734 return method_do_shutdown_or_sleep(
1736 SPECIAL_REBOOT_TARGET,
1738 "org.freedesktop.login1.reboot",
1739 "org.freedesktop.login1.reboot-multiple-sessions",
1740 "org.freedesktop.login1.reboot-ignore-inhibit",
1745 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1746 Manager *m = userdata;
1748 return method_do_shutdown_or_sleep(
1750 SPECIAL_SUSPEND_TARGET,
1752 "org.freedesktop.login1.suspend",
1753 "org.freedesktop.login1.suspend-multiple-sessions",
1754 "org.freedesktop.login1.suspend-ignore-inhibit",
1759 static int nologin_timeout_handler(
1764 Manager *m = userdata;
1767 log_info("Creating /run/nologin, blocking further logins...");
1769 r = write_string_file_atomic("/run/nologin", "System is going down.");
1771 log_error_errno(r, "Failed to create /run/nologin: %m");
1773 m->unlink_nologin = true;
1778 static int update_schedule_file(Manager *m) {
1779 _cleanup_free_ char *temp_path = NULL;
1780 _cleanup_fclose_ FILE *f = NULL;
1785 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1787 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1789 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1791 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1793 (void) fchmod(fileno(f), 0644);
1799 m->scheduled_shutdown_timeout,
1800 m->enable_wall_messages,
1801 m->scheduled_shutdown_type);
1803 if (!isempty(m->wall_message)) {
1804 _cleanup_free_ char *t;
1806 t = cescape(m->wall_message);
1812 fprintf(f, "WALL_MESSAGE=%s\n", t);
1815 r = fflush_and_check(f);
1819 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1827 (void) unlink(temp_path);
1828 (void) unlink("/run/systemd/shutdown/scheduled");
1830 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1833 static int manager_scheduled_shutdown_handler(
1838 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1839 Manager *m = userdata;
1845 if (isempty(m->scheduled_shutdown_type))
1848 if (streq(m->scheduled_shutdown_type, "halt"))
1849 target = SPECIAL_HALT_TARGET;
1850 else if (streq(m->scheduled_shutdown_type, "poweroff"))
1851 target = SPECIAL_POWEROFF_TARGET;
1853 target = SPECIAL_REBOOT_TARGET;
1855 r = execute_shutdown_or_sleep(m, 0, target, &error);
1857 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1862 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1863 Manager *m = userdata;
1864 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1865 const char *action_multiple_sessions = NULL;
1866 const char *action_ignore_inhibit = NULL;
1867 const char *action = NULL;
1875 r = sd_bus_message_read(message, "st", &type, &elapse);
1879 if (streq(type, "reboot")) {
1880 action = "org.freedesktop.login1.reboot";
1881 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1882 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1883 } else if (streq(type, "halt")) {
1884 action = "org.freedesktop.login1.halt";
1885 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1886 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1887 } else if (streq(type, "poweroff")) {
1888 action = "org.freedesktop.login1.poweroff";
1889 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1890 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1892 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1894 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1895 action, action_multiple_sessions, action_ignore_inhibit, error);
1899 if (m->scheduled_shutdown_timeout_source) {
1900 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1902 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1904 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1906 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1908 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1909 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1911 return log_error_errno(r, "sd_event_add_time() failed: %m");
1914 r = free_and_strdup(&m->scheduled_shutdown_type, type);
1916 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1920 if (m->nologin_timeout_source) {
1921 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1923 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1925 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1927 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1929 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1930 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1932 return log_error_errno(r, "sd_event_add_time() failed: %m");
1935 m->scheduled_shutdown_timeout = elapse;
1937 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1941 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1942 (void) sd_bus_creds_get_tty(creds, &tty);
1944 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1946 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1951 r = manager_setup_wall_message_timer(m);
1955 if (!isempty(type)) {
1956 r = update_schedule_file(m);
1960 (void) unlink("/run/systemd/shutdown/scheduled");
1962 return sd_bus_reply_method_return(message, NULL);
1965 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1966 Manager *m = userdata;
1972 cancelled = m->scheduled_shutdown_type != NULL;
1974 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1975 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1976 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1977 free(m->scheduled_shutdown_type);
1978 m->scheduled_shutdown_type = NULL;
1979 m->scheduled_shutdown_timeout = 0;
1982 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1983 const char *tty = NULL;
1987 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1989 (void) sd_bus_creds_get_uid(creds, &uid);
1990 (void) sd_bus_creds_get_tty(creds, &tty);
1993 utmp_wall("The system shutdown has been cancelled",
1994 lookup_uid(uid), tty, logind_wall_tty_filter, m);
1997 return sd_bus_reply_method_return(message, "b", cancelled);
2000 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2001 Manager *m = userdata;
2003 return method_do_shutdown_or_sleep(
2005 SPECIAL_HIBERNATE_TARGET,
2007 "org.freedesktop.login1.hibernate",
2008 "org.freedesktop.login1.hibernate-multiple-sessions",
2009 "org.freedesktop.login1.hibernate-ignore-inhibit",
2014 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2015 Manager *m = userdata;
2017 return method_do_shutdown_or_sleep(
2019 SPECIAL_HYBRID_SLEEP_TARGET,
2021 "org.freedesktop.login1.hibernate",
2022 "org.freedesktop.login1.hibernate-multiple-sessions",
2023 "org.freedesktop.login1.hibernate-ignore-inhibit",
2028 static int method_can_shutdown_or_sleep(
2030 sd_bus_message *message,
2033 const char *action_multiple_sessions,
2034 const char *action_ignore_inhibit,
2035 const char *sleep_verb,
2036 sd_bus_error *error) {
2038 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2039 bool multiple_sessions, challenge, blocked;
2040 const char *result = NULL;
2047 assert(w <= _INHIBIT_WHAT_MAX);
2049 assert(action_multiple_sessions);
2050 assert(action_ignore_inhibit);
2053 r = can_sleep(sleep_verb);
2057 return sd_bus_reply_method_return(message, "s", "na");
2060 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2064 r = sd_bus_creds_get_euid(creds, &uid);
2068 r = have_multiple_sessions(m, uid);
2072 multiple_sessions = r > 0;
2073 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2075 if (multiple_sessions) {
2076 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2083 result = "challenge";
2089 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2093 if (r > 0 && !result)
2095 else if (challenge && (!result || streq(result, "yes")))
2096 result = "challenge";
2101 if (!multiple_sessions && !blocked) {
2102 /* If neither inhibit nor multiple sessions
2103 * apply then just check the normal policy */
2105 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2112 result = "challenge";
2117 return sd_bus_reply_method_return(message, "s", result);
2120 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2121 Manager *m = userdata;
2123 return method_can_shutdown_or_sleep(
2126 "org.freedesktop.login1.power-off",
2127 "org.freedesktop.login1.power-off-multiple-sessions",
2128 "org.freedesktop.login1.power-off-ignore-inhibit",
2133 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2134 Manager *m = userdata;
2136 return method_can_shutdown_or_sleep(
2139 "org.freedesktop.login1.reboot",
2140 "org.freedesktop.login1.reboot-multiple-sessions",
2141 "org.freedesktop.login1.reboot-ignore-inhibit",
2146 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2147 Manager *m = userdata;
2149 return method_can_shutdown_or_sleep(
2152 "org.freedesktop.login1.suspend",
2153 "org.freedesktop.login1.suspend-multiple-sessions",
2154 "org.freedesktop.login1.suspend-ignore-inhibit",
2159 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2160 Manager *m = userdata;
2162 return method_can_shutdown_or_sleep(
2165 "org.freedesktop.login1.hibernate",
2166 "org.freedesktop.login1.hibernate-multiple-sessions",
2167 "org.freedesktop.login1.hibernate-ignore-inhibit",
2172 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2173 Manager *m = userdata;
2175 return method_can_shutdown_or_sleep(
2178 "org.freedesktop.login1.hibernate",
2179 "org.freedesktop.login1.hibernate-multiple-sessions",
2180 "org.freedesktop.login1.hibernate-ignore-inhibit",
2185 static int property_get_reboot_to_firmware_setup(
2188 const char *interface,
2189 const char *property,
2190 sd_bus_message *reply,
2192 sd_bus_error *error) {
2199 r = efi_get_reboot_to_firmware();
2200 if (r < 0 && r != -EOPNOTSUPP)
2203 return sd_bus_message_append(reply, "b", r > 0);
2206 static int method_set_reboot_to_firmware_setup(
2207 sd_bus_message *message,
2209 sd_bus_error *error) {
2212 Manager *m = userdata;
2217 r = sd_bus_message_read(message, "b", &b);
2221 r = bus_verify_polkit_async(message,
2223 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2227 &m->polkit_registry,
2232 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2234 r = efi_set_reboot_to_firmware(b);
2238 return sd_bus_reply_method_return(message, NULL);
2241 static int method_can_reboot_to_firmware_setup(
2242 sd_bus_message *message,
2244 sd_bus_error *error) {
2249 Manager *m = userdata;
2254 r = efi_reboot_to_firmware_supported();
2255 if (r == -EOPNOTSUPP)
2256 return sd_bus_reply_method_return(message, "s", "na");
2260 r = bus_test_polkit(message,
2262 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2273 result = "challenge";
2277 return sd_bus_reply_method_return(message, "s", result);
2280 static int method_set_wall_message(
2281 sd_bus_message *message,
2283 sd_bus_error *error) {
2286 Manager *m = userdata;
2288 int enable_wall_messages;
2293 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2297 r = bus_verify_polkit_async(message,
2299 "org.freedesktop.login1.set-wall-message",
2303 &m->polkit_registry,
2308 return 1; /* Will call us back */
2310 if (isempty(wall_message))
2311 m->wall_message = mfree(m->wall_message);
2313 r = free_and_strdup(&m->wall_message, wall_message);
2318 m->enable_wall_messages = enable_wall_messages;
2320 return sd_bus_reply_method_return(message, NULL);
2323 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2324 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2325 const char *who, *why, *what, *mode;
2326 _cleanup_free_ char *id = NULL;
2327 _cleanup_close_ int fifo_fd = -1;
2328 Manager *m = userdata;
2329 Inhibitor *i = NULL;
2339 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2343 w = inhibit_what_from_string(what);
2345 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2347 mm = inhibit_mode_from_string(mode);
2349 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2351 /* Delay is only supported for shutdown/sleep */
2352 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2353 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2355 /* Don't allow taking delay locks while we are already
2356 * executing the operation. We shouldn't create the impression
2357 * that the lock was successful if the machine is about to go
2358 * down/suspend any moment. */
2359 if (m->action_what & w)
2360 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2362 r = bus_verify_polkit_async(
2365 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2366 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2367 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2368 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2369 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2370 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2371 "org.freedesktop.login1.inhibit-handle-lid-switch",
2375 &m->polkit_registry,
2380 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2382 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2386 r = sd_bus_creds_get_euid(creds, &uid);
2390 r = sd_bus_creds_get_pid(creds, &pid);
2397 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2400 } while (hashmap_get(m->inhibitors, id));
2402 r = manager_add_inhibitor(m, id, &i);
2410 i->why = strdup(why);
2411 i->who = strdup(who);
2413 if (!i->why || !i->who) {
2418 fifo_fd = inhibitor_create_fifo(i);
2426 return sd_bus_reply_method_return(message, "h", fifo_fd);
2435 const sd_bus_vtable manager_vtable[] = {
2436 SD_BUS_VTABLE_START(0),
2438 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2439 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2441 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2442 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2443 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2444 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2445 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2446 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2447 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2448 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2449 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2450 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2451 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2452 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2453 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2454 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2455 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2456 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2457 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2458 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2459 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2460 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2461 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2462 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2464 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2465 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2466 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2467 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2468 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2469 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2470 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2471 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2472 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2473 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2474 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2475 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2476 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2477 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2478 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2479 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2480 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2481 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2482 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2483 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2484 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2485 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2486 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2487 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2488 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2489 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2490 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2491 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2492 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2493 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2498 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2499 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2500 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2501 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2502 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2503 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2504 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2506 SD_BUS_SIGNAL("SessionNew", "so", 0),
2507 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2508 SD_BUS_SIGNAL("UserNew", "uo", 0),
2509 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2510 SD_BUS_SIGNAL("SeatNew", "so", 0),
2511 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2512 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2513 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2518 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2527 if (streq(result, "done"))
2528 r = session_send_create_reply(s, NULL);
2530 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2532 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2533 r = session_send_create_reply(s, &e);
2539 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2540 const char *path, *result, *unit;
2541 Manager *m = userdata;
2550 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2552 bus_log_parse_error(r);
2556 if (m->action_job && streq(m->action_job, path)) {
2557 log_info("Operation finished.");
2559 /* Tell people that they now may take a lock again */
2560 send_prepare_for(m, m->action_what, false);
2562 m->action_job = mfree(m->action_job);
2563 m->action_unit = NULL;
2568 session = hashmap_get(m->session_units, unit);
2571 if (streq_ptr(path, session->scope_job))
2572 session->scope_job = mfree(session->scope_job);
2574 session_jobs_reply(session, unit, result);
2576 session_save(session);
2577 session_add_to_gc_queue(session);
2580 user = hashmap_get(m->user_units, unit);
2583 if (streq_ptr(path, user->service_job))
2584 user->service_job = mfree(user->service_job);
2586 if (streq_ptr(path, user->slice_job))
2587 user->slice_job = mfree(user->slice_job);
2589 LIST_FOREACH(sessions_by_user, session, user->sessions)
2590 session_jobs_reply(session, unit, result);
2593 user_add_to_gc_queue(user);
2599 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2600 const char *path, *unit;
2601 Manager *m = userdata;
2609 r = sd_bus_message_read(message, "so", &unit, &path);
2611 bus_log_parse_error(r);
2615 session = hashmap_get(m->session_units, unit);
2617 session_add_to_gc_queue(session);
2619 user = hashmap_get(m->user_units, unit);
2621 user_add_to_gc_queue(user);
2626 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627 _cleanup_free_ char *unit = NULL;
2628 Manager *m = userdata;
2637 path = sd_bus_message_get_path(message);
2641 r = unit_name_from_dbus_path(path, &unit);
2642 if (r == -EINVAL) /* not a unit */
2649 session = hashmap_get(m->session_units, unit);
2651 session_add_to_gc_queue(session);
2653 user = hashmap_get(m->user_units, unit);
2655 user_add_to_gc_queue(user);
2660 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2661 Manager *m = userdata;
2669 r = sd_bus_message_read(message, "b", &b);
2671 bus_log_parse_error(r);
2678 /* systemd finished reloading, let's recheck all our sessions */
2679 log_debug("System manager has been reloaded, rechecking sessions...");
2681 HASHMAP_FOREACH(session, m->sessions, i)
2682 session_add_to_gc_queue(session);
2687 int manager_send_changed(Manager *manager, const char *property, ...) {
2692 l = strv_from_stdarg_alloca(property);
2694 return sd_bus_emit_properties_changed_strv(
2696 "/org/freedesktop/login1",
2697 "org.freedesktop.login1.Manager",
2701 int manager_start_scope(
2706 const char *description,
2707 const char *after, const char *after2,
2708 sd_bus_error *error,
2711 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2718 r = sd_bus_message_new_method_call(
2721 "org.freedesktop.systemd1",
2722 "/org/freedesktop/systemd1",
2723 "org.freedesktop.systemd1.Manager",
2724 "StartTransientUnit");
2728 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2732 r = sd_bus_message_open_container(m, 'a', "(sv)");
2736 if (!isempty(slice)) {
2737 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2742 if (!isempty(description)) {
2743 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2748 if (!isempty(after)) {
2749 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2754 if (!isempty(after2)) {
2755 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2760 /* cgroup empty notification is not available in containers
2761 * currently. To make this less problematic, let's shorten the
2762 * stop timeout for sessions, so that we don't wait
2765 /* Make sure that the session shells are terminated with
2766 * SIGHUP since bash and friends tend to ignore SIGTERM */
2767 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2771 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2775 r = sd_bus_message_close_container(m);
2779 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2783 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2791 r = sd_bus_message_read(reply, "o", &j);
2805 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2806 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2812 r = sd_bus_call_method(
2814 "org.freedesktop.systemd1",
2815 "/org/freedesktop/systemd1",
2816 "org.freedesktop.systemd1.Manager",
2820 "ss", unit, "fail");
2828 r = sd_bus_message_read(reply, "o", &j);
2842 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2843 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2849 r = sd_bus_call_method(
2851 "org.freedesktop.systemd1",
2852 "/org/freedesktop/systemd1",
2853 "org.freedesktop.systemd1.Manager",
2857 "ss", unit, "fail");
2859 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2860 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2865 sd_bus_error_free(error);
2876 r = sd_bus_message_read(reply, "o", &j);
2890 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2891 _cleanup_free_ char *path = NULL;
2897 path = unit_dbus_path_from_name(scope);
2901 r = sd_bus_call_method(
2903 "org.freedesktop.systemd1",
2905 "org.freedesktop.systemd1.Scope",
2911 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2912 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2913 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2914 sd_bus_error_free(error);
2924 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2928 return sd_bus_call_method(
2930 "org.freedesktop.systemd1",
2931 "/org/freedesktop/systemd1",
2932 "org.freedesktop.systemd1.Manager",
2936 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2939 int manager_unit_is_active(Manager *manager, const char *unit) {
2940 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2941 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2942 _cleanup_free_ char *path = NULL;
2949 path = unit_dbus_path_from_name(unit);
2953 r = sd_bus_get_property(
2955 "org.freedesktop.systemd1",
2957 "org.freedesktop.systemd1.Unit",
2963 /* systemd might have droppped off momentarily, let's
2964 * not make this an error */
2965 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2966 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2969 /* If the unit is already unloaded then it's not
2971 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2972 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2978 r = sd_bus_message_read(reply, "s", &state);
2982 return !streq(state, "inactive") && !streq(state, "failed");
2985 int manager_job_is_active(Manager *manager, const char *path) {
2986 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2987 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2993 r = sd_bus_get_property(
2995 "org.freedesktop.systemd1",
2997 "org.freedesktop.systemd1.Job",
3003 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3004 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3007 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3013 /* We don't actually care about the state really. The fact
3014 * that we could read the job state is enough for us */