1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-messages.h"
30 #include "path-util.h"
32 #include "sleep-config.h"
33 #include "fileio-label.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-common-errors.h"
39 #include "udev-util.h"
40 #include "selinux-util.h"
43 #include "formats-util.h"
44 #include "process-util.h"
45 #include "terminal-util.h"
47 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
48 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
61 r = sd_bus_creds_get_session(creds, &name);
66 session = hashmap_get(m->sessions, name);
68 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
74 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
82 if (uid == UID_INVALID) {
83 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
85 /* Note that we get the owner UID of the session, not the actual client UID here! */
86 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
90 r = sd_bus_creds_get_owner_uid(creds, &uid);
95 user = hashmap_get(m->users, UID_TO_PTR(uid));
97 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
103 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
114 r = manager_get_session_from_creds(m, message, NULL, error, &session);
118 seat = session->seat;
121 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
123 seat = hashmap_get(m->seats, name);
125 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
132 static int property_get_idle_hint(
135 const char *interface,
136 const char *property,
137 sd_bus_message *reply,
139 sd_bus_error *error) {
141 Manager *m = userdata;
147 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
150 static int property_get_idle_since_hint(
153 const char *interface,
154 const char *property,
155 sd_bus_message *reply,
157 sd_bus_error *error) {
159 Manager *m = userdata;
166 manager_get_idle_hint(m, &t);
168 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
171 static int property_get_inhibited(
174 const char *interface,
175 const char *property,
176 sd_bus_message *reply,
178 sd_bus_error *error) {
180 Manager *m = userdata;
187 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
189 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
192 static int property_get_preparing(
195 const char *interface,
196 const char *property,
197 sd_bus_message *reply,
199 sd_bus_error *error) {
201 Manager *m = userdata;
208 if (streq(property, "PreparingForShutdown"))
209 b = !!(m->action_what & INHIBIT_SHUTDOWN);
211 b = !!(m->action_what & INHIBIT_SLEEP);
213 return sd_bus_message_append(reply, "b", b);
216 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
218 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
219 _cleanup_free_ char *p = NULL;
220 Manager *m = userdata;
229 r = sd_bus_message_read(message, "s", &name);
233 r = manager_get_session_from_creds(m, message, name, error, &session);
237 p = session_bus_path(session);
241 return sd_bus_reply_method_return(message, "o", p);
244 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
245 _cleanup_free_ char *p = NULL;
246 Session *session = NULL;
247 Manager *m = userdata;
255 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
257 r = sd_bus_message_read(message, "u", &pid);
262 r = manager_get_session_from_creds(m, message, NULL, error, &session);
266 r = manager_get_session_by_pid(m, pid, &session);
271 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
274 p = session_bus_path(session);
278 return sd_bus_reply_method_return(message, "o", p);
281 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
282 _cleanup_free_ char *p = NULL;
283 Manager *m = userdata;
292 r = sd_bus_message_read(message, "u", &uid);
296 r = manager_get_user_from_creds(m, message, uid, error, &user);
300 p = user_bus_path(user);
304 return sd_bus_reply_method_return(message, "o", p);
307 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
308 _cleanup_free_ char *p = NULL;
309 Manager *m = userdata;
318 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
320 r = sd_bus_message_read(message, "u", &pid);
325 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
329 r = manager_get_user_by_pid(m, pid, &user);
333 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);
336 p = user_bus_path(user);
340 return sd_bus_reply_method_return(message, "o", p);
343 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
344 _cleanup_free_ char *p = NULL;
345 Manager *m = userdata;
354 r = sd_bus_message_read(message, "s", &name);
358 r = manager_get_seat_from_creds(m, message, name, error, &seat);
362 p = seat_bus_path(seat);
366 return sd_bus_reply_method_return(message, "o", p);
369 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
371 Manager *m = userdata;
380 r = sd_bus_message_new_method_return(message, &reply);
384 r = sd_bus_message_open_container(reply, 'a', "(susso)");
388 HASHMAP_FOREACH(session, m->sessions, i) {
389 _cleanup_free_ char *p = NULL;
391 p = session_bus_path(session);
395 r = sd_bus_message_append(reply, "(susso)",
397 (uint32_t) session->user->uid,
399 session->seat ? session->seat->id : "",
405 r = sd_bus_message_close_container(reply);
409 return sd_bus_send(bus, reply, NULL);
412 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
413 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
414 Manager *m = userdata;
423 r = sd_bus_message_new_method_return(message, &reply);
427 r = sd_bus_message_open_container(reply, 'a', "(uso)");
431 HASHMAP_FOREACH(user, m->users, i) {
432 _cleanup_free_ char *p = NULL;
434 p = user_bus_path(user);
438 r = sd_bus_message_append(reply, "(uso)",
439 (uint32_t) user->uid,
446 r = sd_bus_message_close_container(reply);
450 return sd_bus_send(bus, reply, NULL);
453 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
454 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
455 Manager *m = userdata;
464 r = sd_bus_message_new_method_return(message, &reply);
468 r = sd_bus_message_open_container(reply, 'a', "(so)");
472 HASHMAP_FOREACH(seat, m->seats, i) {
473 _cleanup_free_ char *p = NULL;
475 p = seat_bus_path(seat);
479 r = sd_bus_message_append(reply, "(so)", seat->id, p);
484 r = sd_bus_message_close_container(reply);
488 return sd_bus_send(bus, reply, NULL);
491 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
492 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
493 Manager *m = userdata;
494 Inhibitor *inhibitor;
498 r = sd_bus_message_new_method_return(message, &reply);
502 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
506 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
508 r = sd_bus_message_append(reply, "(ssssuu)",
509 strempty(inhibit_what_to_string(inhibitor->what)),
510 strempty(inhibitor->who),
511 strempty(inhibitor->why),
512 strempty(inhibit_mode_to_string(inhibitor->mode)),
513 (uint32_t) inhibitor->uid,
514 (uint32_t) inhibitor->pid);
519 r = sd_bus_message_close_container(reply);
523 return sd_bus_send(bus, reply, NULL);
526 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
527 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
528 uint32_t uid, leader, audit_id = 0;
529 _cleanup_free_ char *id = NULL;
530 Session *session = NULL;
531 Manager *m = userdata;
544 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
549 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
552 t = _SESSION_TYPE_INVALID;
554 t = session_type_from_string(type);
556 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
560 c = _SESSION_CLASS_INVALID;
562 c = session_class_from_string(class);
564 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
567 if (isempty(desktop))
570 if (!string_is_safe(desktop))
571 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
577 seat = hashmap_get(m->seats, cseat);
579 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
582 if (tty_is_vc(tty)) {
587 else if (seat != m->seat0)
588 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);
590 v = vtnr_from_tty(tty);
592 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
596 else if (vtnr != (uint32_t) v)
597 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
599 } else if (tty_is_console(tty)) {
603 else if (seat != m->seat0)
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
607 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
611 if (seat_has_vts(seat)) {
612 if (!vtnr || vtnr > 63)
613 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
616 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
620 r = sd_bus_message_enter_container(message, 'a', "(sv)");
624 if (t == _SESSION_TYPE_INVALID) {
625 if (!isempty(display))
627 else if (!isempty(tty))
630 t = SESSION_UNSPECIFIED;
633 if (c == _SESSION_CLASS_INVALID) {
634 if (t == SESSION_UNSPECIFIED)
635 c = SESSION_BACKGROUND;
641 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
643 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
647 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
652 manager_get_session_by_pid(m, leader, &session);
654 _cleanup_free_ char *path = NULL;
655 _cleanup_close_ int fifo_fd = -1;
657 /* Session already exists, client is probably
658 * something like "su" which changes uid but is still
659 * the same session */
661 fifo_fd = session_create_fifo(session);
665 path = session_bus_path(session);
669 log_debug("Sending reply about an existing session: "
670 "id=%s object_path=%s uid=%u runtime_path=%s "
671 "session_fd=%d seat=%s vtnr=%u",
674 (uint32_t) session->user->uid,
675 session->user->runtime_path,
677 session->seat ? session->seat->id : "",
678 (uint32_t) session->vtnr);
680 return sd_bus_reply_method_return(
684 session->user->runtime_path,
686 (uint32_t) session->user->uid,
687 session->seat ? session->seat->id : "",
688 (uint32_t) session->vtnr,
692 audit_session_from_pid(leader, &audit_id);
694 /* Keep our session IDs and the audit session IDs in sync */
696 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
699 /* Wut? There's already a session by this name and we
700 * didn't find it above? Weird, then let's not trust
701 * the audit data and let's better register a new
703 if (hashmap_get(m->sessions, id)) {
704 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
717 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
720 } while (hashmap_get(m->sessions, id));
723 r = manager_add_user_by_uid(m, uid, &user);
727 r = manager_add_session(m, id, &session);
731 session_set_user(session, user);
733 session->leader = leader;
734 session->audit_id = audit_id;
737 session->remote = remote;
738 session->vtnr = vtnr;
741 session->tty = strdup(tty);
748 if (!isempty(display)) {
749 session->display = strdup(display);
750 if (!session->display) {
756 if (!isempty(remote_user)) {
757 session->remote_user = strdup(remote_user);
758 if (!session->remote_user) {
764 if (!isempty(remote_host)) {
765 session->remote_host = strdup(remote_host);
766 if (!session->remote_host) {
772 if (!isempty(service)) {
773 session->service = strdup(service);
774 if (!session->service) {
780 if (!isempty(desktop)) {
781 session->desktop = strdup(desktop);
782 if (!session->desktop) {
789 r = seat_attach_session(seat, session);
794 r = session_start(session);
798 session->create_message = sd_bus_message_ref(message);
800 /* Here upstream systemd starts cgroups and the user systemd,
801 and arranges to reply asynchronously. We reply
804 r = session_send_create_reply(session, NULL);
812 session_add_to_gc_queue(session);
815 user_add_to_gc_queue(user);
820 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
821 Manager *m = userdata;
830 r = sd_bus_message_read(message, "s", &name);
834 r = manager_get_session_from_creds(m, message, name, error, &session);
838 r = session_release(session);
842 session_add_to_gc_queue(session);
844 return sd_bus_reply_method_return(message, NULL);
847 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
848 Manager *m = userdata;
857 r = sd_bus_message_read(message, "s", &name);
861 r = manager_get_session_from_creds(m, message, name, error, &session);
865 return bus_session_method_activate(bus, message, session, error);
868 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
869 const char *session_name, *seat_name;
870 Manager *m = userdata;
879 /* Same as ActivateSession() but refuses to work if
880 * the seat doesn't match */
882 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
886 r = manager_get_session_from_creds(m, message, session_name, error, &session);
890 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
894 if (session->seat != seat)
895 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
897 r = session_activate(session);
901 return sd_bus_reply_method_return(message, NULL);
904 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
905 Manager *m = userdata;
914 r = sd_bus_message_read(message, "s", &name);
918 r = manager_get_session_from_creds(m, message, name, error, &session);
922 return bus_session_method_lock(bus, message, session, error);
925 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
926 Manager *m = userdata;
933 r = bus_verify_polkit_async(
936 "org.freedesktop.login1.lock-sessions",
944 return 1; /* Will call us back */
946 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
950 return sd_bus_reply_method_return(message, NULL);
953 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
955 Manager *m = userdata;
963 r = sd_bus_message_read(message, "s", &name);
967 r = manager_get_session_from_creds(m, message, name, error, &session);
971 return bus_session_method_kill(bus, message, session, error);
974 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
975 Manager *m = userdata;
984 r = sd_bus_message_read(message, "u", &uid);
988 r = manager_get_user_from_creds(m, message, uid, error, &user);
992 return bus_user_method_kill(bus, message, user, error);
995 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
996 Manager *m = userdata;
1005 r = sd_bus_message_read(message, "s", &name);
1009 r = manager_get_session_from_creds(m, message, name, error, &session);
1013 return bus_session_method_terminate(bus, message, session, error);
1016 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1017 Manager *m = userdata;
1026 r = sd_bus_message_read(message, "u", &uid);
1030 r = manager_get_user_from_creds(m, message, uid, error, &user);
1034 return bus_user_method_terminate(bus, message, user, error);
1037 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1038 Manager *m = userdata;
1047 r = sd_bus_message_read(message, "s", &name);
1051 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1055 return bus_seat_method_terminate(bus, message, seat, error);
1058 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1059 _cleanup_free_ char *cc = NULL;
1060 Manager *m = userdata;
1071 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1075 if (uid == UID_INVALID) {
1076 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1078 /* Note that we get the owner UID of the session, not the actual client UID here! */
1079 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1083 r = sd_bus_creds_get_owner_uid(creds, &uid);
1091 return errno ? -errno : -ENOENT;
1093 r = bus_verify_polkit_async(
1096 "org.freedesktop.login1.set-user-linger",
1099 &m->polkit_registry,
1104 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1106 mkdir_p_label("/var/lib/systemd", 0755);
1108 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1112 cc = cescape(pw->pw_name);
1116 path = strjoina("/var/lib/systemd/linger/", cc);
1124 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1131 if (r < 0 && errno != ENOENT)
1134 u = hashmap_get(m->users, UID_TO_PTR(uid));
1136 user_add_to_gc_queue(u);
1139 return sd_bus_reply_method_return(message, NULL);
1142 static int trigger_device(Manager *m, struct udev_device *d) {
1143 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1144 struct udev_list_entry *first, *item;
1149 e = udev_enumerate_new(m->udev);
1154 r = udev_enumerate_add_match_parent(e, d);
1159 r = udev_enumerate_scan_devices(e);
1163 first = udev_enumerate_get_list_entry(e);
1164 udev_list_entry_foreach(item, first) {
1165 _cleanup_free_ char *t = NULL;
1168 p = udev_list_entry_get_name(item);
1170 t = strappend(p, "/uevent");
1174 write_string_file(t, "change");
1180 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1181 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1182 _cleanup_free_ char *rule = NULL, *file = NULL;
1183 const char *id_for_seat;
1190 d = udev_device_new_from_syspath(m->udev, sysfs);
1194 if (!udev_device_has_tag(d, "seat"))
1197 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1201 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1204 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1207 mkdir_p_label("/etc/udev/rules.d", 0755);
1208 mac_selinux_init("/etc");
1209 r = write_string_file_atomic_label(file, rule);
1213 return trigger_device(m, d);
1216 static int flush_devices(Manager *m) {
1217 _cleanup_closedir_ DIR *d;
1221 d = opendir("/etc/udev/rules.d");
1223 if (errno != ENOENT)
1224 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1228 while ((de = readdir(d))) {
1230 if (!dirent_is_file(de))
1233 if (!startswith(de->d_name, "72-seat-"))
1236 if (!endswith(de->d_name, ".rules"))
1239 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1240 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1244 return trigger_device(m, NULL);
1247 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1248 const char *sysfs, *seat;
1249 Manager *m = userdata;
1256 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1260 if (!path_startswith(sysfs, "/sys"))
1261 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1263 if (!seat_name_is_valid(seat))
1264 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1266 r = bus_verify_polkit_async(
1269 "org.freedesktop.login1.attach-device",
1272 &m->polkit_registry,
1277 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1279 r = attach_device(m, seat, sysfs);
1283 return sd_bus_reply_method_return(message, NULL);
1286 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1287 Manager *m = userdata;
1294 r = sd_bus_message_read(message, "b", &interactive);
1298 r = bus_verify_polkit_async(
1301 "org.freedesktop.login1.flush-devices",
1304 &m->polkit_registry,
1309 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1311 r = flush_devices(m);
1315 return sd_bus_reply_method_return(message, NULL);
1318 static int have_multiple_sessions(
1327 /* Check for other users' sessions. Greeter sessions do not
1328 * count, and non-login sessions do not count either. */
1329 HASHMAP_FOREACH(session, m->sessions, i)
1330 if (session->class == SESSION_USER &&
1331 session->user->uid != uid)
1337 static int bus_manager_log_shutdown(
1340 HandleAction action) {
1346 if (w != INHIBIT_SHUTDOWN)
1350 case HANDLE_POWEROFF:
1351 p = "MESSAGE=System is powering down.";
1352 q = "SHUTDOWN=power-off";
1355 p = "MESSAGE=System is halting.";
1356 q = "SHUTDOWN=halt";
1359 p = "MESSAGE=System is rebooting.";
1360 q = "SHUTDOWN=reboot";
1363 p = "MESSAGE=System is rebooting with kexec.";
1364 q = "SHUTDOWN=kexec";
1367 p = "MESSAGE=System is shutting down.";
1372 return log_struct(LOG_NOTICE,
1373 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1379 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1380 Manager *m = userdata;
1385 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1389 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1394 if (until <= now(CLOCK_MONOTONIC))
1397 /* We want to ignore the lid switch for a while after each
1398 * suspend, and after boot-up. Hence let's install a timer for
1399 * this. As long as the event source exists we ignore the lid
1402 if (m->lid_switch_ignore_event_source) {
1405 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1412 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1414 r = sd_event_add_time(
1416 &m->lid_switch_ignore_event_source,
1419 lid_switch_ignore_handler, m);
1424 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1426 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1427 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1428 [INHIBIT_SLEEP] = "PrepareForSleep"
1431 int active = _active;
1435 assert(w < _INHIBIT_WHAT_MAX);
1436 assert(signal_name[w]);
1438 return sd_bus_emit_signal(m->bus,
1439 "/org/freedesktop/login1",
1440 "org.freedesktop.login1.Manager",
1446 static int execute_shutdown_or_sleep(
1449 HandleAction action,
1450 sd_bus_error *error) {
1455 assert(w < _INHIBIT_WHAT_MAX);
1457 bus_manager_log_shutdown(m, w, action);
1459 r = shutdown_or_sleep(m, action);
1463 if (w == INHIBIT_SLEEP)
1464 /* And we're back. */
1465 send_prepare_for(m, w, false);
1469 /* Make sure the lid switch is ignored for a while (?) */
1470 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1475 static int delay_shutdown_or_sleep(
1478 HandleAction action) {
1482 assert(w < _INHIBIT_WHAT_MAX);
1484 m->action_timestamp = now(CLOCK_MONOTONIC);
1485 m->pending_action = action;
1491 int bus_manager_shutdown_or_sleep_now_or_later(
1493 HandleAction action,
1495 sd_bus_error *error) {
1502 assert(w <= _INHIBIT_WHAT_MAX);
1504 /* Tell everybody to prepare for shutdown/sleep */
1505 send_prepare_for(m, w, true);
1508 m->inhibit_delay_max > 0 &&
1509 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1512 /* Shutdown is delayed, keep in mind what we
1513 * want to do, and start a timeout */
1514 r = delay_shutdown_or_sleep(m, w, action);
1516 /* Shutdown is not delayed, execute it
1518 r = execute_shutdown_or_sleep(m, w, action, error);
1523 static int method_do_shutdown_or_sleep(
1525 sd_bus_message *message,
1526 HandleAction sleep_action,
1529 const char *action_multiple_sessions,
1530 const char *action_ignore_inhibit,
1531 const char *sleep_verb,
1532 sd_bus_message_handler_t method,
1533 sd_bus_error *error) {
1535 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1536 bool multiple_sessions, blocked;
1543 assert(w <= _INHIBIT_WHAT_MAX);
1545 assert(action_multiple_sessions);
1546 assert(action_ignore_inhibit);
1549 r = sd_bus_message_read(message, "b", &interactive);
1553 /* Don't allow multiple jobs being executed at the same time */
1555 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1558 r = can_sleep(sleep_verb);
1563 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1566 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1570 r = sd_bus_creds_get_euid(creds, &uid);
1574 r = have_multiple_sessions(m, uid);
1578 multiple_sessions = r > 0;
1579 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1581 if (multiple_sessions) {
1582 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1586 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1590 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1594 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1597 if (!multiple_sessions && !blocked) {
1598 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1602 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1605 r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1609 return sd_bus_reply_method_return(message, NULL);
1612 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1613 Manager *m = userdata;
1615 return method_do_shutdown_or_sleep(
1619 "org.freedesktop.login1.power-off",
1620 "org.freedesktop.login1.power-off-multiple-sessions",
1621 "org.freedesktop.login1.power-off-ignore-inhibit",
1627 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1628 Manager *m = userdata;
1630 return method_do_shutdown_or_sleep(
1634 "org.freedesktop.login1.reboot",
1635 "org.freedesktop.login1.reboot-multiple-sessions",
1636 "org.freedesktop.login1.reboot-ignore-inhibit",
1642 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1643 Manager *m = userdata;
1645 return method_do_shutdown_or_sleep(
1649 "org.freedesktop.login1.suspend",
1650 "org.freedesktop.login1.suspend-multiple-sessions",
1651 "org.freedesktop.login1.suspend-ignore-inhibit",
1657 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1658 Manager *m = userdata;
1660 return method_do_shutdown_or_sleep(
1664 "org.freedesktop.login1.hibernate",
1665 "org.freedesktop.login1.hibernate-multiple-sessions",
1666 "org.freedesktop.login1.hibernate-ignore-inhibit",
1672 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1673 Manager *m = userdata;
1675 return method_do_shutdown_or_sleep(
1677 HANDLE_HYBRID_SLEEP,
1679 "org.freedesktop.login1.hibernate",
1680 "org.freedesktop.login1.hibernate-multiple-sessions",
1681 "org.freedesktop.login1.hibernate-ignore-inhibit",
1683 method_hybrid_sleep,
1687 static int method_can_shutdown_or_sleep(
1689 sd_bus_message *message,
1692 const char *action_multiple_sessions,
1693 const char *action_ignore_inhibit,
1694 const char *sleep_verb,
1695 sd_bus_error *error) {
1697 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1698 bool multiple_sessions, challenge, blocked;
1699 const char *result = NULL;
1706 assert(w <= _INHIBIT_WHAT_MAX);
1708 assert(action_multiple_sessions);
1709 assert(action_ignore_inhibit);
1712 r = can_sleep(sleep_verb);
1716 return sd_bus_reply_method_return(message, "s", "na");
1719 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1723 r = sd_bus_creds_get_euid(creds, &uid);
1727 r = have_multiple_sessions(m, uid);
1731 multiple_sessions = r > 0;
1732 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1734 if (multiple_sessions) {
1735 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1742 result = "challenge";
1748 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1752 if (r > 0 && !result)
1754 else if (challenge && (!result || streq(result, "yes")))
1755 result = "challenge";
1760 if (!multiple_sessions && !blocked) {
1761 /* If neither inhibit nor multiple sessions
1762 * apply then just check the normal policy */
1764 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1771 result = "challenge";
1776 return sd_bus_reply_method_return(message, "s", result);
1779 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1780 Manager *m = userdata;
1782 return method_can_shutdown_or_sleep(
1785 "org.freedesktop.login1.power-off",
1786 "org.freedesktop.login1.power-off-multiple-sessions",
1787 "org.freedesktop.login1.power-off-ignore-inhibit",
1792 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1793 Manager *m = userdata;
1795 return method_can_shutdown_or_sleep(
1798 "org.freedesktop.login1.reboot",
1799 "org.freedesktop.login1.reboot-multiple-sessions",
1800 "org.freedesktop.login1.reboot-ignore-inhibit",
1805 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1806 Manager *m = userdata;
1808 return method_can_shutdown_or_sleep(
1811 "org.freedesktop.login1.suspend",
1812 "org.freedesktop.login1.suspend-multiple-sessions",
1813 "org.freedesktop.login1.suspend-ignore-inhibit",
1818 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1819 Manager *m = userdata;
1821 return method_can_shutdown_or_sleep(
1824 "org.freedesktop.login1.hibernate",
1825 "org.freedesktop.login1.hibernate-multiple-sessions",
1826 "org.freedesktop.login1.hibernate-ignore-inhibit",
1831 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1832 Manager *m = userdata;
1834 return method_can_shutdown_or_sleep(
1837 "org.freedesktop.login1.hibernate",
1838 "org.freedesktop.login1.hibernate-multiple-sessions",
1839 "org.freedesktop.login1.hibernate-ignore-inhibit",
1844 static int property_get_reboot_to_firmware_setup(
1847 const char *interface,
1848 const char *property,
1849 sd_bus_message *reply,
1851 sd_bus_error *error) {
1858 r = efi_get_reboot_to_firmware();
1859 if (r < 0 && r != -EOPNOTSUPP)
1862 return sd_bus_message_append(reply, "b", r > 0);
1865 static int method_set_reboot_to_firmware_setup(
1867 sd_bus_message *message,
1869 sd_bus_error *error) {
1872 Manager *m = userdata;
1878 r = sd_bus_message_read(message, "b", &b);
1882 r = bus_verify_polkit_async(message,
1884 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1887 &m->polkit_registry,
1892 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1894 r = efi_set_reboot_to_firmware(b);
1898 return sd_bus_reply_method_return(message, NULL);
1901 static int method_can_reboot_to_firmware_setup(
1903 sd_bus_message *message,
1905 sd_bus_error *error) {
1910 Manager *m = userdata;
1916 r = efi_reboot_to_firmware_supported();
1917 if (r == -EOPNOTSUPP)
1918 return sd_bus_reply_method_return(message, "s", "na");
1922 r = bus_test_polkit(message,
1924 "org.freedesktop.login1.set-reboot-to-firmware-setup",
1934 result = "challenge";
1938 return sd_bus_reply_method_return(message, "s", result);
1941 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1942 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1943 const char *who, *why, *what, *mode;
1944 _cleanup_free_ char *id = NULL;
1945 _cleanup_close_ int fifo_fd = -1;
1946 Manager *m = userdata;
1947 Inhibitor *i = NULL;
1958 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1962 w = inhibit_what_from_string(what);
1964 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1966 mm = inhibit_mode_from_string(mode);
1968 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1970 /* Delay is only supported for shutdown/sleep */
1971 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1972 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1974 /* Don't allow taking delay locks while we are already
1975 * executing the operation. We shouldn't create the impression
1976 * that the lock was successful if the machine is about to go
1977 * down/suspend any moment. */
1978 if (m->action_what & w)
1979 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1981 r = bus_verify_polkit_async(
1984 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1985 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1986 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1987 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1988 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1989 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1990 "org.freedesktop.login1.inhibit-handle-lid-switch",
1993 &m->polkit_registry,
1998 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2000 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2004 r = sd_bus_creds_get_euid(creds, &uid);
2008 r = sd_bus_creds_get_pid(creds, &pid);
2016 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2019 } while (hashmap_get(m->inhibitors, id));
2021 r = manager_add_inhibitor(m, id, &i);
2029 i->why = strdup(why);
2030 i->who = strdup(who);
2032 if (!i->why || !i->who) {
2037 fifo_fd = inhibitor_create_fifo(i);
2045 return sd_bus_reply_method_return(message, "h", fifo_fd);
2054 const sd_bus_vtable manager_vtable[] = {
2055 SD_BUS_VTABLE_START(0),
2057 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2058 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2059 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2060 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2061 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2062 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2063 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2064 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2065 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2066 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2067 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2068 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2069 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2070 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2071 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2072 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2073 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2074 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2075 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2076 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2078 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2079 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2080 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2081 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2082 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2084 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2085 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2086 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2087 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2088 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2089 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2090 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2091 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2092 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2094 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2095 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2096 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2097 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2099 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2100 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2101 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2102 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2104 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2105 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2106 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2107 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2108 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2109 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2110 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2111 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2112 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2113 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2114 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2115 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2117 SD_BUS_SIGNAL("SessionNew", "so", 0),
2118 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2119 SD_BUS_SIGNAL("UserNew", "uo", 0),
2120 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2121 SD_BUS_SIGNAL("SeatNew", "so", 0),
2122 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2123 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2124 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2129 int manager_send_changed(Manager *manager, const char *property, ...) {
2134 l = strv_from_stdarg_alloca(property);
2136 return sd_bus_emit_properties_changed_strv(
2138 "/org/freedesktop/login1",
2139 "org.freedesktop.login1.Manager",
2143 int manager_dispatch_delayed(Manager *manager) {
2144 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2145 Inhibitor *offending = NULL;
2150 if (manager->action_what == 0)
2153 /* Continue delay? */
2154 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2155 _cleanup_free_ char *comm = NULL, *u = NULL;
2157 get_process_comm(offending->pid, &comm);
2158 u = uid_to_name(offending->uid);
2160 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2163 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2164 offending->uid, strna(u),
2165 offending->pid, strna(comm));
2168 /* Actually do the operation */
2169 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
2171 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2173 manager->pending_action = HANDLE_IGNORE;
2174 manager->action_what = 0;