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/>.
26 #include <sys/capability.h>
29 #include "sd-messages.h"
32 #include "path-util.h"
34 #include "sleep-config.h"
35 #include "fileio-label.h"
38 #include "unit-name.h"
42 #include "bus-error.h"
44 #include "bus-errors.h"
45 #include "udev-util.h"
47 static int property_get_idle_hint(
50 const char *interface,
52 sd_bus_message *reply,
54 sd_bus_error *error) {
56 Manager *m = userdata;
62 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
65 static int property_get_idle_since_hint(
68 const char *interface,
70 sd_bus_message *reply,
72 sd_bus_error *error) {
74 Manager *m = userdata;
81 manager_get_idle_hint(m, &t);
83 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
86 static int property_get_inhibited(
89 const char *interface,
91 sd_bus_message *reply,
93 sd_bus_error *error) {
95 Manager *m = userdata;
102 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
104 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
107 static int property_get_preparing(
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
114 sd_bus_error *error) {
116 Manager *m = userdata;
123 if (streq(property, "PreparingForShutdown"))
124 b = !!(m->action_what & INHIBIT_SHUTDOWN);
126 b = !!(m->action_what & INHIBIT_SLEEP);
128 return sd_bus_message_append(reply, "b", b);
131 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
133 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
134 _cleanup_free_ char *p = NULL;
135 Manager *m = userdata;
144 r = sd_bus_message_read(message, "s", &name);
148 session = hashmap_get(m->sessions, name);
150 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
152 p = session_bus_path(session);
156 return sd_bus_reply_method_return(message, "o", p);
159 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
160 _cleanup_free_ char *p = NULL;
161 Session *session = NULL;
162 Manager *m = userdata;
170 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
172 r = sd_bus_message_read(message, "u", &pid);
177 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
179 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
183 r = sd_bus_creds_get_pid(creds, &pid);
188 r = manager_get_session_by_pid(m, pid, &session);
192 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
194 p = session_bus_path(session);
198 return sd_bus_reply_method_return(message, "o", p);
201 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
202 _cleanup_free_ char *p = NULL;
203 Manager *m = userdata;
212 r = sd_bus_message_read(message, "u", &uid);
216 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
218 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
220 p = user_bus_path(user);
224 return sd_bus_reply_method_return(message, "o", p);
227 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
228 _cleanup_free_ char *p = NULL;
229 Manager *m = userdata;
238 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
240 r = sd_bus_message_read(message, "u", &pid);
245 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
247 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
251 r = sd_bus_creds_get_pid(creds, &pid);
256 r = manager_get_user_by_pid(m, pid, &user);
260 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
262 p = user_bus_path(user);
266 return sd_bus_reply_method_return(message, "o", p);
269 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
270 _cleanup_free_ char *p = NULL;
271 Manager *m = userdata;
280 r = sd_bus_message_read(message, "s", &name);
284 seat = hashmap_get(m->seats, name);
286 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
288 p = seat_bus_path(seat);
292 return sd_bus_reply_method_return(message, "o", p);
295 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
297 Manager *m = userdata;
306 r = sd_bus_message_new_method_return(message, &reply);
310 r = sd_bus_message_open_container(reply, 'a', "(susso)");
314 HASHMAP_FOREACH(session, m->sessions, i) {
315 _cleanup_free_ char *p = NULL;
317 p = session_bus_path(session);
321 r = sd_bus_message_append(reply, "(susso)",
323 (uint32_t) session->user->uid,
325 session->seat ? session->seat->id : "",
331 r = sd_bus_message_close_container(reply);
335 return sd_bus_send(bus, reply, NULL);
338 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
339 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
340 Manager *m = userdata;
349 r = sd_bus_message_new_method_return(message, &reply);
353 r = sd_bus_message_open_container(reply, 'a', "(uso)");
357 HASHMAP_FOREACH(user, m->users, i) {
358 _cleanup_free_ char *p = NULL;
360 p = user_bus_path(user);
364 r = sd_bus_message_append(reply, "(uso)",
365 (uint32_t) user->uid,
372 r = sd_bus_message_close_container(reply);
376 return sd_bus_send(bus, reply, NULL);
379 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
380 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
381 Manager *m = userdata;
390 r = sd_bus_message_new_method_return(message, &reply);
394 r = sd_bus_message_open_container(reply, 'a', "(so)");
398 HASHMAP_FOREACH(seat, m->seats, i) {
399 _cleanup_free_ char *p = NULL;
401 p = seat_bus_path(seat);
405 r = sd_bus_message_append(reply, "(so)", seat->id, p);
410 r = sd_bus_message_close_container(reply);
414 return sd_bus_send(bus, reply, NULL);
417 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
418 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
419 Manager *m = userdata;
420 Inhibitor *inhibitor;
424 r = sd_bus_message_new_method_return(message, &reply);
428 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
432 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
434 r = sd_bus_message_append(reply, "(ssssuu)",
435 strempty(inhibit_what_to_string(inhibitor->what)),
436 strempty(inhibitor->who),
437 strempty(inhibitor->why),
438 strempty(inhibit_mode_to_string(inhibitor->mode)),
439 (uint32_t) inhibitor->uid,
440 (uint32_t) inhibitor->pid);
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(bus, reply, NULL);
452 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
454 uint32_t uid, leader, audit_id = 0;
455 _cleanup_free_ char *id = NULL;
456 Session *session = NULL;
457 Manager *m = userdata;
470 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
475 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
478 t = _SESSION_TYPE_INVALID;
480 t = session_type_from_string(type);
482 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
486 c = _SESSION_CLASS_INVALID;
488 c = session_class_from_string(class);
490 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
493 if (isempty(desktop))
496 if (!string_is_safe(desktop))
497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
503 seat = hashmap_get(m->seats, cseat);
505 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
508 if (tty_is_vc(tty)) {
513 else if (seat != m->seat0)
514 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);
516 v = vtnr_from_tty(tty);
518 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
522 else if (vtnr != (uint32_t) v)
523 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
525 } else if (tty_is_console(tty)) {
529 else if (seat != m->seat0)
530 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
533 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
537 if (seat_has_vts(seat)) {
538 if (!vtnr || vtnr > 63)
539 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
542 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
546 r = sd_bus_message_enter_container(message, 'a', "(sv)");
550 if (t == _SESSION_TYPE_INVALID) {
551 if (!isempty(display))
553 else if (!isempty(tty))
556 t = SESSION_UNSPECIFIED;
559 if (c == _SESSION_CLASS_INVALID) {
560 if (t == SESSION_UNSPECIFIED)
561 c = SESSION_BACKGROUND;
567 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
569 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
573 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
575 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
580 manager_get_session_by_pid(m, leader, &session);
582 _cleanup_free_ char *path = NULL;
583 _cleanup_close_ int fifo_fd = -1;
585 /* Session already exists, client is probably
586 * something like "su" which changes uid but is still
587 * the same session */
589 fifo_fd = session_create_fifo(session);
593 path = session_bus_path(session);
597 return sd_bus_reply_method_return(
601 session->user->runtime_path,
603 (uint32_t) session->user->uid,
604 session->seat ? session->seat->id : "",
605 (uint32_t) session->vtnr,
609 audit_session_from_pid(leader, &audit_id);
611 /* Keep our session IDs and the audit session IDs in sync */
613 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
616 /* Wut? There's already a session by this name and we
617 * didn't find it above? Weird, then let's not trust
618 * the audit data and let's better register a new
620 if (hashmap_get(m->sessions, id)) {
621 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
634 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
637 } while (hashmap_get(m->sessions, id));
640 r = manager_add_user_by_uid(m, uid, &user);
644 r = manager_add_session(m, id, &session);
648 session_set_user(session, user);
650 session->leader = leader;
651 session->audit_id = audit_id;
654 session->remote = remote;
655 session->vtnr = vtnr;
658 session->tty = strdup(tty);
665 if (!isempty(display)) {
666 session->display = strdup(display);
667 if (!session->display) {
673 if (!isempty(remote_user)) {
674 session->remote_user = strdup(remote_user);
675 if (!session->remote_user) {
681 if (!isempty(remote_host)) {
682 session->remote_host = strdup(remote_host);
683 if (!session->remote_host) {
689 if (!isempty(service)) {
690 session->service = strdup(service);
691 if (!session->service) {
697 if (!isempty(desktop)) {
698 session->desktop = strdup(desktop);
699 if (!session->desktop) {
706 r = seat_attach_session(seat, session);
711 r = session_start(session);
715 session->create_message = sd_bus_message_ref(message);
717 /* Now, let's wait until the slice unit and stuff got
718 * created. We send the reply back from
719 * session_send_create_reply().*/
725 session_add_to_gc_queue(session);
728 user_add_to_gc_queue(user);
733 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
734 Manager *m = userdata;
743 r = sd_bus_message_read(message, "s", &name);
747 session = hashmap_get(m->sessions, name);
749 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
751 /* We use the FIFO to detect stray sessions where the process
752 invoking PAM dies abnormally. We need to make sure that
753 that process is not killed if at the clean end of the
754 session it closes the FIFO. Hence, with this call
755 explicitly turn off the FIFO logic, so that the PAM code
756 can finish clean up on its own */
757 session_remove_fifo(session);
758 session_save(session);
759 user_save(session->user);
761 return sd_bus_reply_method_return(message, NULL);
764 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
765 Manager *m = userdata;
774 r = sd_bus_message_read(message, "s", &name);
778 session = hashmap_get(m->sessions, name);
780 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
782 r = session_activate(session);
786 return sd_bus_reply_method_return(message, NULL);
789 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
790 const char *session_name, *seat_name;
791 Manager *m = userdata;
800 /* Same as ActivateSession() but refuses to work if
801 * the seat doesn't match */
803 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
807 session = hashmap_get(m->sessions, session_name);
809 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
811 seat = hashmap_get(m->seats, seat_name);
813 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
815 if (session->seat != seat)
816 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
818 r = session_activate(session);
822 return sd_bus_reply_method_return(message, NULL);
825 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
826 Manager *m = userdata;
835 r = sd_bus_message_read(message, "s", &name);
839 session = hashmap_get(m->sessions, name);
841 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
843 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
847 return sd_bus_reply_method_return(message, NULL);
850 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
851 Manager *m = userdata;
858 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
862 return sd_bus_reply_method_return(message, NULL);
865 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
866 const char *name, *swho;
867 Manager *m = userdata;
877 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
884 who = kill_who_from_string(swho);
886 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
889 if (signo <= 0 || signo >= _NSIG)
890 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
892 session = hashmap_get(m->sessions, name);
894 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
896 r = session_kill(session, who, signo);
900 return sd_bus_reply_method_return(message, NULL);
903 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
904 Manager *m = userdata;
914 r = sd_bus_message_read(message, "ui", &uid, &signo);
918 if (signo <= 0 || signo >= _NSIG)
919 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
921 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
923 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
925 r = user_kill(user, signo);
929 return sd_bus_reply_method_return(message, NULL);
932 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
933 Manager *m = userdata;
942 r = sd_bus_message_read(message, "s", &name);
946 session = hashmap_get(m->sessions, name);
948 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
950 r = session_stop(session);
954 return sd_bus_reply_method_return(message, NULL);
957 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
958 Manager *m = userdata;
967 r = sd_bus_message_read(message, "u", &uid);
971 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
973 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
979 return sd_bus_reply_method_return(message, NULL);
982 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
983 Manager *m = userdata;
992 r = sd_bus_message_read(message, "s", &name);
996 seat = hashmap_get(m->seats, name);
998 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
1000 r = seat_stop_sessions(seat);
1004 return sd_bus_reply_method_return(message, NULL);
1007 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1008 _cleanup_free_ char *cc = NULL;
1009 Manager *m = userdata;
1020 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1027 return errno ? -errno : -ENOENT;
1029 r = bus_verify_polkit_async(bus,
1030 &m->polkit_registry,
1032 "org.freedesktop.login1.set-user-linger",
1035 method_set_user_linger, m);
1039 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1041 mkdir_p_label("/var/lib/systemd", 0755);
1043 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1047 cc = cescape(pw->pw_name);
1051 path = strappenda("/var/lib/systemd/linger/", cc);
1059 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1066 if (r < 0 && errno != ENOENT)
1069 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1071 user_add_to_gc_queue(u);
1074 return sd_bus_reply_method_return(message, NULL);
1077 static int trigger_device(Manager *m, struct udev_device *d) {
1078 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1079 struct udev_list_entry *first, *item;
1084 e = udev_enumerate_new(m->udev);
1089 r = udev_enumerate_add_match_parent(e, d);
1094 r = udev_enumerate_scan_devices(e);
1098 first = udev_enumerate_get_list_entry(e);
1099 udev_list_entry_foreach(item, first) {
1100 _cleanup_free_ char *t = NULL;
1103 p = udev_list_entry_get_name(item);
1105 t = strappend(p, "/uevent");
1109 write_string_file(t, "change");
1115 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1116 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1117 _cleanup_free_ char *rule = NULL, *file = NULL;
1118 const char *id_for_seat;
1125 d = udev_device_new_from_syspath(m->udev, sysfs);
1129 if (!udev_device_has_tag(d, "seat"))
1132 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1136 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1139 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1142 mkdir_p_label("/etc/udev/rules.d", 0755);
1144 r = write_string_file_atomic_label(file, rule);
1148 return trigger_device(m, d);
1151 static int flush_devices(Manager *m) {
1152 _cleanup_closedir_ DIR *d;
1156 d = opendir("/etc/udev/rules.d");
1158 if (errno != ENOENT)
1159 log_warning("Failed to open /etc/udev/rules.d: %m");
1163 while ((de = readdir(d))) {
1165 if (!dirent_is_file(de))
1168 if (!startswith(de->d_name, "72-seat-"))
1171 if (!endswith(de->d_name, ".rules"))
1174 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1175 log_warning("Failed to unlink %s: %m", de->d_name);
1179 return trigger_device(m, NULL);
1182 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1183 const char *sysfs, *seat;
1184 Manager *m = userdata;
1191 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1195 if (!path_startswith(sysfs, "/sys"))
1196 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1198 if (!seat_name_is_valid(seat))
1199 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1201 r = bus_verify_polkit_async(bus,
1202 &m->polkit_registry,
1204 "org.freedesktop.login1.attach-device",
1207 method_attach_device, m);
1211 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1213 r = attach_device(m, seat, sysfs);
1217 return sd_bus_reply_method_return(message, NULL);
1220 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1221 Manager *m = userdata;
1228 r = sd_bus_message_read(message, "b", &interactive);
1232 r = bus_verify_polkit_async(bus,
1233 &m->polkit_registry,
1235 "org.freedesktop.login1.flush-devices",
1238 method_flush_devices, m);
1242 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1244 r = flush_devices(m);
1248 return sd_bus_reply_method_return(message, NULL);
1251 static int have_multiple_sessions(
1260 /* Check for other users' sessions. Greeter sessions do not
1261 * count, and non-login sessions do not count either. */
1262 HASHMAP_FOREACH(session, m->sessions, i)
1263 if (session->class == SESSION_USER &&
1264 session->user->uid != uid)
1270 static int bus_manager_log_shutdown(
1273 const char *unit_name) {
1280 if (w != INHIBIT_SHUTDOWN)
1283 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1284 p = "MESSAGE=System is powering down.";
1285 q = "SHUTDOWN=power-off";
1286 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1287 p = "MESSAGE=System is halting.";
1288 q = "SHUTDOWN=halt";
1289 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1290 p = "MESSAGE=System is rebooting.";
1291 q = "SHUTDOWN=reboot";
1292 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1293 p = "MESSAGE=System is rebooting with kexec.";
1294 q = "SHUTDOWN=kexec";
1296 p = "MESSAGE=System is shutting down.";
1300 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1305 static int execute_shutdown_or_sleep(
1308 const char *unit_name,
1309 sd_bus_error *error) {
1311 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1318 assert(w < _INHIBIT_WHAT_MAX);
1321 bus_manager_log_shutdown(m, w, unit_name);
1323 r = sd_bus_call_method(
1325 "org.freedesktop.systemd1",
1326 "/org/freedesktop/systemd1",
1327 "org.freedesktop.systemd1.Manager",
1331 "ss", unit_name, "replace-irreversibly");
1335 r = sd_bus_message_read(reply, "o", &p);
1343 m->action_unit = unit_name;
1344 free(m->action_job);
1351 static int delay_shutdown_or_sleep(
1354 const char *unit_name) {
1358 assert(w < _INHIBIT_WHAT_MAX);
1361 m->action_timestamp = now(CLOCK_MONOTONIC);
1362 m->action_unit = unit_name;
1368 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1370 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1371 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1372 [INHIBIT_SLEEP] = "PrepareForSleep"
1375 int active = _active;
1379 assert(w < _INHIBIT_WHAT_MAX);
1380 assert(signal_name[w]);
1382 return sd_bus_emit_signal(m->bus,
1383 "/org/freedesktop/login1",
1384 "org.freedesktop.login1.Manager",
1390 int bus_manager_shutdown_or_sleep_now_or_later(
1392 const char *unit_name,
1394 sd_bus_error *error) {
1402 assert(w <= _INHIBIT_WHAT_MAX);
1403 assert(!m->action_job);
1405 /* Tell everybody to prepare for shutdown/sleep */
1406 send_prepare_for(m, w, true);
1409 m->inhibit_delay_max > 0 &&
1410 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1413 /* Shutdown is delayed, keep in mind what we
1414 * want to do, and start a timeout */
1415 r = delay_shutdown_or_sleep(m, w, unit_name);
1417 /* Shutdown is not delayed, execute it
1419 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1424 static int method_do_shutdown_or_sleep(
1426 sd_bus_message *message,
1427 const char *unit_name,
1430 const char *action_multiple_sessions,
1431 const char *action_ignore_inhibit,
1432 const char *sleep_verb,
1433 sd_bus_message_handler_t method,
1434 sd_bus_error *error) {
1436 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1437 bool multiple_sessions, blocked;
1445 assert(w <= _INHIBIT_WHAT_MAX);
1447 assert(action_multiple_sessions);
1448 assert(action_ignore_inhibit);
1451 r = sd_bus_message_read(message, "b", &interactive);
1455 /* Don't allow multiple jobs being executed at the same time */
1457 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1460 r = can_sleep(sleep_verb);
1465 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1468 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1472 r = sd_bus_creds_get_uid(creds, &uid);
1476 r = have_multiple_sessions(m, uid);
1480 multiple_sessions = r > 0;
1481 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1483 if (multiple_sessions) {
1484 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1485 action_multiple_sessions, interactive, error, method, m);
1491 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1492 action_ignore_inhibit, interactive, error, method, m);
1497 if (!multiple_sessions && !blocked) {
1498 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1499 action, interactive, error, method, m);
1504 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1508 return sd_bus_reply_method_return(message, NULL);
1511 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1512 Manager *m = userdata;
1514 return method_do_shutdown_or_sleep(
1516 SPECIAL_POWEROFF_TARGET,
1518 "org.freedesktop.login1.power-off",
1519 "org.freedesktop.login1.power-off-multiple-sessions",
1520 "org.freedesktop.login1.power-off-ignore-inhibit",
1526 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1527 Manager *m = userdata;
1529 return method_do_shutdown_or_sleep(
1531 SPECIAL_REBOOT_TARGET,
1533 "org.freedesktop.login1.reboot",
1534 "org.freedesktop.login1.reboot-multiple-sessions",
1535 "org.freedesktop.login1.reboot-ignore-inhibit",
1541 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1542 Manager *m = userdata;
1544 return method_do_shutdown_or_sleep(
1546 SPECIAL_SUSPEND_TARGET,
1548 "org.freedesktop.login1.suspend",
1549 "org.freedesktop.login1.suspend-multiple-sessions",
1550 "org.freedesktop.login1.suspend-ignore-inhibit",
1556 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1557 Manager *m = userdata;
1559 return method_do_shutdown_or_sleep(
1561 SPECIAL_HIBERNATE_TARGET,
1563 "org.freedesktop.login1.hibernate",
1564 "org.freedesktop.login1.hibernate-multiple-sessions",
1565 "org.freedesktop.login1.hibernate-ignore-inhibit",
1571 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1572 Manager *m = userdata;
1574 return method_do_shutdown_or_sleep(
1576 SPECIAL_HYBRID_SLEEP_TARGET,
1578 "org.freedesktop.login1.hibernate",
1579 "org.freedesktop.login1.hibernate-multiple-sessions",
1580 "org.freedesktop.login1.hibernate-ignore-inhibit",
1582 method_hybrid_sleep,
1586 static int method_can_shutdown_or_sleep(
1588 sd_bus_message *message,
1591 const char *action_multiple_sessions,
1592 const char *action_ignore_inhibit,
1593 const char *sleep_verb,
1594 sd_bus_error *error) {
1596 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1597 bool multiple_sessions, challenge, blocked;
1598 const char *result = NULL;
1605 assert(w <= _INHIBIT_WHAT_MAX);
1607 assert(action_multiple_sessions);
1608 assert(action_ignore_inhibit);
1611 r = can_sleep(sleep_verb);
1615 return sd_bus_reply_method_return(message, "s", "na");
1618 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1622 r = sd_bus_creds_get_uid(creds, &uid);
1626 r = have_multiple_sessions(m, uid);
1630 multiple_sessions = r > 0;
1631 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1633 if (multiple_sessions) {
1634 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1641 result = "challenge";
1647 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1651 if (r > 0 && !result)
1653 else if (challenge && (!result || streq(result, "yes")))
1654 result = "challenge";
1659 if (!multiple_sessions && !blocked) {
1660 /* If neither inhibit nor multiple sessions
1661 * apply then just check the normal policy */
1663 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1670 result = "challenge";
1675 return sd_bus_reply_method_return(message, "s", result);
1678 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1679 Manager *m = userdata;
1681 return method_can_shutdown_or_sleep(
1684 "org.freedesktop.login1.power-off",
1685 "org.freedesktop.login1.power-off-multiple-sessions",
1686 "org.freedesktop.login1.power-off-ignore-inhibit",
1691 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1692 Manager *m = userdata;
1694 return method_can_shutdown_or_sleep(
1697 "org.freedesktop.login1.reboot",
1698 "org.freedesktop.login1.reboot-multiple-sessions",
1699 "org.freedesktop.login1.reboot-ignore-inhibit",
1704 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1705 Manager *m = userdata;
1707 return method_can_shutdown_or_sleep(
1710 "org.freedesktop.login1.suspend",
1711 "org.freedesktop.login1.suspend-multiple-sessions",
1712 "org.freedesktop.login1.suspend-ignore-inhibit",
1717 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1718 Manager *m = userdata;
1720 return method_can_shutdown_or_sleep(
1723 "org.freedesktop.login1.hibernate",
1724 "org.freedesktop.login1.hibernate-multiple-sessions",
1725 "org.freedesktop.login1.hibernate-ignore-inhibit",
1730 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1731 Manager *m = userdata;
1733 return method_can_shutdown_or_sleep(
1736 "org.freedesktop.login1.hibernate",
1737 "org.freedesktop.login1.hibernate-multiple-sessions",
1738 "org.freedesktop.login1.hibernate-ignore-inhibit",
1743 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1744 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1745 const char *who, *why, *what, *mode;
1746 _cleanup_free_ char *id = NULL;
1747 _cleanup_close_ int fifo_fd = -1;
1748 Manager *m = userdata;
1749 Inhibitor *i = NULL;
1760 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1764 w = inhibit_what_from_string(what);
1766 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1768 mm = inhibit_mode_from_string(mode);
1770 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1772 /* Delay is only supported for shutdown/sleep */
1773 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1774 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1776 /* Don't allow taking delay locks while we are already
1777 * executing the operation. We shouldn't create the impression
1778 * that the lock was successful if the machine is about to go
1779 * down/suspend any moment. */
1780 if (m->action_what & w)
1781 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1783 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1784 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1785 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1786 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1787 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1788 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1789 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1790 "org.freedesktop.login1.inhibit-handle-lid-switch",
1791 false, error, method_inhibit, m);
1795 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1797 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1801 r = sd_bus_creds_get_uid(creds, &uid);
1805 r = sd_bus_creds_get_pid(creds, &pid);
1813 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1816 } while (hashmap_get(m->inhibitors, id));
1818 r = manager_add_inhibitor(m, id, &i);
1826 i->why = strdup(why);
1827 i->who = strdup(who);
1829 if (!i->why || !i->who) {
1834 fifo_fd = inhibitor_create_fifo(i);
1842 return sd_bus_reply_method_return(message, "h", fifo_fd);
1851 const sd_bus_vtable manager_vtable[] = {
1852 SD_BUS_VTABLE_START(0),
1854 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1855 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1856 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1857 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1858 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1859 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1860 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1861 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1862 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1863 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1864 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1865 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1866 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1867 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1868 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1869 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1870 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1871 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1873 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1874 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1875 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1876 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1877 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1878 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1879 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1880 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1881 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1882 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1883 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1884 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1885 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1887 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1888 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1889 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1890 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1891 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1892 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1893 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1894 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1895 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1896 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1897 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1899 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1900 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1901 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1902 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1903 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1904 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1905 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1906 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1907 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1908 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1910 SD_BUS_SIGNAL("SessionNew", "so", 0),
1911 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1912 SD_BUS_SIGNAL("UserNew", "uo", 0),
1913 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1914 SD_BUS_SIGNAL("SeatNew", "so", 0),
1915 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1916 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1917 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1922 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1923 const char *path, *result, *unit;
1924 Manager *m = userdata;
1934 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1936 bus_log_parse_error(r);
1940 if (m->action_job && streq(m->action_job, path)) {
1941 log_info("Operation finished.");
1943 /* Tell people that they now may take a lock again */
1944 send_prepare_for(m, m->action_what, false);
1946 free(m->action_job);
1947 m->action_job = NULL;
1948 m->action_unit = NULL;
1953 session = hashmap_get(m->session_units, unit);
1956 if (streq_ptr(path, session->scope_job)) {
1957 free(session->scope_job);
1958 session->scope_job = NULL;
1961 if (session->started) {
1962 if (streq(result, "done"))
1963 session_send_create_reply(session, NULL);
1965 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1967 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1968 session_send_create_reply(session, &e);
1971 session_save(session);
1973 session_add_to_gc_queue(session);
1976 user = hashmap_get(m->user_units, unit);
1979 if (streq_ptr(path, user->service_job)) {
1980 free(user->service_job);
1981 user->service_job = NULL;
1984 if (streq_ptr(path, user->slice_job)) {
1985 free(user->slice_job);
1986 user->slice_job = NULL;
1989 LIST_FOREACH(sessions_by_user, session, user->sessions) {
1990 if (!session->started)
1993 if (streq(result, "done"))
1994 session_send_create_reply(session, NULL);
1996 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1998 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1999 session_send_create_reply(session, &e);
2004 user_add_to_gc_queue(user);
2010 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2011 const char *path, *unit;
2012 Manager *m = userdata;
2021 r = sd_bus_message_read(message, "so", &unit, &path);
2023 bus_log_parse_error(r);
2027 session = hashmap_get(m->session_units, unit);
2029 session_add_to_gc_queue(session);
2031 user = hashmap_get(m->user_units, unit);
2033 user_add_to_gc_queue(user);
2038 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2039 _cleanup_free_ char *unit = NULL;
2040 Manager *m = userdata;
2050 path = sd_bus_message_get_path(message);
2054 r = unit_name_from_dbus_path(path, &unit);
2058 session = hashmap_get(m->session_units, unit);
2060 session_add_to_gc_queue(session);
2062 user = hashmap_get(m->user_units, unit);
2064 user_add_to_gc_queue(user);
2069 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2070 Manager *m = userdata;
2077 r = sd_bus_message_read(message, "b", &b);
2079 bus_log_parse_error(r);
2086 /* systemd finished reloading, let's recheck all our sessions */
2087 log_debug("System manager has been reloaded, rechecking sessions...");
2089 HASHMAP_FOREACH(session, m->sessions, i)
2090 session_add_to_gc_queue(session);
2095 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2096 const char *name, *old, *new;
2097 Manager *m = userdata;
2105 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2107 bus_log_parse_error(r);
2111 if (isempty(old) || !isempty(new))
2114 key = set_remove(m->busnames, (char*) old);
2118 /* Drop all controllers owned by this name */
2122 HASHMAP_FOREACH(session, m->sessions, i)
2123 if (session_is_controller(session, old))
2124 session_drop_controller(session);
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 || manager->action_job)
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 %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2164 (unsigned long) offending->uid, strna(u),
2165 (unsigned long) offending->pid, strna(comm));
2168 /* Actually do the operation */
2169 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2171 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2173 manager->action_unit = NULL;
2174 manager->action_what = 0;
2181 int manager_start_scope(
2186 const char *description,
2188 const char *kill_mode,
2189 sd_bus_error *error,
2192 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2199 r = sd_bus_message_new_method_call(
2201 "org.freedesktop.systemd1",
2202 "/org/freedesktop/systemd1",
2203 "org.freedesktop.systemd1.Manager",
2204 "StartTransientUnit",
2209 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2213 r = sd_bus_message_open_container(m, 'a', "(sv)");
2217 if (!isempty(slice)) {
2218 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2223 if (!isempty(description)) {
2224 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2229 if (!isempty(description)) {
2230 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2235 if (!isempty(kill_mode)) {
2236 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2241 /* cgroup empty notification is not available in containers
2242 * currently. To make this less problematic, let's shorten the
2243 * stop timeout for sessions, so that we don't wait
2246 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2250 /* Make sure that the session shells are terminated with
2251 * SIGHUP since bash and friends tend to ignore SIGTERM */
2252 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2256 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2260 r = sd_bus_message_close_container(m);
2264 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2268 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2276 r = sd_bus_message_read(reply, "o", &j);
2290 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2291 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2297 r = sd_bus_call_method(
2299 "org.freedesktop.systemd1",
2300 "/org/freedesktop/systemd1",
2301 "org.freedesktop.systemd1.Manager",
2305 "ss", unit, "fail");
2313 r = sd_bus_message_read(reply, "o", &j);
2327 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2328 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2334 r = sd_bus_call_method(
2336 "org.freedesktop.systemd1",
2337 "/org/freedesktop/systemd1",
2338 "org.freedesktop.systemd1.Manager",
2342 "ss", unit, "fail");
2344 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2345 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2350 sd_bus_error_free(error);
2361 r = sd_bus_message_read(reply, "o", &j);
2375 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2379 return sd_bus_call_method(
2381 "org.freedesktop.systemd1",
2382 "/org/freedesktop/systemd1",
2383 "org.freedesktop.systemd1.Manager",
2387 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2390 int manager_unit_is_active(Manager *manager, const char *unit) {
2391 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2392 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2393 _cleanup_free_ char *path = NULL;
2400 path = unit_dbus_path_from_name(unit);
2404 r = sd_bus_get_property(
2406 "org.freedesktop.systemd1",
2408 "org.freedesktop.systemd1.Unit",
2414 /* systemd might have droppped off momentarily, let's
2415 * not make this an error */
2416 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2417 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2420 /* If the unit is already unloaded then it's not
2422 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2423 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2429 r = sd_bus_message_read(reply, "s", &state);
2433 return !streq(state, "inactive") && !streq(state, "failed");
2436 int manager_job_is_active(Manager *manager, const char *path) {
2437 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2438 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2444 r = sd_bus_get_property(
2446 "org.freedesktop.systemd1",
2448 "org.freedesktop.systemd1.Job",
2454 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2455 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2458 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2464 /* We don't actually care about the state really. The fact
2465 * that we could read the job state is enough for us */