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"
45 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
46 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
55 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
59 r = sd_bus_creds_get_session(creds, &name);
64 session = hashmap_get(m->sessions, name);
66 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
72 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
80 if (uid == UID_INVALID) {
81 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
83 /* Note that we get the owner UID of the session, not the actual client UID here! */
84 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
88 r = sd_bus_creds_get_owner_uid(creds, &uid);
93 user = hashmap_get(m->users, UID_TO_PTR(uid));
95 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
101 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
112 r = manager_get_session_from_creds(m, message, NULL, error, &session);
116 seat = session->seat;
119 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
121 seat = hashmap_get(m->seats, name);
123 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
130 static int property_get_idle_hint(
133 const char *interface,
134 const char *property,
135 sd_bus_message *reply,
137 sd_bus_error *error) {
139 Manager *m = userdata;
145 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
148 static int property_get_idle_since_hint(
151 const char *interface,
152 const char *property,
153 sd_bus_message *reply,
155 sd_bus_error *error) {
157 Manager *m = userdata;
164 manager_get_idle_hint(m, &t);
166 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
169 static int property_get_inhibited(
172 const char *interface,
173 const char *property,
174 sd_bus_message *reply,
176 sd_bus_error *error) {
178 Manager *m = userdata;
185 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
187 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
190 static int property_get_preparing(
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
197 sd_bus_error *error) {
199 Manager *m = userdata;
206 if (streq(property, "PreparingForShutdown"))
207 b = !!(m->action_what & INHIBIT_SHUTDOWN);
209 b = !!(m->action_what & INHIBIT_SLEEP);
211 return sd_bus_message_append(reply, "b", b);
214 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
216 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
217 _cleanup_free_ char *p = NULL;
218 Manager *m = userdata;
227 r = sd_bus_message_read(message, "s", &name);
231 r = manager_get_session_from_creds(m, message, name, error, &session);
235 p = session_bus_path(session);
239 return sd_bus_reply_method_return(message, "o", p);
242 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
243 _cleanup_free_ char *p = NULL;
244 Session *session = NULL;
245 Manager *m = userdata;
253 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
255 r = sd_bus_message_read(message, "u", &pid);
260 r = manager_get_session_from_creds(m, message, NULL, error, &session);
264 r = manager_get_session_by_pid(m, pid, &session);
269 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
272 p = session_bus_path(session);
276 return sd_bus_reply_method_return(message, "o", p);
279 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
280 _cleanup_free_ char *p = NULL;
281 Manager *m = userdata;
290 r = sd_bus_message_read(message, "u", &uid);
294 r = manager_get_user_from_creds(m, message, uid, error, &user);
298 p = user_bus_path(user);
302 return sd_bus_reply_method_return(message, "o", p);
305 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
306 _cleanup_free_ char *p = NULL;
307 Manager *m = userdata;
316 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
318 r = sd_bus_message_read(message, "u", &pid);
323 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
327 r = manager_get_user_by_pid(m, pid, &user);
331 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);
334 p = user_bus_path(user);
338 return sd_bus_reply_method_return(message, "o", p);
341 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
342 _cleanup_free_ char *p = NULL;
343 Manager *m = userdata;
352 r = sd_bus_message_read(message, "s", &name);
356 r = manager_get_seat_from_creds(m, message, name, error, &seat);
360 p = seat_bus_path(seat);
364 return sd_bus_reply_method_return(message, "o", p);
367 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
368 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
369 Manager *m = userdata;
378 r = sd_bus_message_new_method_return(message, &reply);
382 r = sd_bus_message_open_container(reply, 'a', "(susso)");
386 HASHMAP_FOREACH(session, m->sessions, i) {
387 _cleanup_free_ char *p = NULL;
389 p = session_bus_path(session);
393 r = sd_bus_message_append(reply, "(susso)",
395 (uint32_t) session->user->uid,
397 session->seat ? session->seat->id : "",
403 r = sd_bus_message_close_container(reply);
407 return sd_bus_send(bus, reply, NULL);
410 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
411 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
412 Manager *m = userdata;
421 r = sd_bus_message_new_method_return(message, &reply);
425 r = sd_bus_message_open_container(reply, 'a', "(uso)");
429 HASHMAP_FOREACH(user, m->users, i) {
430 _cleanup_free_ char *p = NULL;
432 p = user_bus_path(user);
436 r = sd_bus_message_append(reply, "(uso)",
437 (uint32_t) user->uid,
444 r = sd_bus_message_close_container(reply);
448 return sd_bus_send(bus, reply, NULL);
451 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
452 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
453 Manager *m = userdata;
462 r = sd_bus_message_new_method_return(message, &reply);
466 r = sd_bus_message_open_container(reply, 'a', "(so)");
470 HASHMAP_FOREACH(seat, m->seats, i) {
471 _cleanup_free_ char *p = NULL;
473 p = seat_bus_path(seat);
477 r = sd_bus_message_append(reply, "(so)", seat->id, p);
482 r = sd_bus_message_close_container(reply);
486 return sd_bus_send(bus, reply, NULL);
489 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
490 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
491 Manager *m = userdata;
492 Inhibitor *inhibitor;
496 r = sd_bus_message_new_method_return(message, &reply);
500 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
504 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
506 r = sd_bus_message_append(reply, "(ssssuu)",
507 strempty(inhibit_what_to_string(inhibitor->what)),
508 strempty(inhibitor->who),
509 strempty(inhibitor->why),
510 strempty(inhibit_mode_to_string(inhibitor->mode)),
511 (uint32_t) inhibitor->uid,
512 (uint32_t) inhibitor->pid);
517 r = sd_bus_message_close_container(reply);
521 return sd_bus_send(bus, reply, NULL);
524 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
525 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
526 uint32_t uid, leader, audit_id = 0;
527 _cleanup_free_ char *id = NULL;
528 Session *session = NULL;
529 Manager *m = userdata;
542 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
547 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
550 t = _SESSION_TYPE_INVALID;
552 t = session_type_from_string(type);
554 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
558 c = _SESSION_CLASS_INVALID;
560 c = session_class_from_string(class);
562 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
565 if (isempty(desktop))
568 if (!string_is_safe(desktop))
569 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
575 seat = hashmap_get(m->seats, cseat);
577 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
580 if (tty_is_vc(tty)) {
585 else if (seat != m->seat0)
586 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);
588 v = vtnr_from_tty(tty);
590 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
594 else if (vtnr != (uint32_t) v)
595 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
597 } else if (tty_is_console(tty)) {
601 else if (seat != m->seat0)
602 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
605 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
609 if (seat_has_vts(seat)) {
610 if (!vtnr || vtnr > 63)
611 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
614 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
618 r = sd_bus_message_enter_container(message, 'a', "(sv)");
622 if (t == _SESSION_TYPE_INVALID) {
623 if (!isempty(display))
625 else if (!isempty(tty))
628 t = SESSION_UNSPECIFIED;
631 if (c == _SESSION_CLASS_INVALID) {
632 if (t == SESSION_UNSPECIFIED)
633 c = SESSION_BACKGROUND;
639 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
641 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
645 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
650 manager_get_session_by_pid(m, leader, &session);
652 _cleanup_free_ char *path = NULL;
653 _cleanup_close_ int fifo_fd = -1;
655 /* Session already exists, client is probably
656 * something like "su" which changes uid but is still
657 * the same session */
659 fifo_fd = session_create_fifo(session);
663 path = session_bus_path(session);
667 log_debug("Sending reply about an existing session: "
668 "id=%s object_path=%s uid=%u runtime_path=%s "
669 "session_fd=%d seat=%s vtnr=%u",
672 (uint32_t) session->user->uid,
673 session->user->runtime_path,
675 session->seat ? session->seat->id : "",
676 (uint32_t) session->vtnr);
678 return sd_bus_reply_method_return(
682 session->user->runtime_path,
684 (uint32_t) session->user->uid,
685 session->seat ? session->seat->id : "",
686 (uint32_t) session->vtnr,
690 audit_session_from_pid(leader, &audit_id);
692 /* Keep our session IDs and the audit session IDs in sync */
694 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
697 /* Wut? There's already a session by this name and we
698 * didn't find it above? Weird, then let's not trust
699 * the audit data and let's better register a new
701 if (hashmap_get(m->sessions, id)) {
702 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
715 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
718 } while (hashmap_get(m->sessions, id));
721 r = manager_add_user_by_uid(m, uid, &user);
725 r = manager_add_session(m, id, &session);
729 session_set_user(session, user);
731 session->leader = leader;
732 session->audit_id = audit_id;
735 session->remote = remote;
736 session->vtnr = vtnr;
739 session->tty = strdup(tty);
746 if (!isempty(display)) {
747 session->display = strdup(display);
748 if (!session->display) {
754 if (!isempty(remote_user)) {
755 session->remote_user = strdup(remote_user);
756 if (!session->remote_user) {
762 if (!isempty(remote_host)) {
763 session->remote_host = strdup(remote_host);
764 if (!session->remote_host) {
770 if (!isempty(service)) {
771 session->service = strdup(service);
772 if (!session->service) {
778 if (!isempty(desktop)) {
779 session->desktop = strdup(desktop);
780 if (!session->desktop) {
787 r = seat_attach_session(seat, session);
792 r = session_start(session);
796 session->create_message = sd_bus_message_ref(message);
798 /* Here upstream systemd starts cgroups and the user systemd,
799 and arranges to reply asynchronously. We reply
802 r = session_send_create_reply(session, NULL);
810 session_add_to_gc_queue(session);
813 user_add_to_gc_queue(user);
818 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
819 Manager *m = userdata;
828 r = sd_bus_message_read(message, "s", &name);
832 r = manager_get_session_from_creds(m, message, name, error, &session);
836 r = session_release(session);
840 session_add_to_gc_queue(session);
842 return sd_bus_reply_method_return(message, NULL);
845 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
846 Manager *m = userdata;
855 r = sd_bus_message_read(message, "s", &name);
859 r = manager_get_session_from_creds(m, message, name, error, &session);
863 return bus_session_method_activate(bus, message, session, error);
866 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
867 const char *session_name, *seat_name;
868 Manager *m = userdata;
877 /* Same as ActivateSession() but refuses to work if
878 * the seat doesn't match */
880 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
884 r = manager_get_session_from_creds(m, message, session_name, error, &session);
888 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
892 if (session->seat != seat)
893 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
895 r = session_activate(session);
899 return sd_bus_reply_method_return(message, NULL);
902 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
903 Manager *m = userdata;
912 r = sd_bus_message_read(message, "s", &name);
916 r = manager_get_session_from_creds(m, message, name, error, &session);
920 return bus_session_method_lock(bus, message, session, error);
923 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
924 Manager *m = userdata;
931 r = bus_verify_polkit_async(
934 "org.freedesktop.login1.lock-sessions",
942 return 1; /* Will call us back */
944 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
948 return sd_bus_reply_method_return(message, NULL);
951 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
953 Manager *m = userdata;
961 r = sd_bus_message_read(message, "s", &name);
965 r = manager_get_session_from_creds(m, message, name, error, &session);
969 return bus_session_method_kill(bus, message, session, error);
972 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
973 Manager *m = userdata;
982 r = sd_bus_message_read(message, "u", &uid);
986 r = manager_get_user_from_creds(m, message, uid, error, &user);
990 return bus_user_method_kill(bus, message, user, error);
993 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
994 Manager *m = userdata;
1003 r = sd_bus_message_read(message, "s", &name);
1007 r = manager_get_session_from_creds(m, message, name, error, &session);
1011 return bus_session_method_terminate(bus, message, session, error);
1014 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1015 Manager *m = userdata;
1024 r = sd_bus_message_read(message, "u", &uid);
1028 r = manager_get_user_from_creds(m, message, uid, error, &user);
1032 return bus_user_method_terminate(bus, message, user, error);
1035 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1036 Manager *m = userdata;
1045 r = sd_bus_message_read(message, "s", &name);
1049 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1053 return bus_seat_method_terminate(bus, message, seat, error);
1056 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1057 _cleanup_free_ char *cc = NULL;
1058 Manager *m = userdata;
1069 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1073 if (uid == UID_INVALID) {
1074 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1076 /* Note that we get the owner UID of the session, not the actual client UID here! */
1077 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1081 r = sd_bus_creds_get_owner_uid(creds, &uid);
1089 return errno ? -errno : -ENOENT;
1091 r = bus_verify_polkit_async(
1094 "org.freedesktop.login1.set-user-linger",
1097 &m->polkit_registry,
1102 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1104 mkdir_p_label("/var/lib/systemd", 0755);
1106 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1110 cc = cescape(pw->pw_name);
1114 path = strjoina("/var/lib/systemd/linger/", cc);
1122 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1129 if (r < 0 && errno != ENOENT)
1132 u = hashmap_get(m->users, UID_TO_PTR(uid));
1134 user_add_to_gc_queue(u);
1137 return sd_bus_reply_method_return(message, NULL);
1140 static int trigger_device(Manager *m, struct udev_device *d) {
1141 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1142 struct udev_list_entry *first, *item;
1147 e = udev_enumerate_new(m->udev);
1152 r = udev_enumerate_add_match_parent(e, d);
1157 r = udev_enumerate_scan_devices(e);
1161 first = udev_enumerate_get_list_entry(e);
1162 udev_list_entry_foreach(item, first) {
1163 _cleanup_free_ char *t = NULL;
1166 p = udev_list_entry_get_name(item);
1168 t = strappend(p, "/uevent");
1172 write_string_file(t, "change");
1178 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1179 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1180 _cleanup_free_ char *rule = NULL, *file = NULL;
1181 const char *id_for_seat;
1188 d = udev_device_new_from_syspath(m->udev, sysfs);
1192 if (!udev_device_has_tag(d, "seat"))
1195 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1199 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1202 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1205 mkdir_p_label("/etc/udev/rules.d", 0755);
1206 mac_selinux_init("/etc");
1207 r = write_string_file_atomic_label(file, rule);
1211 return trigger_device(m, d);
1214 static int flush_devices(Manager *m) {
1215 _cleanup_closedir_ DIR *d;
1219 d = opendir("/etc/udev/rules.d");
1221 if (errno != ENOENT)
1222 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1226 while ((de = readdir(d))) {
1228 if (!dirent_is_file(de))
1231 if (!startswith(de->d_name, "72-seat-"))
1234 if (!endswith(de->d_name, ".rules"))
1237 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1238 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1242 return trigger_device(m, NULL);
1245 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1246 const char *sysfs, *seat;
1247 Manager *m = userdata;
1254 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1258 if (!path_startswith(sysfs, "/sys"))
1259 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1261 if (!seat_name_is_valid(seat))
1262 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1264 r = bus_verify_polkit_async(
1267 "org.freedesktop.login1.attach-device",
1270 &m->polkit_registry,
1275 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1277 r = attach_device(m, seat, sysfs);
1281 return sd_bus_reply_method_return(message, NULL);
1284 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1285 Manager *m = userdata;
1292 r = sd_bus_message_read(message, "b", &interactive);
1296 r = bus_verify_polkit_async(
1299 "org.freedesktop.login1.flush-devices",
1302 &m->polkit_registry,
1307 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1309 r = flush_devices(m);
1313 return sd_bus_reply_method_return(message, NULL);
1316 static int have_multiple_sessions(
1325 /* Check for other users' sessions. Greeter sessions do not
1326 * count, and non-login sessions do not count either. */
1327 HASHMAP_FOREACH(session, m->sessions, i)
1328 if (session->class == SESSION_USER &&
1329 session->user->uid != uid)
1335 static int bus_manager_log_shutdown(
1338 HandleAction action) {
1344 if (w != INHIBIT_SHUTDOWN)
1348 case HANDLE_POWEROFF:
1349 p = "MESSAGE=System is powering down.";
1350 q = "SHUTDOWN=power-off";
1353 p = "MESSAGE=System is halting.";
1354 q = "SHUTDOWN=halt";
1357 p = "MESSAGE=System is rebooting.";
1358 q = "SHUTDOWN=reboot";
1361 p = "MESSAGE=System is rebooting with kexec.";
1362 q = "SHUTDOWN=kexec";
1365 p = "MESSAGE=System is shutting down.";
1370 return log_struct(LOG_NOTICE,
1371 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1377 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1378 Manager *m = userdata;
1383 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1387 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1392 if (until <= now(CLOCK_MONOTONIC))
1395 /* We want to ignore the lid switch for a while after each
1396 * suspend, and after boot-up. Hence let's install a timer for
1397 * this. As long as the event source exists we ignore the lid
1400 if (m->lid_switch_ignore_event_source) {
1403 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1410 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1412 r = sd_event_add_time(
1414 &m->lid_switch_ignore_event_source,
1417 lid_switch_ignore_handler, m);
1422 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1424 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1425 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1426 [INHIBIT_SLEEP] = "PrepareForSleep"
1429 int active = _active;
1433 assert(w < _INHIBIT_WHAT_MAX);
1434 assert(signal_name[w]);
1436 return sd_bus_emit_signal(m->bus,
1437 "/org/freedesktop/login1",
1438 "org.freedesktop.login1.Manager",
1444 static int execute_shutdown_or_sleep(
1447 HandleAction action,
1448 sd_bus_error *error) {
1453 assert(w < _INHIBIT_WHAT_MAX);
1455 bus_manager_log_shutdown(m, w, action);
1457 r = shutdown_or_sleep(m, action);
1461 if (w == INHIBIT_SLEEP)
1462 /* And we're back. */
1463 send_prepare_for(m, w, false);
1467 /* Make sure the lid switch is ignored for a while (?) */
1468 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1473 static int delay_shutdown_or_sleep(
1476 HandleAction action) {
1480 assert(w < _INHIBIT_WHAT_MAX);
1482 m->action_timestamp = now(CLOCK_MONOTONIC);
1483 m->pending_action = action;
1489 int bus_manager_shutdown_or_sleep_now_or_later(
1491 HandleAction action,
1493 sd_bus_error *error) {
1500 assert(w <= _INHIBIT_WHAT_MAX);
1502 /* Tell everybody to prepare for shutdown/sleep */
1503 send_prepare_for(m, w, true);
1506 m->inhibit_delay_max > 0 &&
1507 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1510 /* Shutdown is delayed, keep in mind what we
1511 * want to do, and start a timeout */
1512 r = delay_shutdown_or_sleep(m, w, action);
1514 /* Shutdown is not delayed, execute it
1516 r = execute_shutdown_or_sleep(m, w, action, error);
1521 static int method_do_shutdown_or_sleep(
1523 sd_bus_message *message,
1524 HandleAction sleep_action,
1527 const char *action_multiple_sessions,
1528 const char *action_ignore_inhibit,
1529 const char *sleep_verb,
1530 sd_bus_message_handler_t method,
1531 sd_bus_error *error) {
1533 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1534 bool multiple_sessions, blocked;
1541 assert(w <= _INHIBIT_WHAT_MAX);
1543 assert(action_multiple_sessions);
1544 assert(action_ignore_inhibit);
1547 r = sd_bus_message_read(message, "b", &interactive);
1551 /* Don't allow multiple jobs being executed at the same time */
1553 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1556 r = can_sleep(sleep_verb);
1561 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1564 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1568 r = sd_bus_creds_get_euid(creds, &uid);
1572 r = have_multiple_sessions(m, uid);
1576 multiple_sessions = r > 0;
1577 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1579 if (multiple_sessions) {
1580 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1584 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1588 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1592 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1595 if (!multiple_sessions && !blocked) {
1596 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1600 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1603 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1607 return sd_bus_reply_method_return(message, NULL);
1610 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1611 Manager *m = userdata;
1613 return method_do_shutdown_or_sleep(
1617 "org.freedesktop.login1.power-off",
1618 "org.freedesktop.login1.power-off-multiple-sessions",
1619 "org.freedesktop.login1.power-off-ignore-inhibit",
1625 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1626 Manager *m = userdata;
1628 return method_do_shutdown_or_sleep(
1632 "org.freedesktop.login1.reboot",
1633 "org.freedesktop.login1.reboot-multiple-sessions",
1634 "org.freedesktop.login1.reboot-ignore-inhibit",
1640 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1641 Manager *m = userdata;
1643 return method_do_shutdown_or_sleep(
1647 "org.freedesktop.login1.suspend",
1648 "org.freedesktop.login1.suspend-multiple-sessions",
1649 "org.freedesktop.login1.suspend-ignore-inhibit",
1655 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1656 Manager *m = userdata;
1658 return method_do_shutdown_or_sleep(
1662 "org.freedesktop.login1.hibernate",
1663 "org.freedesktop.login1.hibernate-multiple-sessions",
1664 "org.freedesktop.login1.hibernate-ignore-inhibit",
1670 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1671 Manager *m = userdata;
1673 return method_do_shutdown_or_sleep(
1675 HANDLE_HYBRID_SLEEP,
1677 "org.freedesktop.login1.hibernate",
1678 "org.freedesktop.login1.hibernate-multiple-sessions",
1679 "org.freedesktop.login1.hibernate-ignore-inhibit",
1681 method_hybrid_sleep,
1685 static int method_can_shutdown_or_sleep(
1687 sd_bus_message *message,
1690 const char *action_multiple_sessions,
1691 const char *action_ignore_inhibit,
1692 const char *sleep_verb,
1693 sd_bus_error *error) {
1695 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1696 bool multiple_sessions, challenge, blocked;
1697 const char *result = NULL;
1704 assert(w <= _INHIBIT_WHAT_MAX);
1706 assert(action_multiple_sessions);
1707 assert(action_ignore_inhibit);
1710 r = can_sleep(sleep_verb);
1714 return sd_bus_reply_method_return(message, "s", "na");
1717 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1721 r = sd_bus_creds_get_euid(creds, &uid);
1725 r = have_multiple_sessions(m, uid);
1729 multiple_sessions = r > 0;
1730 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1732 if (multiple_sessions) {
1733 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1740 result = "challenge";
1746 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1750 if (r > 0 && !result)
1752 else if (challenge && (!result || streq(result, "yes")))
1753 result = "challenge";
1758 if (!multiple_sessions && !blocked) {
1759 /* If neither inhibit nor multiple sessions
1760 * apply then just check the normal policy */
1762 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1769 result = "challenge";
1774 return sd_bus_reply_method_return(message, "s", result);
1777 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1778 Manager *m = userdata;
1780 return method_can_shutdown_or_sleep(
1783 "org.freedesktop.login1.power-off",
1784 "org.freedesktop.login1.power-off-multiple-sessions",
1785 "org.freedesktop.login1.power-off-ignore-inhibit",
1790 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1791 Manager *m = userdata;
1793 return method_can_shutdown_or_sleep(
1796 "org.freedesktop.login1.reboot",
1797 "org.freedesktop.login1.reboot-multiple-sessions",
1798 "org.freedesktop.login1.reboot-ignore-inhibit",
1803 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1804 Manager *m = userdata;
1806 return method_can_shutdown_or_sleep(
1809 "org.freedesktop.login1.suspend",
1810 "org.freedesktop.login1.suspend-multiple-sessions",
1811 "org.freedesktop.login1.suspend-ignore-inhibit",
1816 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1817 Manager *m = userdata;
1819 return method_can_shutdown_or_sleep(
1822 "org.freedesktop.login1.hibernate",
1823 "org.freedesktop.login1.hibernate-multiple-sessions",
1824 "org.freedesktop.login1.hibernate-ignore-inhibit",
1829 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1830 Manager *m = userdata;
1832 return method_can_shutdown_or_sleep(
1835 "org.freedesktop.login1.hibernate",
1836 "org.freedesktop.login1.hibernate-multiple-sessions",
1837 "org.freedesktop.login1.hibernate-ignore-inhibit",
1842 static int property_get_reboot_to_firmware_setup(
1845 const char *interface,
1846 const char *property,
1847 sd_bus_message *reply,
1849 sd_bus_error *error) {
1856 r = efi_get_reboot_to_firmware();
1857 if (r < 0 && r != -EOPNOTSUPP)
1860 return sd_bus_message_append(reply, "b", r > 0);
1863 static int method_set_reboot_to_firmware_setup(
1865 sd_bus_message *message,
1867 sd_bus_error *error) {
1870 Manager *m = userdata;
1876 r = sd_bus_message_read(message, "b", &b);
1880 r = bus_verify_polkit_async(message,
1882 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1885 &m->polkit_registry,
1890 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1892 r = efi_set_reboot_to_firmware(b);
1896 return sd_bus_reply_method_return(message, NULL);
1899 static int method_can_reboot_to_firmware_setup(
1901 sd_bus_message *message,
1903 sd_bus_error *error) {
1908 Manager *m = userdata;
1914 r = efi_reboot_to_firmware_supported();
1915 if (r == -EOPNOTSUPP)
1916 return sd_bus_reply_method_return(message, "s", "na");
1920 r = bus_test_polkit(message,
1922 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1932 result = "challenge";
1936 return sd_bus_reply_method_return(message, "s", result);
1939 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1940 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1941 const char *who, *why, *what, *mode;
1942 _cleanup_free_ char *id = NULL;
1943 _cleanup_close_ int fifo_fd = -1;
1944 Manager *m = userdata;
1945 Inhibitor *i = NULL;
1956 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1960 w = inhibit_what_from_string(what);
1962 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1964 mm = inhibit_mode_from_string(mode);
1966 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1968 /* Delay is only supported for shutdown/sleep */
1969 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1970 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1972 /* Don't allow taking delay locks while we are already
1973 * executing the operation. We shouldn't create the impression
1974 * that the lock was successful if the machine is about to go
1975 * down/suspend any moment. */
1976 if (m->action_what & w)
1977 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1979 r = bus_verify_polkit_async(
1982 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1983 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1984 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1985 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1986 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1987 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1988 "org.freedesktop.login1.inhibit-handle-lid-switch",
1991 &m->polkit_registry,
1996 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1998 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2002 r = sd_bus_creds_get_euid(creds, &uid);
2006 r = sd_bus_creds_get_pid(creds, &pid);
2014 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2017 } while (hashmap_get(m->inhibitors, id));
2019 r = manager_add_inhibitor(m, id, &i);
2027 i->why = strdup(why);
2028 i->who = strdup(who);
2030 if (!i->why || !i->who) {
2035 fifo_fd = inhibitor_create_fifo(i);
2043 return sd_bus_reply_method_return(message, "h", fifo_fd);
2052 const sd_bus_vtable manager_vtable[] = {
2053 SD_BUS_VTABLE_START(0),
2055 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2056 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2057 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2058 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2059 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2060 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2061 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2062 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2063 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2064 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2065 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2066 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2067 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2068 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2069 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2070 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2071 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2072 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2073 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2074 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2076 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2077 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2078 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2079 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2080 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2081 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2082 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2084 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2085 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2086 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2087 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2088 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2089 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2090 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2091 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2092 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2094 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2095 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2096 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2097 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2099 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2100 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2101 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2102 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2104 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2105 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2106 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2107 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2108 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2109 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2110 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2111 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2112 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2113 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2115 SD_BUS_SIGNAL("SessionNew", "so", 0),
2116 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2117 SD_BUS_SIGNAL("UserNew", "uo", 0),
2118 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2119 SD_BUS_SIGNAL("SeatNew", "so", 0),
2120 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2121 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2122 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2127 int manager_send_changed(Manager *manager, const char *property, ...) {
2132 l = strv_from_stdarg_alloca(property);
2134 return sd_bus_emit_properties_changed_strv(
2136 "/org/freedesktop/login1",
2137 "org.freedesktop.login1.Manager",
2141 int manager_dispatch_delayed(Manager *manager) {
2142 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2143 Inhibitor *offending = NULL;
2148 if (manager->action_what == 0)
2151 /* Continue delay? */
2152 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2153 _cleanup_free_ char *comm = NULL, *u = NULL;
2155 get_process_comm(offending->pid, &comm);
2156 u = uid_to_name(offending->uid);
2158 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2161 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2162 offending->uid, strna(u),
2163 offending->pid, strna(comm));
2166 /* Actually do the operation */
2167 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
2169 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2171 manager->pending_action = HANDLE_IGNORE;
2172 manager->action_what = 0;