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_message_handler_t method,
1530 sd_bus_error *error) {
1532 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1533 bool multiple_sessions, blocked;
1540 assert(w <= _INHIBIT_WHAT_MAX);
1542 assert(action_multiple_sessions);
1543 assert(action_ignore_inhibit);
1546 r = sd_bus_message_read(message, "b", &interactive);
1550 /* Don't allow multiple jobs being executed at the same time */
1552 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1555 r = can_sleep(sleep_verb);
1560 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1563 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1567 r = sd_bus_creds_get_euid(creds, &uid);
1571 r = have_multiple_sessions(m, uid);
1575 multiple_sessions = r > 0;
1576 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1578 if (multiple_sessions) {
1579 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1583 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1587 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1591 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1594 if (!multiple_sessions && !blocked) {
1595 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1599 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1602 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1606 return sd_bus_reply_method_return(message, NULL);
1609 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1610 Manager *m = userdata;
1612 return method_do_shutdown_or_sleep(
1616 "org.freedesktop.login1.power-off",
1617 "org.freedesktop.login1.power-off-multiple-sessions",
1618 "org.freedesktop.login1.power-off-ignore-inhibit",
1624 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1625 Manager *m = userdata;
1627 return method_do_shutdown_or_sleep(
1631 "org.freedesktop.login1.reboot",
1632 "org.freedesktop.login1.reboot-multiple-sessions",
1633 "org.freedesktop.login1.reboot-ignore-inhibit",
1639 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1640 Manager *m = userdata;
1642 return method_do_shutdown_or_sleep(
1646 "org.freedesktop.login1.suspend",
1647 "org.freedesktop.login1.suspend-multiple-sessions",
1648 "org.freedesktop.login1.suspend-ignore-inhibit",
1654 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1655 Manager *m = userdata;
1657 return method_do_shutdown_or_sleep(
1661 "org.freedesktop.login1.hibernate",
1662 "org.freedesktop.login1.hibernate-multiple-sessions",
1663 "org.freedesktop.login1.hibernate-ignore-inhibit",
1669 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1670 Manager *m = userdata;
1672 return method_do_shutdown_or_sleep(
1674 HANDLE_HYBRID_SLEEP,
1676 "org.freedesktop.login1.hibernate",
1677 "org.freedesktop.login1.hibernate-multiple-sessions",
1678 "org.freedesktop.login1.hibernate-ignore-inhibit",
1680 method_hybrid_sleep,
1684 static int method_can_shutdown_or_sleep(
1686 sd_bus_message *message,
1689 const char *action_multiple_sessions,
1690 const char *action_ignore_inhibit,
1691 const char *sleep_verb,
1692 sd_bus_error *error) {
1694 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1695 bool multiple_sessions, challenge, blocked;
1696 const char *result = NULL;
1703 assert(w <= _INHIBIT_WHAT_MAX);
1705 assert(action_multiple_sessions);
1706 assert(action_ignore_inhibit);
1709 r = can_sleep(sleep_verb);
1713 return sd_bus_reply_method_return(message, "s", "na");
1716 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1720 r = sd_bus_creds_get_euid(creds, &uid);
1724 r = have_multiple_sessions(m, uid);
1728 multiple_sessions = r > 0;
1729 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1731 if (multiple_sessions) {
1732 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1739 result = "challenge";
1745 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1749 if (r > 0 && !result)
1751 else if (challenge && (!result || streq(result, "yes")))
1752 result = "challenge";
1757 if (!multiple_sessions && !blocked) {
1758 /* If neither inhibit nor multiple sessions
1759 * apply then just check the normal policy */
1761 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1768 result = "challenge";
1773 return sd_bus_reply_method_return(message, "s", result);
1776 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1777 Manager *m = userdata;
1779 return method_can_shutdown_or_sleep(
1782 "org.freedesktop.login1.power-off",
1783 "org.freedesktop.login1.power-off-multiple-sessions",
1784 "org.freedesktop.login1.power-off-ignore-inhibit",
1789 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1790 Manager *m = userdata;
1792 return method_can_shutdown_or_sleep(
1795 "org.freedesktop.login1.reboot",
1796 "org.freedesktop.login1.reboot-multiple-sessions",
1797 "org.freedesktop.login1.reboot-ignore-inhibit",
1802 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1803 Manager *m = userdata;
1805 return method_can_shutdown_or_sleep(
1808 "org.freedesktop.login1.suspend",
1809 "org.freedesktop.login1.suspend-multiple-sessions",
1810 "org.freedesktop.login1.suspend-ignore-inhibit",
1815 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1816 Manager *m = userdata;
1818 return method_can_shutdown_or_sleep(
1821 "org.freedesktop.login1.hibernate",
1822 "org.freedesktop.login1.hibernate-multiple-sessions",
1823 "org.freedesktop.login1.hibernate-ignore-inhibit",
1828 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1829 Manager *m = userdata;
1831 return method_can_shutdown_or_sleep(
1834 "org.freedesktop.login1.hibernate",
1835 "org.freedesktop.login1.hibernate-multiple-sessions",
1836 "org.freedesktop.login1.hibernate-ignore-inhibit",
1841 static int property_get_reboot_to_firmware_setup(
1844 const char *interface,
1845 const char *property,
1846 sd_bus_message *reply,
1848 sd_bus_error *error) {
1855 r = efi_get_reboot_to_firmware();
1856 if (r < 0 && r != -EOPNOTSUPP)
1859 return sd_bus_message_append(reply, "b", r > 0);
1862 static int method_set_reboot_to_firmware_setup(
1864 sd_bus_message *message,
1866 sd_bus_error *error) {
1869 Manager *m = userdata;
1875 r = sd_bus_message_read(message, "b", &b);
1879 r = bus_verify_polkit_async(message,
1881 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1884 &m->polkit_registry,
1889 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1891 r = efi_set_reboot_to_firmware(b);
1895 return sd_bus_reply_method_return(message, NULL);
1898 static int method_can_reboot_to_firmware_setup(
1900 sd_bus_message *message,
1902 sd_bus_error *error) {
1907 Manager *m = userdata;
1913 r = efi_reboot_to_firmware_supported();
1914 if (r == -EOPNOTSUPP)
1915 return sd_bus_reply_method_return(message, "s", "na");
1919 r = bus_test_polkit(message,
1921 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1931 result = "challenge";
1935 return sd_bus_reply_method_return(message, "s", result);
1938 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1939 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1940 const char *who, *why, *what, *mode;
1941 _cleanup_free_ char *id = NULL;
1942 _cleanup_close_ int fifo_fd = -1;
1943 Manager *m = userdata;
1944 Inhibitor *i = NULL;
1955 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1959 w = inhibit_what_from_string(what);
1961 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1963 mm = inhibit_mode_from_string(mode);
1965 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1967 /* Delay is only supported for shutdown/sleep */
1968 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1969 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1971 /* Don't allow taking delay locks while we are already
1972 * executing the operation. We shouldn't create the impression
1973 * that the lock was successful if the machine is about to go
1974 * down/suspend any moment. */
1975 if (m->action_what & w)
1976 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1978 r = bus_verify_polkit_async(
1981 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1982 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1983 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1984 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1985 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1986 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1987 "org.freedesktop.login1.inhibit-handle-lid-switch",
1990 &m->polkit_registry,
1995 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1997 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2001 r = sd_bus_creds_get_euid(creds, &uid);
2005 r = sd_bus_creds_get_pid(creds, &pid);
2013 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2016 } while (hashmap_get(m->inhibitors, id));
2018 r = manager_add_inhibitor(m, id, &i);
2026 i->why = strdup(why);
2027 i->who = strdup(who);
2029 if (!i->why || !i->who) {
2034 fifo_fd = inhibitor_create_fifo(i);
2042 return sd_bus_reply_method_return(message, "h", fifo_fd);
2051 const sd_bus_vtable manager_vtable[] = {
2052 SD_BUS_VTABLE_START(0),
2054 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2055 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2056 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2057 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2058 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2059 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2060 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2061 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2062 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2063 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2064 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2065 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2066 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2067 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2068 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2069 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2070 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2071 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2072 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2073 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2075 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2076 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2077 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2078 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2079 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2080 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2081 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2082 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2084 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2085 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2086 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2087 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2088 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2089 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2090 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2091 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2092 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2094 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2095 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2096 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2097 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2099 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2100 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2101 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2102 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2104 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2105 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2106 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2107 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2108 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2109 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2110 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2111 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2112 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2114 SD_BUS_SIGNAL("SessionNew", "so", 0),
2115 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2116 SD_BUS_SIGNAL("UserNew", "uo", 0),
2117 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2118 SD_BUS_SIGNAL("SeatNew", "so", 0),
2119 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2120 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2121 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2126 int manager_send_changed(Manager *manager, const char *property, ...) {
2131 l = strv_from_stdarg_alloca(property);
2133 return sd_bus_emit_properties_changed_strv(
2135 "/org/freedesktop/login1",
2136 "org.freedesktop.login1.Manager",
2140 int manager_dispatch_delayed(Manager *manager) {
2141 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2142 Inhibitor *offending = NULL;
2147 if (manager->action_what == 0)
2150 /* Continue delay? */
2151 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2152 _cleanup_free_ char *comm = NULL, *u = NULL;
2154 get_process_comm(offending->pid, &comm);
2155 u = uid_to_name(offending->uid);
2157 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2160 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2161 offending->uid, strna(u),
2162 offending->pid, strna(comm));
2165 /* Actually do the operation */
2166 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
2168 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2170 manager->pending_action = HANDLE_IGNORE;
2171 manager->action_what = 0;