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"
44 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
45 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
54 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
58 r = sd_bus_creds_get_session(creds, &name);
63 session = hashmap_get(m->sessions, name);
65 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
71 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
79 if (uid == UID_INVALID) {
80 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
82 /* Note that we get the owner UID of the session, not the actual client UID here! */
83 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
87 r = sd_bus_creds_get_owner_uid(creds, &uid);
92 user = hashmap_get(m->users, UID_TO_PTR(uid));
94 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
100 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
111 r = manager_get_session_from_creds(m, message, NULL, error, &session);
115 seat = session->seat;
118 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
120 seat = hashmap_get(m->seats, name);
122 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
129 static int property_get_idle_hint(
132 const char *interface,
133 const char *property,
134 sd_bus_message *reply,
136 sd_bus_error *error) {
138 Manager *m = userdata;
144 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
147 static int property_get_idle_since_hint(
150 const char *interface,
151 const char *property,
152 sd_bus_message *reply,
154 sd_bus_error *error) {
156 Manager *m = userdata;
163 manager_get_idle_hint(m, &t);
165 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
168 static int property_get_inhibited(
171 const char *interface,
172 const char *property,
173 sd_bus_message *reply,
175 sd_bus_error *error) {
177 Manager *m = userdata;
184 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
186 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
189 static int property_get_preparing(
192 const char *interface,
193 const char *property,
194 sd_bus_message *reply,
196 sd_bus_error *error) {
198 Manager *m = userdata;
205 if (streq(property, "PreparingForShutdown"))
206 b = !!(m->action_what & INHIBIT_SHUTDOWN);
208 b = !!(m->action_what & INHIBIT_SLEEP);
210 return sd_bus_message_append(reply, "b", b);
213 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
215 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
216 _cleanup_free_ char *p = NULL;
217 Manager *m = userdata;
226 r = sd_bus_message_read(message, "s", &name);
230 r = manager_get_session_from_creds(m, message, name, error, &session);
234 p = session_bus_path(session);
238 return sd_bus_reply_method_return(message, "o", p);
241 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
242 _cleanup_free_ char *p = NULL;
243 Session *session = NULL;
244 Manager *m = userdata;
252 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
254 r = sd_bus_message_read(message, "u", &pid);
259 r = manager_get_session_from_creds(m, message, NULL, error, &session);
263 r = manager_get_session_by_pid(m, pid, &session);
268 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
271 p = session_bus_path(session);
275 return sd_bus_reply_method_return(message, "o", p);
278 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
279 _cleanup_free_ char *p = NULL;
280 Manager *m = userdata;
289 r = sd_bus_message_read(message, "u", &uid);
293 r = manager_get_user_from_creds(m, message, uid, error, &user);
297 p = user_bus_path(user);
301 return sd_bus_reply_method_return(message, "o", p);
304 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
305 _cleanup_free_ char *p = NULL;
306 Manager *m = userdata;
315 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
317 r = sd_bus_message_read(message, "u", &pid);
322 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
326 r = manager_get_user_by_pid(m, pid, &user);
330 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);
333 p = user_bus_path(user);
337 return sd_bus_reply_method_return(message, "o", p);
340 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
341 _cleanup_free_ char *p = NULL;
342 Manager *m = userdata;
351 r = sd_bus_message_read(message, "s", &name);
355 r = manager_get_seat_from_creds(m, message, name, error, &seat);
359 p = seat_bus_path(seat);
363 return sd_bus_reply_method_return(message, "o", p);
366 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
367 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
368 Manager *m = userdata;
377 r = sd_bus_message_new_method_return(message, &reply);
381 r = sd_bus_message_open_container(reply, 'a', "(susso)");
385 HASHMAP_FOREACH(session, m->sessions, i) {
386 _cleanup_free_ char *p = NULL;
388 p = session_bus_path(session);
392 r = sd_bus_message_append(reply, "(susso)",
394 (uint32_t) session->user->uid,
396 session->seat ? session->seat->id : "",
402 r = sd_bus_message_close_container(reply);
406 return sd_bus_send(bus, reply, NULL);
409 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
410 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
411 Manager *m = userdata;
420 r = sd_bus_message_new_method_return(message, &reply);
424 r = sd_bus_message_open_container(reply, 'a', "(uso)");
428 HASHMAP_FOREACH(user, m->users, i) {
429 _cleanup_free_ char *p = NULL;
431 p = user_bus_path(user);
435 r = sd_bus_message_append(reply, "(uso)",
436 (uint32_t) user->uid,
443 r = sd_bus_message_close_container(reply);
447 return sd_bus_send(bus, reply, NULL);
450 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
451 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
452 Manager *m = userdata;
461 r = sd_bus_message_new_method_return(message, &reply);
465 r = sd_bus_message_open_container(reply, 'a', "(so)");
469 HASHMAP_FOREACH(seat, m->seats, i) {
470 _cleanup_free_ char *p = NULL;
472 p = seat_bus_path(seat);
476 r = sd_bus_message_append(reply, "(so)", seat->id, p);
481 r = sd_bus_message_close_container(reply);
485 return sd_bus_send(bus, reply, NULL);
488 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
489 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
490 Manager *m = userdata;
491 Inhibitor *inhibitor;
495 r = sd_bus_message_new_method_return(message, &reply);
499 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
503 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
505 r = sd_bus_message_append(reply, "(ssssuu)",
506 strempty(inhibit_what_to_string(inhibitor->what)),
507 strempty(inhibitor->who),
508 strempty(inhibitor->why),
509 strempty(inhibit_mode_to_string(inhibitor->mode)),
510 (uint32_t) inhibitor->uid,
511 (uint32_t) inhibitor->pid);
516 r = sd_bus_message_close_container(reply);
520 return sd_bus_send(bus, reply, NULL);
523 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
524 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
525 uint32_t uid, leader, audit_id = 0;
526 _cleanup_free_ char *id = NULL;
527 Session *session = NULL;
528 Manager *m = userdata;
541 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
546 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
549 t = _SESSION_TYPE_INVALID;
551 t = session_type_from_string(type);
553 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
557 c = _SESSION_CLASS_INVALID;
559 c = session_class_from_string(class);
561 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
564 if (isempty(desktop))
567 if (!string_is_safe(desktop))
568 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
574 seat = hashmap_get(m->seats, cseat);
576 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
579 if (tty_is_vc(tty)) {
584 else if (seat != m->seat0)
585 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);
587 v = vtnr_from_tty(tty);
589 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
593 else if (vtnr != (uint32_t) v)
594 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
596 } else if (tty_is_console(tty)) {
600 else if (seat != m->seat0)
601 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
608 if (seat_has_vts(seat)) {
609 if (!vtnr || vtnr > 63)
610 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
613 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
617 r = sd_bus_message_enter_container(message, 'a', "(sv)");
621 if (t == _SESSION_TYPE_INVALID) {
622 if (!isempty(display))
624 else if (!isempty(tty))
627 t = SESSION_UNSPECIFIED;
630 if (c == _SESSION_CLASS_INVALID) {
631 if (t == SESSION_UNSPECIFIED)
632 c = SESSION_BACKGROUND;
638 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
640 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
644 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
649 manager_get_session_by_pid(m, leader, &session);
651 _cleanup_free_ char *path = NULL;
652 _cleanup_close_ int fifo_fd = -1;
654 /* Session already exists, client is probably
655 * something like "su" which changes uid but is still
656 * the same session */
658 fifo_fd = session_create_fifo(session);
662 path = session_bus_path(session);
666 log_debug("Sending reply about an existing session: "
667 "id=%s object_path=%s uid=%u runtime_path=%s "
668 "session_fd=%d seat=%s vtnr=%u",
671 (uint32_t) session->user->uid,
672 session->user->runtime_path,
674 session->seat ? session->seat->id : "",
675 (uint32_t) session->vtnr);
677 return sd_bus_reply_method_return(
681 session->user->runtime_path,
683 (uint32_t) session->user->uid,
684 session->seat ? session->seat->id : "",
685 (uint32_t) session->vtnr,
689 audit_session_from_pid(leader, &audit_id);
691 /* Keep our session IDs and the audit session IDs in sync */
693 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
696 /* Wut? There's already a session by this name and we
697 * didn't find it above? Weird, then let's not trust
698 * the audit data and let's better register a new
700 if (hashmap_get(m->sessions, id)) {
701 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
714 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
717 } while (hashmap_get(m->sessions, id));
720 r = manager_add_user_by_uid(m, uid, &user);
724 r = manager_add_session(m, id, &session);
728 session_set_user(session, user);
730 session->leader = leader;
731 session->audit_id = audit_id;
734 session->remote = remote;
735 session->vtnr = vtnr;
738 session->tty = strdup(tty);
745 if (!isempty(display)) {
746 session->display = strdup(display);
747 if (!session->display) {
753 if (!isempty(remote_user)) {
754 session->remote_user = strdup(remote_user);
755 if (!session->remote_user) {
761 if (!isempty(remote_host)) {
762 session->remote_host = strdup(remote_host);
763 if (!session->remote_host) {
769 if (!isempty(service)) {
770 session->service = strdup(service);
771 if (!session->service) {
777 if (!isempty(desktop)) {
778 session->desktop = strdup(desktop);
779 if (!session->desktop) {
786 r = seat_attach_session(seat, session);
791 r = session_start(session);
795 session->create_message = sd_bus_message_ref(message);
797 /* Here upstream systemd starts cgroups and the user systemd,
798 and arranges to reply asynchronously. We reply
801 r = session_send_create_reply(session, NULL);
809 session_add_to_gc_queue(session);
812 user_add_to_gc_queue(user);
817 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
818 Manager *m = userdata;
827 r = sd_bus_message_read(message, "s", &name);
831 r = manager_get_session_from_creds(m, message, name, error, &session);
835 r = session_release(session);
839 session_add_to_gc_queue(session);
841 return sd_bus_reply_method_return(message, NULL);
844 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
845 Manager *m = userdata;
854 r = sd_bus_message_read(message, "s", &name);
858 r = manager_get_session_from_creds(m, message, name, error, &session);
862 return bus_session_method_activate(bus, message, session, error);
865 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
866 const char *session_name, *seat_name;
867 Manager *m = userdata;
876 /* Same as ActivateSession() but refuses to work if
877 * the seat doesn't match */
879 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
883 r = manager_get_session_from_creds(m, message, session_name, error, &session);
887 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
891 if (session->seat != seat)
892 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
894 r = session_activate(session);
898 return sd_bus_reply_method_return(message, NULL);
901 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
902 Manager *m = userdata;
911 r = sd_bus_message_read(message, "s", &name);
915 r = manager_get_session_from_creds(m, message, name, error, &session);
919 return bus_session_method_lock(bus, message, session, error);
922 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
923 Manager *m = userdata;
930 r = bus_verify_polkit_async(
933 "org.freedesktop.login1.lock-sessions",
941 return 1; /* Will call us back */
943 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
947 return sd_bus_reply_method_return(message, NULL);
950 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
952 Manager *m = userdata;
960 r = sd_bus_message_read(message, "s", &name);
964 r = manager_get_session_from_creds(m, message, name, error, &session);
968 return bus_session_method_kill(bus, message, session, error);
971 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
972 Manager *m = userdata;
981 r = sd_bus_message_read(message, "u", &uid);
985 r = manager_get_user_from_creds(m, message, uid, error, &user);
989 return bus_user_method_kill(bus, message, user, error);
992 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
993 Manager *m = userdata;
1002 r = sd_bus_message_read(message, "s", &name);
1006 r = manager_get_session_from_creds(m, message, name, error, &session);
1010 return bus_session_method_terminate(bus, message, session, error);
1013 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1014 Manager *m = userdata;
1023 r = sd_bus_message_read(message, "u", &uid);
1027 r = manager_get_user_from_creds(m, message, uid, error, &user);
1031 return bus_user_method_terminate(bus, message, user, error);
1034 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1035 Manager *m = userdata;
1044 r = sd_bus_message_read(message, "s", &name);
1048 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1052 return bus_seat_method_terminate(bus, message, seat, error);
1055 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1056 _cleanup_free_ char *cc = NULL;
1057 Manager *m = userdata;
1068 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1072 if (uid == UID_INVALID) {
1073 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1075 /* Note that we get the owner UID of the session, not the actual client UID here! */
1076 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1080 r = sd_bus_creds_get_owner_uid(creds, &uid);
1088 return errno ? -errno : -ENOENT;
1090 r = bus_verify_polkit_async(
1093 "org.freedesktop.login1.set-user-linger",
1096 &m->polkit_registry,
1101 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1103 mkdir_p_label("/var/lib/systemd", 0755);
1105 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1109 cc = cescape(pw->pw_name);
1113 path = strjoina("/var/lib/systemd/linger/", cc);
1121 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1128 if (r < 0 && errno != ENOENT)
1131 u = hashmap_get(m->users, UID_TO_PTR(uid));
1133 user_add_to_gc_queue(u);
1136 return sd_bus_reply_method_return(message, NULL);
1139 static int trigger_device(Manager *m, struct udev_device *d) {
1140 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1141 struct udev_list_entry *first, *item;
1146 e = udev_enumerate_new(m->udev);
1151 r = udev_enumerate_add_match_parent(e, d);
1156 r = udev_enumerate_scan_devices(e);
1160 first = udev_enumerate_get_list_entry(e);
1161 udev_list_entry_foreach(item, first) {
1162 _cleanup_free_ char *t = NULL;
1165 p = udev_list_entry_get_name(item);
1167 t = strappend(p, "/uevent");
1171 write_string_file(t, "change");
1177 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1178 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1179 _cleanup_free_ char *rule = NULL, *file = NULL;
1180 const char *id_for_seat;
1187 d = udev_device_new_from_syspath(m->udev, sysfs);
1191 if (!udev_device_has_tag(d, "seat"))
1194 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1198 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1201 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1204 mkdir_p_label("/etc/udev/rules.d", 0755);
1205 mac_selinux_init("/etc");
1206 r = write_string_file_atomic_label(file, rule);
1210 return trigger_device(m, d);
1213 static int flush_devices(Manager *m) {
1214 _cleanup_closedir_ DIR *d;
1218 d = opendir("/etc/udev/rules.d");
1220 if (errno != ENOENT)
1221 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1225 while ((de = readdir(d))) {
1227 if (!dirent_is_file(de))
1230 if (!startswith(de->d_name, "72-seat-"))
1233 if (!endswith(de->d_name, ".rules"))
1236 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1237 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1241 return trigger_device(m, NULL);
1244 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1245 const char *sysfs, *seat;
1246 Manager *m = userdata;
1253 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1257 if (!path_startswith(sysfs, "/sys"))
1258 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1260 if (!seat_name_is_valid(seat))
1261 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1263 r = bus_verify_polkit_async(
1266 "org.freedesktop.login1.attach-device",
1269 &m->polkit_registry,
1274 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1276 r = attach_device(m, seat, sysfs);
1280 return sd_bus_reply_method_return(message, NULL);
1283 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1284 Manager *m = userdata;
1291 r = sd_bus_message_read(message, "b", &interactive);
1295 r = bus_verify_polkit_async(
1298 "org.freedesktop.login1.flush-devices",
1301 &m->polkit_registry,
1306 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1308 r = flush_devices(m);
1312 return sd_bus_reply_method_return(message, NULL);
1315 static int have_multiple_sessions(
1324 /* Check for other users' sessions. Greeter sessions do not
1325 * count, and non-login sessions do not count either. */
1326 HASHMAP_FOREACH(session, m->sessions, i)
1327 if (session->class == SESSION_USER &&
1328 session->user->uid != uid)
1334 static int bus_manager_log_shutdown(
1337 HandleAction action) {
1343 if (w != INHIBIT_SHUTDOWN)
1347 case HANDLE_POWEROFF:
1348 p = "MESSAGE=System is powering down.";
1349 q = "SHUTDOWN=power-off";
1352 p = "MESSAGE=System is halting.";
1353 q = "SHUTDOWN=halt";
1356 p = "MESSAGE=System is rebooting.";
1357 q = "SHUTDOWN=reboot";
1360 p = "MESSAGE=System is rebooting with kexec.";
1361 q = "SHUTDOWN=kexec";
1364 p = "MESSAGE=System is shutting down.";
1369 return log_struct(LOG_NOTICE,
1370 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1376 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1377 Manager *m = userdata;
1382 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1386 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1391 if (until <= now(CLOCK_MONOTONIC))
1394 /* We want to ignore the lid switch for a while after each
1395 * suspend, and after boot-up. Hence let's install a timer for
1396 * this. As long as the event source exists we ignore the lid
1399 if (m->lid_switch_ignore_event_source) {
1402 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1409 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1411 r = sd_event_add_time(
1413 &m->lid_switch_ignore_event_source,
1416 lid_switch_ignore_handler, m);
1421 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1423 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1424 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1425 [INHIBIT_SLEEP] = "PrepareForSleep"
1428 int active = _active;
1432 assert(w < _INHIBIT_WHAT_MAX);
1433 assert(signal_name[w]);
1435 return sd_bus_emit_signal(m->bus,
1436 "/org/freedesktop/login1",
1437 "org.freedesktop.login1.Manager",
1443 static int execute_shutdown_or_sleep(
1446 HandleAction action,
1447 sd_bus_error *error) {
1452 assert(w < _INHIBIT_WHAT_MAX);
1454 bus_manager_log_shutdown(m, w, action);
1456 r = shutdown_or_sleep(m, action);
1460 if (w == INHIBIT_SLEEP)
1461 /* And we're back. */
1462 send_prepare_for(m, w, false);
1466 /* Make sure the lid switch is ignored for a while (?) */
1467 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1472 static int delay_shutdown_or_sleep(
1475 HandleAction action) {
1479 assert(w < _INHIBIT_WHAT_MAX);
1481 m->action_timestamp = now(CLOCK_MONOTONIC);
1482 m->pending_action = action;
1488 int bus_manager_shutdown_or_sleep_now_or_later(
1490 HandleAction action,
1492 sd_bus_error *error) {
1499 assert(w <= _INHIBIT_WHAT_MAX);
1501 /* Tell everybody to prepare for shutdown/sleep */
1502 send_prepare_for(m, w, true);
1505 m->inhibit_delay_max > 0 &&
1506 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1509 /* Shutdown is delayed, keep in mind what we
1510 * want to do, and start a timeout */
1511 r = delay_shutdown_or_sleep(m, w, action);
1513 /* Shutdown is not delayed, execute it
1515 r = execute_shutdown_or_sleep(m, w, action, error);
1520 static int method_do_shutdown_or_sleep(
1522 sd_bus_message *message,
1523 HandleAction sleep_action,
1526 const char *action_multiple_sessions,
1527 const char *action_ignore_inhibit,
1528 const char *sleep_verb,
1529 sd_bus_error *error) {
1531 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1532 bool multiple_sessions, blocked;
1539 assert(w <= _INHIBIT_WHAT_MAX);
1541 assert(action_multiple_sessions);
1542 assert(action_ignore_inhibit);
1544 r = sd_bus_message_read(message, "b", &interactive);
1548 /* Don't allow multiple jobs being executed at the same time */
1550 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1553 r = can_sleep(sleep_verb);
1558 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1561 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1565 r = sd_bus_creds_get_euid(creds, &uid);
1569 r = have_multiple_sessions(m, uid);
1573 multiple_sessions = r > 0;
1574 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1576 if (multiple_sessions) {
1577 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1581 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1585 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1589 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1592 if (!multiple_sessions && !blocked) {
1593 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1597 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1600 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1604 return sd_bus_reply_method_return(message, NULL);
1607 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1608 Manager *m = userdata;
1610 return method_do_shutdown_or_sleep(
1614 "org.freedesktop.login1.power-off",
1615 "org.freedesktop.login1.power-off-multiple-sessions",
1616 "org.freedesktop.login1.power-off-ignore-inhibit",
1621 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1622 Manager *m = userdata;
1624 return method_do_shutdown_or_sleep(
1628 "org.freedesktop.login1.reboot",
1629 "org.freedesktop.login1.reboot-multiple-sessions",
1630 "org.freedesktop.login1.reboot-ignore-inhibit",
1635 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1636 Manager *m = userdata;
1638 return method_do_shutdown_or_sleep(
1642 "org.freedesktop.login1.suspend",
1643 "org.freedesktop.login1.suspend-multiple-sessions",
1644 "org.freedesktop.login1.suspend-ignore-inhibit",
1649 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1650 Manager *m = userdata;
1652 return method_do_shutdown_or_sleep(
1656 "org.freedesktop.login1.hibernate",
1657 "org.freedesktop.login1.hibernate-multiple-sessions",
1658 "org.freedesktop.login1.hibernate-ignore-inhibit",
1663 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1664 Manager *m = userdata;
1666 return method_do_shutdown_or_sleep(
1668 HANDLE_HYBRID_SLEEP,
1670 "org.freedesktop.login1.hibernate",
1671 "org.freedesktop.login1.hibernate-multiple-sessions",
1672 "org.freedesktop.login1.hibernate-ignore-inhibit",
1677 static int method_can_shutdown_or_sleep(
1679 sd_bus_message *message,
1682 const char *action_multiple_sessions,
1683 const char *action_ignore_inhibit,
1684 const char *sleep_verb,
1685 sd_bus_error *error) {
1687 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1688 bool multiple_sessions, challenge, blocked;
1689 const char *result = NULL;
1696 assert(w <= _INHIBIT_WHAT_MAX);
1698 assert(action_multiple_sessions);
1699 assert(action_ignore_inhibit);
1702 r = can_sleep(sleep_verb);
1706 return sd_bus_reply_method_return(message, "s", "na");
1709 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1713 r = sd_bus_creds_get_euid(creds, &uid);
1717 r = have_multiple_sessions(m, uid);
1721 multiple_sessions = r > 0;
1722 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1724 if (multiple_sessions) {
1725 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1732 result = "challenge";
1738 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1742 if (r > 0 && !result)
1744 else if (challenge && (!result || streq(result, "yes")))
1745 result = "challenge";
1750 if (!multiple_sessions && !blocked) {
1751 /* If neither inhibit nor multiple sessions
1752 * apply then just check the normal policy */
1754 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1761 result = "challenge";
1766 return sd_bus_reply_method_return(message, "s", result);
1769 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1770 Manager *m = userdata;
1772 return method_can_shutdown_or_sleep(
1775 "org.freedesktop.login1.power-off",
1776 "org.freedesktop.login1.power-off-multiple-sessions",
1777 "org.freedesktop.login1.power-off-ignore-inhibit",
1782 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1783 Manager *m = userdata;
1785 return method_can_shutdown_or_sleep(
1788 "org.freedesktop.login1.reboot",
1789 "org.freedesktop.login1.reboot-multiple-sessions",
1790 "org.freedesktop.login1.reboot-ignore-inhibit",
1795 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1796 Manager *m = userdata;
1798 return method_can_shutdown_or_sleep(
1801 "org.freedesktop.login1.suspend",
1802 "org.freedesktop.login1.suspend-multiple-sessions",
1803 "org.freedesktop.login1.suspend-ignore-inhibit",
1808 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1809 Manager *m = userdata;
1811 return method_can_shutdown_or_sleep(
1814 "org.freedesktop.login1.hibernate",
1815 "org.freedesktop.login1.hibernate-multiple-sessions",
1816 "org.freedesktop.login1.hibernate-ignore-inhibit",
1821 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1822 Manager *m = userdata;
1824 return method_can_shutdown_or_sleep(
1827 "org.freedesktop.login1.hibernate",
1828 "org.freedesktop.login1.hibernate-multiple-sessions",
1829 "org.freedesktop.login1.hibernate-ignore-inhibit",
1834 static int property_get_reboot_to_firmware_setup(
1837 const char *interface,
1838 const char *property,
1839 sd_bus_message *reply,
1841 sd_bus_error *error) {
1848 r = efi_get_reboot_to_firmware();
1849 if (r < 0 && r != -EOPNOTSUPP)
1852 return sd_bus_message_append(reply, "b", r > 0);
1855 static int method_set_reboot_to_firmware_setup(
1857 sd_bus_message *message,
1859 sd_bus_error *error) {
1862 Manager *m = userdata;
1868 r = sd_bus_message_read(message, "b", &b);
1872 r = bus_verify_polkit_async(message,
1874 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1877 &m->polkit_registry,
1882 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1884 r = efi_set_reboot_to_firmware(b);
1888 return sd_bus_reply_method_return(message, NULL);
1891 static int method_can_reboot_to_firmware_setup(
1893 sd_bus_message *message,
1895 sd_bus_error *error) {
1900 Manager *m = userdata;
1906 r = efi_reboot_to_firmware_supported();
1907 if (r == -EOPNOTSUPP)
1908 return sd_bus_reply_method_return(message, "s", "na");
1912 r = bus_test_polkit(message,
1914 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1924 result = "challenge";
1928 return sd_bus_reply_method_return(message, "s", result);
1931 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1932 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1933 const char *who, *why, *what, *mode;
1934 _cleanup_free_ char *id = NULL;
1935 _cleanup_close_ int fifo_fd = -1;
1936 Manager *m = userdata;
1937 Inhibitor *i = NULL;
1948 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1952 w = inhibit_what_from_string(what);
1954 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1956 mm = inhibit_mode_from_string(mode);
1958 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1960 /* Delay is only supported for shutdown/sleep */
1961 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1962 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1964 /* Don't allow taking delay locks while we are already
1965 * executing the operation. We shouldn't create the impression
1966 * that the lock was successful if the machine is about to go
1967 * down/suspend any moment. */
1968 if (m->action_what & w)
1969 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1971 r = bus_verify_polkit_async(
1974 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1975 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1976 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1977 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1978 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1979 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1980 "org.freedesktop.login1.inhibit-handle-lid-switch",
1983 &m->polkit_registry,
1988 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1990 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
1994 r = sd_bus_creds_get_euid(creds, &uid);
1998 r = sd_bus_creds_get_pid(creds, &pid);
2006 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2009 } while (hashmap_get(m->inhibitors, id));
2011 r = manager_add_inhibitor(m, id, &i);
2019 i->why = strdup(why);
2020 i->who = strdup(who);
2022 if (!i->why || !i->who) {
2027 fifo_fd = inhibitor_create_fifo(i);
2035 return sd_bus_reply_method_return(message, "h", fifo_fd);
2044 const sd_bus_vtable manager_vtable[] = {
2045 SD_BUS_VTABLE_START(0),
2047 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2048 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2049 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2050 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2051 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2052 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2053 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2054 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2055 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2056 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2057 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2058 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2059 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2060 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2061 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2062 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2063 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2064 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2065 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2066 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2068 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2069 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2070 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2071 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2072 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2073 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2074 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2075 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2076 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2077 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2078 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2079 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2080 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2081 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2082 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2084 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2085 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2086 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2087 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2088 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2089 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2090 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2091 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2092 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2094 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2095 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2096 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2097 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2099 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2100 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2101 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2102 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2104 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2105 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2107 SD_BUS_SIGNAL("SessionNew", "so", 0),
2108 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2109 SD_BUS_SIGNAL("UserNew", "uo", 0),
2110 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2111 SD_BUS_SIGNAL("SeatNew", "so", 0),
2112 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2113 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2114 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2119 int manager_send_changed(Manager *manager, const char *property, ...) {
2124 l = strv_from_stdarg_alloca(property);
2126 return sd_bus_emit_properties_changed_strv(
2128 "/org/freedesktop/login1",
2129 "org.freedesktop.login1.Manager",
2133 int manager_dispatch_delayed(Manager *manager) {
2134 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2135 Inhibitor *offending = NULL;
2140 if (manager->action_what == 0)
2143 /* Continue delay? */
2144 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2145 _cleanup_free_ char *comm = NULL, *u = NULL;
2147 get_process_comm(offending->pid, &comm);
2148 u = uid_to_name(offending->uid);
2150 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2153 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2154 offending->uid, strna(u),
2155 offending->pid, strna(comm));
2158 /* Actually do the operation */
2159 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
2161 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2163 manager->pending_action = HANDLE_IGNORE;
2164 manager->action_what = 0;