1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
46 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
47 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
56 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
60 r = sd_bus_creds_get_session(creds, &name);
65 session = hashmap_get(m->sessions, name);
67 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
73 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
81 if (uid == UID_INVALID) {
82 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
84 /* Note that we get the owner UID of the session, not the actual client UID here! */
85 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
89 r = sd_bus_creds_get_owner_uid(creds, &uid);
94 user = hashmap_get(m->users, UID_TO_PTR(uid));
96 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
102 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
113 r = manager_get_session_from_creds(m, message, NULL, error, &session);
117 seat = session->seat;
120 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
122 seat = hashmap_get(m->seats, name);
124 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
131 static int property_get_idle_hint(
134 const char *interface,
135 const char *property,
136 sd_bus_message *reply,
138 sd_bus_error *error) {
140 Manager *m = userdata;
146 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
149 static int property_get_idle_since_hint(
152 const char *interface,
153 const char *property,
154 sd_bus_message *reply,
156 sd_bus_error *error) {
158 Manager *m = userdata;
165 manager_get_idle_hint(m, &t);
167 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
170 static int property_get_inhibited(
173 const char *interface,
174 const char *property,
175 sd_bus_message *reply,
177 sd_bus_error *error) {
179 Manager *m = userdata;
186 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
188 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
191 static int property_get_preparing(
194 const char *interface,
195 const char *property,
196 sd_bus_message *reply,
198 sd_bus_error *error) {
200 Manager *m = userdata;
207 if (streq(property, "PreparingForShutdown"))
208 b = !!(m->action_what & INHIBIT_SHUTDOWN);
210 b = !!(m->action_what & INHIBIT_SLEEP);
212 return sd_bus_message_append(reply, "b", b);
215 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
217 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
218 _cleanup_free_ char *p = NULL;
219 Manager *m = userdata;
228 r = sd_bus_message_read(message, "s", &name);
232 r = manager_get_session_from_creds(m, message, name, error, &session);
236 p = session_bus_path(session);
240 return sd_bus_reply_method_return(message, "o", p);
243 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
244 _cleanup_free_ char *p = NULL;
245 Session *session = NULL;
246 Manager *m = userdata;
254 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
256 r = sd_bus_message_read(message, "u", &pid);
261 r = manager_get_session_from_creds(m, message, NULL, error, &session);
265 r = manager_get_session_by_pid(m, pid, &session);
270 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
273 p = session_bus_path(session);
277 return sd_bus_reply_method_return(message, "o", p);
280 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
281 _cleanup_free_ char *p = NULL;
282 Manager *m = userdata;
291 r = sd_bus_message_read(message, "u", &uid);
295 r = manager_get_user_from_creds(m, message, uid, error, &user);
299 p = user_bus_path(user);
303 return sd_bus_reply_method_return(message, "o", p);
306 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
307 _cleanup_free_ char *p = NULL;
308 Manager *m = userdata;
317 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
319 r = sd_bus_message_read(message, "u", &pid);
324 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
328 r = manager_get_user_by_pid(m, pid, &user);
332 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);
335 p = user_bus_path(user);
339 return sd_bus_reply_method_return(message, "o", p);
342 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
343 _cleanup_free_ char *p = NULL;
344 Manager *m = userdata;
353 r = sd_bus_message_read(message, "s", &name);
357 r = manager_get_seat_from_creds(m, message, name, error, &seat);
361 p = seat_bus_path(seat);
365 return sd_bus_reply_method_return(message, "o", p);
368 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
369 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
370 Manager *m = userdata;
379 r = sd_bus_message_new_method_return(message, &reply);
383 r = sd_bus_message_open_container(reply, 'a', "(susso)");
387 HASHMAP_FOREACH(session, m->sessions, i) {
388 _cleanup_free_ char *p = NULL;
390 p = session_bus_path(session);
394 r = sd_bus_message_append(reply, "(susso)",
396 (uint32_t) session->user->uid,
398 session->seat ? session->seat->id : "",
404 r = sd_bus_message_close_container(reply);
408 return sd_bus_send(bus, reply, NULL);
411 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
412 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
413 Manager *m = userdata;
422 r = sd_bus_message_new_method_return(message, &reply);
426 r = sd_bus_message_open_container(reply, 'a', "(uso)");
430 HASHMAP_FOREACH(user, m->users, i) {
431 _cleanup_free_ char *p = NULL;
433 p = user_bus_path(user);
437 r = sd_bus_message_append(reply, "(uso)",
438 (uint32_t) user->uid,
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(bus, reply, NULL);
452 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
454 Manager *m = userdata;
463 r = sd_bus_message_new_method_return(message, &reply);
467 r = sd_bus_message_open_container(reply, 'a', "(so)");
471 HASHMAP_FOREACH(seat, m->seats, i) {
472 _cleanup_free_ char *p = NULL;
474 p = seat_bus_path(seat);
478 r = sd_bus_message_append(reply, "(so)", seat->id, p);
483 r = sd_bus_message_close_container(reply);
487 return sd_bus_send(bus, reply, NULL);
490 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
491 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
492 Manager *m = userdata;
493 Inhibitor *inhibitor;
497 r = sd_bus_message_new_method_return(message, &reply);
501 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
505 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
507 r = sd_bus_message_append(reply, "(ssssuu)",
508 strempty(inhibit_what_to_string(inhibitor->what)),
509 strempty(inhibitor->who),
510 strempty(inhibitor->why),
511 strempty(inhibit_mode_to_string(inhibitor->mode)),
512 (uint32_t) inhibitor->uid,
513 (uint32_t) inhibitor->pid);
518 r = sd_bus_message_close_container(reply);
522 return sd_bus_send(bus, reply, NULL);
525 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
526 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
527 uint32_t uid, leader, audit_id = 0;
528 _cleanup_free_ char *id = NULL;
529 Session *session = NULL;
530 Manager *m = userdata;
543 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
548 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
551 t = _SESSION_TYPE_INVALID;
553 t = session_type_from_string(type);
555 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
559 c = _SESSION_CLASS_INVALID;
561 c = session_class_from_string(class);
563 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
566 if (isempty(desktop))
569 if (!string_is_safe(desktop))
570 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
576 seat = hashmap_get(m->seats, cseat);
578 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
581 if (tty_is_vc(tty)) {
586 else if (seat != m->seat0)
587 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);
589 v = vtnr_from_tty(tty);
591 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
595 else if (vtnr != (uint32_t) v)
596 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
598 } else if (tty_is_console(tty)) {
602 else if (seat != m->seat0)
603 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
606 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
610 if (seat_has_vts(seat)) {
611 if (!vtnr || vtnr > 63)
612 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
615 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
619 r = sd_bus_message_enter_container(message, 'a', "(sv)");
623 if (t == _SESSION_TYPE_INVALID) {
624 if (!isempty(display))
626 else if (!isempty(tty))
629 t = SESSION_UNSPECIFIED;
632 if (c == _SESSION_CLASS_INVALID) {
633 if (t == SESSION_UNSPECIFIED)
634 c = SESSION_BACKGROUND;
640 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
642 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
646 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
651 manager_get_session_by_pid(m, leader, &session);
653 _cleanup_free_ char *path = NULL;
654 _cleanup_close_ int fifo_fd = -1;
656 /* Session already exists, client is probably
657 * something like "su" which changes uid but is still
658 * the same session */
660 fifo_fd = session_create_fifo(session);
664 path = session_bus_path(session);
668 log_debug("Sending reply about an existing session: "
669 "id=%s object_path=%s uid=%u runtime_path=%s "
670 "session_fd=%d seat=%s vtnr=%u",
673 (uint32_t) session->user->uid,
674 session->user->runtime_path,
676 session->seat ? session->seat->id : "",
677 (uint32_t) session->vtnr);
679 return sd_bus_reply_method_return(
683 session->user->runtime_path,
685 (uint32_t) session->user->uid,
686 session->seat ? session->seat->id : "",
687 (uint32_t) session->vtnr,
691 audit_session_from_pid(leader, &audit_id);
693 /* Keep our session IDs and the audit session IDs in sync */
695 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
698 /* Wut? There's already a session by this name and we
699 * didn't find it above? Weird, then let's not trust
700 * the audit data and let's better register a new
702 if (hashmap_get(m->sessions, id)) {
703 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
716 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
719 } while (hashmap_get(m->sessions, id));
722 r = manager_add_user_by_uid(m, uid, &user);
726 r = manager_add_session(m, id, &session);
730 session_set_user(session, user);
732 session->leader = leader;
733 session->audit_id = audit_id;
736 session->remote = remote;
737 session->vtnr = vtnr;
740 session->tty = strdup(tty);
747 if (!isempty(display)) {
748 session->display = strdup(display);
749 if (!session->display) {
755 if (!isempty(remote_user)) {
756 session->remote_user = strdup(remote_user);
757 if (!session->remote_user) {
763 if (!isempty(remote_host)) {
764 session->remote_host = strdup(remote_host);
765 if (!session->remote_host) {
771 if (!isempty(service)) {
772 session->service = strdup(service);
773 if (!session->service) {
779 if (!isempty(desktop)) {
780 session->desktop = strdup(desktop);
781 if (!session->desktop) {
788 r = seat_attach_session(seat, session);
793 r = session_start(session);
797 session->create_message = sd_bus_message_ref(message);
799 /* Here upstream systemd starts cgroups and the user systemd,
800 and arranges to reply asynchronously. We reply
803 r = session_send_create_reply(session, NULL);
811 session_add_to_gc_queue(session);
814 user_add_to_gc_queue(user);
819 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
820 Manager *m = userdata;
829 r = sd_bus_message_read(message, "s", &name);
833 r = manager_get_session_from_creds(m, message, name, error, &session);
837 r = session_release(session);
841 session_add_to_gc_queue(session);
843 return sd_bus_reply_method_return(message, NULL);
846 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
847 Manager *m = userdata;
856 r = sd_bus_message_read(message, "s", &name);
860 r = manager_get_session_from_creds(m, message, name, error, &session);
864 return bus_session_method_activate(bus, message, session, error);
867 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
868 const char *session_name, *seat_name;
869 Manager *m = userdata;
878 /* Same as ActivateSession() but refuses to work if
879 * the seat doesn't match */
881 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
885 r = manager_get_session_from_creds(m, message, session_name, error, &session);
889 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
893 if (session->seat != seat)
894 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
896 r = session_activate(session);
900 return sd_bus_reply_method_return(message, NULL);
903 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
904 Manager *m = userdata;
913 r = sd_bus_message_read(message, "s", &name);
917 r = manager_get_session_from_creds(m, message, name, error, &session);
921 return bus_session_method_lock(bus, message, session, error);
924 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
925 Manager *m = userdata;
932 r = bus_verify_polkit_async(
935 "org.freedesktop.login1.lock-sessions",
943 return 1; /* Will call us back */
945 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
949 return sd_bus_reply_method_return(message, NULL);
952 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
954 Manager *m = userdata;
962 r = sd_bus_message_read(message, "s", &name);
966 r = manager_get_session_from_creds(m, message, name, error, &session);
970 return bus_session_method_kill(bus, message, session, error);
973 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
974 Manager *m = userdata;
983 r = sd_bus_message_read(message, "u", &uid);
987 r = manager_get_user_from_creds(m, message, uid, error, &user);
991 return bus_user_method_kill(bus, message, user, error);
994 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
995 Manager *m = userdata;
1004 r = sd_bus_message_read(message, "s", &name);
1008 r = manager_get_session_from_creds(m, message, name, error, &session);
1012 return bus_session_method_terminate(bus, message, session, error);
1015 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1016 Manager *m = userdata;
1025 r = sd_bus_message_read(message, "u", &uid);
1029 r = manager_get_user_from_creds(m, message, uid, error, &user);
1033 return bus_user_method_terminate(bus, message, user, error);
1036 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1037 Manager *m = userdata;
1046 r = sd_bus_message_read(message, "s", &name);
1050 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1054 return bus_seat_method_terminate(bus, message, seat, error);
1057 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1058 _cleanup_free_ char *cc = NULL;
1059 Manager *m = userdata;
1070 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1074 if (uid == UID_INVALID) {
1075 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1077 /* Note that we get the owner UID of the session, not the actual client UID here! */
1078 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1082 r = sd_bus_creds_get_owner_uid(creds, &uid);
1090 return errno ? -errno : -ENOENT;
1092 r = bus_verify_polkit_async(
1095 "org.freedesktop.login1.set-user-linger",
1098 &m->polkit_registry,
1103 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1105 mkdir_p_label("/var/lib/systemd", 0755);
1107 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1111 cc = cescape(pw->pw_name);
1115 path = strjoina("/var/lib/systemd/linger/", cc);
1123 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1130 if (r < 0 && errno != ENOENT)
1133 u = hashmap_get(m->users, UID_TO_PTR(uid));
1135 user_add_to_gc_queue(u);
1138 return sd_bus_reply_method_return(message, NULL);
1141 static int trigger_device(Manager *m, struct udev_device *d) {
1142 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1143 struct udev_list_entry *first, *item;
1148 e = udev_enumerate_new(m->udev);
1153 r = udev_enumerate_add_match_parent(e, d);
1158 r = udev_enumerate_scan_devices(e);
1162 first = udev_enumerate_get_list_entry(e);
1163 udev_list_entry_foreach(item, first) {
1164 _cleanup_free_ char *t = NULL;
1167 p = udev_list_entry_get_name(item);
1169 t = strappend(p, "/uevent");
1173 write_string_file(t, "change");
1179 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1180 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1181 _cleanup_free_ char *rule = NULL, *file = NULL;
1182 const char *id_for_seat;
1189 d = udev_device_new_from_syspath(m->udev, sysfs);
1193 if (!udev_device_has_tag(d, "seat"))
1196 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1200 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1203 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1206 mkdir_p_label("/etc/udev/rules.d", 0755);
1207 mac_selinux_init("/etc");
1208 r = write_string_file_atomic_label(file, rule);
1212 return trigger_device(m, d);
1215 static int flush_devices(Manager *m) {
1216 _cleanup_closedir_ DIR *d;
1220 d = opendir("/etc/udev/rules.d");
1222 if (errno != ENOENT)
1223 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1227 while ((de = readdir(d))) {
1229 if (!dirent_is_file(de))
1232 if (!startswith(de->d_name, "72-seat-"))
1235 if (!endswith(de->d_name, ".rules"))
1238 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1239 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1243 return trigger_device(m, NULL);
1246 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1247 const char *sysfs, *seat;
1248 Manager *m = userdata;
1255 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1259 if (!path_startswith(sysfs, "/sys"))
1260 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1262 if (!seat_name_is_valid(seat))
1263 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1265 r = bus_verify_polkit_async(
1268 "org.freedesktop.login1.attach-device",
1271 &m->polkit_registry,
1276 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1278 r = attach_device(m, seat, sysfs);
1282 return sd_bus_reply_method_return(message, NULL);
1285 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1286 Manager *m = userdata;
1293 r = sd_bus_message_read(message, "b", &interactive);
1297 r = bus_verify_polkit_async(
1300 "org.freedesktop.login1.flush-devices",
1303 &m->polkit_registry,
1308 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1310 r = flush_devices(m);
1314 return sd_bus_reply_method_return(message, NULL);
1317 static int have_multiple_sessions(
1326 /* Check for other users' sessions. Greeter sessions do not
1327 * count, and non-login sessions do not count either. */
1328 HASHMAP_FOREACH(session, m->sessions, i)
1329 if (session->class == SESSION_USER &&
1330 session->user->uid != uid)
1336 static int bus_manager_log_shutdown(
1339 HandleAction action) {
1345 if (w != INHIBIT_SHUTDOWN)
1349 case HANDLE_POWEROFF:
1350 p = "MESSAGE=System is powering down.";
1351 q = "SHUTDOWN=power-off";
1354 p = "MESSAGE=System is halting.";
1355 q = "SHUTDOWN=halt";
1358 p = "MESSAGE=System is rebooting.";
1359 q = "SHUTDOWN=reboot";
1362 p = "MESSAGE=System is rebooting with kexec.";
1363 q = "SHUTDOWN=kexec";
1366 p = "MESSAGE=System is shutting down.";
1371 return log_struct(LOG_NOTICE,
1372 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1378 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1379 Manager *m = userdata;
1384 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1388 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1393 if (until <= now(CLOCK_MONOTONIC))
1396 /* We want to ignore the lid switch for a while after each
1397 * suspend, and after boot-up. Hence let's install a timer for
1398 * this. As long as the event source exists we ignore the lid
1401 if (m->lid_switch_ignore_event_source) {
1404 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1411 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1413 r = sd_event_add_time(
1415 &m->lid_switch_ignore_event_source,
1418 lid_switch_ignore_handler, m);
1423 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1425 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1426 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1427 [INHIBIT_SLEEP] = "PrepareForSleep"
1430 int active = _active;
1434 assert(w < _INHIBIT_WHAT_MAX);
1435 assert(signal_name[w]);
1437 return sd_bus_emit_signal(m->bus,
1438 "/org/freedesktop/login1",
1439 "org.freedesktop.login1.Manager",
1445 static int execute_shutdown_or_sleep(
1448 HandleAction action,
1449 sd_bus_error *error) {
1454 assert(w < _INHIBIT_WHAT_MAX);
1456 bus_manager_log_shutdown(m, w, action);
1458 r = shutdown_or_sleep(m, action);
1462 if (w == INHIBIT_SLEEP)
1463 /* And we're back. */
1464 send_prepare_for(m, w, false);
1468 /* Make sure the lid switch is ignored for a while (?) */
1469 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1474 static int delay_shutdown_or_sleep(
1477 HandleAction action) {
1481 assert(w < _INHIBIT_WHAT_MAX);
1483 m->action_timestamp = now(CLOCK_MONOTONIC);
1484 m->pending_action = action;
1490 int bus_manager_shutdown_or_sleep_now_or_later(
1492 HandleAction action,
1494 sd_bus_error *error) {
1501 assert(w <= _INHIBIT_WHAT_MAX);
1503 /* Tell everybody to prepare for shutdown/sleep */
1504 send_prepare_for(m, w, true);
1507 m->inhibit_delay_max > 0 &&
1508 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1511 /* Shutdown is delayed, keep in mind what we
1512 * want to do, and start a timeout */
1513 r = delay_shutdown_or_sleep(m, w, action);
1515 /* Shutdown is not delayed, execute it
1517 r = execute_shutdown_or_sleep(m, w, action, error);
1522 static int method_do_shutdown_or_sleep(
1524 sd_bus_message *message,
1525 HandleAction sleep_action,
1528 const char *action_multiple_sessions,
1529 const char *action_ignore_inhibit,
1530 const char *sleep_verb,
1531 sd_bus_message_handler_t method,
1532 sd_bus_error *error) {
1534 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1535 bool multiple_sessions, blocked;
1542 assert(w <= _INHIBIT_WHAT_MAX);
1544 assert(action_multiple_sessions);
1545 assert(action_ignore_inhibit);
1548 r = sd_bus_message_read(message, "b", &interactive);
1552 /* Don't allow multiple jobs being executed at the same time */
1554 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1557 r = can_sleep(sleep_verb);
1562 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1565 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1569 r = sd_bus_creds_get_euid(creds, &uid);
1573 r = have_multiple_sessions(m, uid);
1577 multiple_sessions = r > 0;
1578 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1580 if (multiple_sessions) {
1581 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1585 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1589 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1593 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1596 if (!multiple_sessions && !blocked) {
1597 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1601 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1604 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1608 return sd_bus_reply_method_return(message, NULL);
1611 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1612 Manager *m = userdata;
1614 return method_do_shutdown_or_sleep(
1618 "org.freedesktop.login1.power-off",
1619 "org.freedesktop.login1.power-off-multiple-sessions",
1620 "org.freedesktop.login1.power-off-ignore-inhibit",
1626 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1627 Manager *m = userdata;
1629 return method_do_shutdown_or_sleep(
1633 "org.freedesktop.login1.reboot",
1634 "org.freedesktop.login1.reboot-multiple-sessions",
1635 "org.freedesktop.login1.reboot-ignore-inhibit",
1641 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1642 Manager *m = userdata;
1644 return method_do_shutdown_or_sleep(
1648 "org.freedesktop.login1.suspend",
1649 "org.freedesktop.login1.suspend-multiple-sessions",
1650 "org.freedesktop.login1.suspend-ignore-inhibit",
1656 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1657 Manager *m = userdata;
1659 return method_do_shutdown_or_sleep(
1663 "org.freedesktop.login1.hibernate",
1664 "org.freedesktop.login1.hibernate-multiple-sessions",
1665 "org.freedesktop.login1.hibernate-ignore-inhibit",
1671 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1672 Manager *m = userdata;
1674 return method_do_shutdown_or_sleep(
1676 HANDLE_HYBRID_SLEEP,
1678 "org.freedesktop.login1.hibernate",
1679 "org.freedesktop.login1.hibernate-multiple-sessions",
1680 "org.freedesktop.login1.hibernate-ignore-inhibit",
1682 method_hybrid_sleep,
1686 static int method_can_shutdown_or_sleep(
1688 sd_bus_message *message,
1691 const char *action_multiple_sessions,
1692 const char *action_ignore_inhibit,
1693 const char *sleep_verb,
1694 sd_bus_error *error) {
1696 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1697 bool multiple_sessions, challenge, blocked;
1698 const char *result = NULL;
1705 assert(w <= _INHIBIT_WHAT_MAX);
1707 assert(action_multiple_sessions);
1708 assert(action_ignore_inhibit);
1711 r = can_sleep(sleep_verb);
1715 return sd_bus_reply_method_return(message, "s", "na");
1718 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1722 r = sd_bus_creds_get_euid(creds, &uid);
1726 r = have_multiple_sessions(m, uid);
1730 multiple_sessions = r > 0;
1731 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1733 if (multiple_sessions) {
1734 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1741 result = "challenge";
1747 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1751 if (r > 0 && !result)
1753 else if (challenge && (!result || streq(result, "yes")))
1754 result = "challenge";
1759 if (!multiple_sessions && !blocked) {
1760 /* If neither inhibit nor multiple sessions
1761 * apply then just check the normal policy */
1763 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1770 result = "challenge";
1775 return sd_bus_reply_method_return(message, "s", result);
1778 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1779 Manager *m = userdata;
1781 return method_can_shutdown_or_sleep(
1784 "org.freedesktop.login1.power-off",
1785 "org.freedesktop.login1.power-off-multiple-sessions",
1786 "org.freedesktop.login1.power-off-ignore-inhibit",
1791 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1792 Manager *m = userdata;
1794 return method_can_shutdown_or_sleep(
1797 "org.freedesktop.login1.reboot",
1798 "org.freedesktop.login1.reboot-multiple-sessions",
1799 "org.freedesktop.login1.reboot-ignore-inhibit",
1804 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1805 Manager *m = userdata;
1807 return method_can_shutdown_or_sleep(
1810 "org.freedesktop.login1.suspend",
1811 "org.freedesktop.login1.suspend-multiple-sessions",
1812 "org.freedesktop.login1.suspend-ignore-inhibit",
1817 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1818 Manager *m = userdata;
1820 return method_can_shutdown_or_sleep(
1823 "org.freedesktop.login1.hibernate",
1824 "org.freedesktop.login1.hibernate-multiple-sessions",
1825 "org.freedesktop.login1.hibernate-ignore-inhibit",
1830 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1831 Manager *m = userdata;
1833 return method_can_shutdown_or_sleep(
1836 "org.freedesktop.login1.hibernate",
1837 "org.freedesktop.login1.hibernate-multiple-sessions",
1838 "org.freedesktop.login1.hibernate-ignore-inhibit",
1843 static int property_get_reboot_to_firmware_setup(
1846 const char *interface,
1847 const char *property,
1848 sd_bus_message *reply,
1850 sd_bus_error *error) {
1857 r = efi_get_reboot_to_firmware();
1858 if (r < 0 && r != -EOPNOTSUPP)
1861 return sd_bus_message_append(reply, "b", r > 0);
1864 static int method_set_reboot_to_firmware_setup(
1866 sd_bus_message *message,
1868 sd_bus_error *error) {
1871 Manager *m = userdata;
1877 r = sd_bus_message_read(message, "b", &b);
1881 r = bus_verify_polkit_async(message,
1883 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1886 &m->polkit_registry,
1891 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1893 r = efi_set_reboot_to_firmware(b);
1897 return sd_bus_reply_method_return(message, NULL);
1900 static int method_can_reboot_to_firmware_setup(
1902 sd_bus_message *message,
1904 sd_bus_error *error) {
1909 Manager *m = userdata;
1915 r = efi_reboot_to_firmware_supported();
1916 if (r == -EOPNOTSUPP)
1917 return sd_bus_reply_method_return(message, "s", "na");
1921 r = bus_test_polkit(message,
1923 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1933 result = "challenge";
1937 return sd_bus_reply_method_return(message, "s", result);
1940 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1941 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1942 const char *who, *why, *what, *mode;
1943 _cleanup_free_ char *id = NULL;
1944 _cleanup_close_ int fifo_fd = -1;
1945 Manager *m = userdata;
1946 Inhibitor *i = NULL;
1957 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1961 w = inhibit_what_from_string(what);
1963 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1965 mm = inhibit_mode_from_string(mode);
1967 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1969 /* Delay is only supported for shutdown/sleep */
1970 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1971 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1973 /* Don't allow taking delay locks while we are already
1974 * executing the operation. We shouldn't create the impression
1975 * that the lock was successful if the machine is about to go
1976 * down/suspend any moment. */
1977 if (m->action_what & w)
1978 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1980 r = bus_verify_polkit_async(
1983 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1984 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1985 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1986 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1987 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1988 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1989 "org.freedesktop.login1.inhibit-handle-lid-switch",
1992 &m->polkit_registry,
1997 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1999 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2003 r = sd_bus_creds_get_euid(creds, &uid);
2007 r = sd_bus_creds_get_pid(creds, &pid);
2015 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2018 } while (hashmap_get(m->inhibitors, id));
2020 r = manager_add_inhibitor(m, id, &i);
2028 i->why = strdup(why);
2029 i->who = strdup(who);
2031 if (!i->why || !i->who) {
2036 fifo_fd = inhibitor_create_fifo(i);
2044 return sd_bus_reply_method_return(message, "h", fifo_fd);
2053 const sd_bus_vtable manager_vtable[] = {
2054 SD_BUS_VTABLE_START(0),
2056 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2057 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2058 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2059 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2060 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2061 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2062 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2063 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2064 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2065 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2066 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2067 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2068 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2069 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2070 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2071 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2072 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2073 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2074 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2075 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2077 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2078 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2079 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2080 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2081 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2082 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2084 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2085 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2086 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2087 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2088 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2089 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2090 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2091 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2092 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2094 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2095 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2096 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2097 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2099 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2100 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2101 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2102 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2104 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2105 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2106 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2107 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2108 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2109 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2110 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2111 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2112 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2113 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2114 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2116 SD_BUS_SIGNAL("SessionNew", "so", 0),
2117 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2118 SD_BUS_SIGNAL("UserNew", "uo", 0),
2119 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2120 SD_BUS_SIGNAL("SeatNew", "so", 0),
2121 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2122 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2123 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2128 int manager_send_changed(Manager *manager, const char *property, ...) {
2133 l = strv_from_stdarg_alloca(property);
2135 return sd_bus_emit_properties_changed_strv(
2137 "/org/freedesktop/login1",
2138 "org.freedesktop.login1.Manager",
2142 int manager_dispatch_delayed(Manager *manager) {
2143 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2144 Inhibitor *offending = NULL;
2149 if (manager->action_what == 0)
2152 /* Continue delay? */
2153 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2154 _cleanup_free_ char *comm = NULL, *u = NULL;
2156 get_process_comm(offending->pid, &comm);
2157 u = uid_to_name(offending->uid);
2159 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2162 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2163 offending->uid, strna(u),
2164 offending->pid, strna(comm));
2167 /* Actually do the operation */
2168 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
2170 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2172 manager->pending_action = HANDLE_IGNORE;
2173 manager->action_what = 0;