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 session_release(session);
753 return sd_bus_reply_method_return(message, NULL);
756 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
757 Manager *m = userdata;
766 r = sd_bus_message_read(message, "s", &name);
770 session = hashmap_get(m->sessions, name);
772 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
774 r = session_activate(session);
778 return sd_bus_reply_method_return(message, NULL);
781 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
782 const char *session_name, *seat_name;
783 Manager *m = userdata;
792 /* Same as ActivateSession() but refuses to work if
793 * the seat doesn't match */
795 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
799 session = hashmap_get(m->sessions, session_name);
801 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
803 seat = hashmap_get(m->seats, seat_name);
805 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
807 if (session->seat != seat)
808 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
810 r = session_activate(session);
814 return sd_bus_reply_method_return(message, NULL);
817 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
818 Manager *m = userdata;
827 r = sd_bus_message_read(message, "s", &name);
831 session = hashmap_get(m->sessions, name);
833 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
835 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
839 return sd_bus_reply_method_return(message, NULL);
842 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
843 Manager *m = userdata;
850 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
854 return sd_bus_reply_method_return(message, NULL);
857 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
858 const char *name, *swho;
859 Manager *m = userdata;
869 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
876 who = kill_who_from_string(swho);
878 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
881 if (signo <= 0 || signo >= _NSIG)
882 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
884 session = hashmap_get(m->sessions, name);
886 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
888 r = session_kill(session, who, signo);
892 return sd_bus_reply_method_return(message, NULL);
895 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
896 Manager *m = userdata;
906 r = sd_bus_message_read(message, "ui", &uid, &signo);
910 if (signo <= 0 || signo >= _NSIG)
911 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
913 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
915 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
917 r = user_kill(user, signo);
921 return sd_bus_reply_method_return(message, NULL);
924 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
925 Manager *m = userdata;
934 r = sd_bus_message_read(message, "s", &name);
938 session = hashmap_get(m->sessions, name);
940 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
942 r = session_stop(session);
946 return sd_bus_reply_method_return(message, NULL);
949 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
950 Manager *m = userdata;
959 r = sd_bus_message_read(message, "u", &uid);
963 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
965 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
971 return sd_bus_reply_method_return(message, NULL);
974 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
975 Manager *m = userdata;
984 r = sd_bus_message_read(message, "s", &name);
988 seat = hashmap_get(m->seats, name);
990 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
992 r = seat_stop_sessions(seat);
996 return sd_bus_reply_method_return(message, NULL);
999 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1000 _cleanup_free_ char *cc = NULL;
1001 Manager *m = userdata;
1012 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1019 return errno ? -errno : -ENOENT;
1021 r = bus_verify_polkit_async(bus,
1022 &m->polkit_registry,
1024 "org.freedesktop.login1.set-user-linger",
1027 method_set_user_linger, m);
1031 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1033 mkdir_p_label("/var/lib/systemd", 0755);
1035 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1039 cc = cescape(pw->pw_name);
1043 path = strappenda("/var/lib/systemd/linger/", cc);
1051 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1058 if (r < 0 && errno != ENOENT)
1061 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1063 user_add_to_gc_queue(u);
1066 return sd_bus_reply_method_return(message, NULL);
1069 static int trigger_device(Manager *m, struct udev_device *d) {
1070 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1071 struct udev_list_entry *first, *item;
1076 e = udev_enumerate_new(m->udev);
1081 r = udev_enumerate_add_match_parent(e, d);
1086 r = udev_enumerate_scan_devices(e);
1090 first = udev_enumerate_get_list_entry(e);
1091 udev_list_entry_foreach(item, first) {
1092 _cleanup_free_ char *t = NULL;
1095 p = udev_list_entry_get_name(item);
1097 t = strappend(p, "/uevent");
1101 write_string_file(t, "change");
1107 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1108 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1109 _cleanup_free_ char *rule = NULL, *file = NULL;
1110 const char *id_for_seat;
1117 d = udev_device_new_from_syspath(m->udev, sysfs);
1121 if (!udev_device_has_tag(d, "seat"))
1124 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1128 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1131 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1134 mkdir_p_label("/etc/udev/rules.d", 0755);
1136 r = write_string_file_atomic_label(file, rule);
1140 return trigger_device(m, d);
1143 static int flush_devices(Manager *m) {
1144 _cleanup_closedir_ DIR *d;
1148 d = opendir("/etc/udev/rules.d");
1150 if (errno != ENOENT)
1151 log_warning("Failed to open /etc/udev/rules.d: %m");
1155 while ((de = readdir(d))) {
1157 if (!dirent_is_file(de))
1160 if (!startswith(de->d_name, "72-seat-"))
1163 if (!endswith(de->d_name, ".rules"))
1166 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1167 log_warning("Failed to unlink %s: %m", de->d_name);
1171 return trigger_device(m, NULL);
1174 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1175 const char *sysfs, *seat;
1176 Manager *m = userdata;
1183 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1187 if (!path_startswith(sysfs, "/sys"))
1188 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1190 if (!seat_name_is_valid(seat))
1191 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1193 r = bus_verify_polkit_async(bus,
1194 &m->polkit_registry,
1196 "org.freedesktop.login1.attach-device",
1199 method_attach_device, m);
1203 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1205 r = attach_device(m, seat, sysfs);
1209 return sd_bus_reply_method_return(message, NULL);
1212 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1213 Manager *m = userdata;
1220 r = sd_bus_message_read(message, "b", &interactive);
1224 r = bus_verify_polkit_async(bus,
1225 &m->polkit_registry,
1227 "org.freedesktop.login1.flush-devices",
1230 method_flush_devices, m);
1234 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1236 r = flush_devices(m);
1240 return sd_bus_reply_method_return(message, NULL);
1243 static int have_multiple_sessions(
1252 /* Check for other users' sessions. Greeter sessions do not
1253 * count, and non-login sessions do not count either. */
1254 HASHMAP_FOREACH(session, m->sessions, i)
1255 if (session->class == SESSION_USER &&
1256 session->user->uid != uid)
1262 static int bus_manager_log_shutdown(
1265 const char *unit_name) {
1272 if (w != INHIBIT_SHUTDOWN)
1275 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1276 p = "MESSAGE=System is powering down.";
1277 q = "SHUTDOWN=power-off";
1278 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1279 p = "MESSAGE=System is halting.";
1280 q = "SHUTDOWN=halt";
1281 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1282 p = "MESSAGE=System is rebooting.";
1283 q = "SHUTDOWN=reboot";
1284 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1285 p = "MESSAGE=System is rebooting with kexec.";
1286 q = "SHUTDOWN=kexec";
1288 p = "MESSAGE=System is shutting down.";
1292 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1297 static int execute_shutdown_or_sleep(
1300 const char *unit_name,
1301 sd_bus_error *error) {
1303 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1310 assert(w < _INHIBIT_WHAT_MAX);
1313 bus_manager_log_shutdown(m, w, unit_name);
1315 r = sd_bus_call_method(
1317 "org.freedesktop.systemd1",
1318 "/org/freedesktop/systemd1",
1319 "org.freedesktop.systemd1.Manager",
1323 "ss", unit_name, "replace-irreversibly");
1327 r = sd_bus_message_read(reply, "o", &p);
1335 m->action_unit = unit_name;
1336 free(m->action_job);
1343 static int delay_shutdown_or_sleep(
1346 const char *unit_name) {
1350 assert(w < _INHIBIT_WHAT_MAX);
1353 m->action_timestamp = now(CLOCK_MONOTONIC);
1354 m->action_unit = unit_name;
1360 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1362 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1363 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1364 [INHIBIT_SLEEP] = "PrepareForSleep"
1367 int active = _active;
1371 assert(w < _INHIBIT_WHAT_MAX);
1372 assert(signal_name[w]);
1374 return sd_bus_emit_signal(m->bus,
1375 "/org/freedesktop/login1",
1376 "org.freedesktop.login1.Manager",
1382 int bus_manager_shutdown_or_sleep_now_or_later(
1384 const char *unit_name,
1386 sd_bus_error *error) {
1394 assert(w <= _INHIBIT_WHAT_MAX);
1395 assert(!m->action_job);
1397 /* Tell everybody to prepare for shutdown/sleep */
1398 send_prepare_for(m, w, true);
1401 m->inhibit_delay_max > 0 &&
1402 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1405 /* Shutdown is delayed, keep in mind what we
1406 * want to do, and start a timeout */
1407 r = delay_shutdown_or_sleep(m, w, unit_name);
1409 /* Shutdown is not delayed, execute it
1411 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1416 static int method_do_shutdown_or_sleep(
1418 sd_bus_message *message,
1419 const char *unit_name,
1422 const char *action_multiple_sessions,
1423 const char *action_ignore_inhibit,
1424 const char *sleep_verb,
1425 sd_bus_message_handler_t method,
1426 sd_bus_error *error) {
1428 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1429 bool multiple_sessions, blocked;
1437 assert(w <= _INHIBIT_WHAT_MAX);
1439 assert(action_multiple_sessions);
1440 assert(action_ignore_inhibit);
1443 r = sd_bus_message_read(message, "b", &interactive);
1447 /* Don't allow multiple jobs being executed at the same time */
1449 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1452 r = can_sleep(sleep_verb);
1457 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1460 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1464 r = sd_bus_creds_get_uid(creds, &uid);
1468 r = have_multiple_sessions(m, uid);
1472 multiple_sessions = r > 0;
1473 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1475 if (multiple_sessions) {
1476 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1477 action_multiple_sessions, interactive, error, method, m);
1483 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1484 action_ignore_inhibit, interactive, error, method, m);
1489 if (!multiple_sessions && !blocked) {
1490 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1491 action, interactive, error, method, m);
1496 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1500 return sd_bus_reply_method_return(message, NULL);
1503 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1504 Manager *m = userdata;
1506 return method_do_shutdown_or_sleep(
1508 SPECIAL_POWEROFF_TARGET,
1510 "org.freedesktop.login1.power-off",
1511 "org.freedesktop.login1.power-off-multiple-sessions",
1512 "org.freedesktop.login1.power-off-ignore-inhibit",
1518 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1519 Manager *m = userdata;
1521 return method_do_shutdown_or_sleep(
1523 SPECIAL_REBOOT_TARGET,
1525 "org.freedesktop.login1.reboot",
1526 "org.freedesktop.login1.reboot-multiple-sessions",
1527 "org.freedesktop.login1.reboot-ignore-inhibit",
1533 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1534 Manager *m = userdata;
1536 return method_do_shutdown_or_sleep(
1538 SPECIAL_SUSPEND_TARGET,
1540 "org.freedesktop.login1.suspend",
1541 "org.freedesktop.login1.suspend-multiple-sessions",
1542 "org.freedesktop.login1.suspend-ignore-inhibit",
1548 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1549 Manager *m = userdata;
1551 return method_do_shutdown_or_sleep(
1553 SPECIAL_HIBERNATE_TARGET,
1555 "org.freedesktop.login1.hibernate",
1556 "org.freedesktop.login1.hibernate-multiple-sessions",
1557 "org.freedesktop.login1.hibernate-ignore-inhibit",
1563 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1564 Manager *m = userdata;
1566 return method_do_shutdown_or_sleep(
1568 SPECIAL_HYBRID_SLEEP_TARGET,
1570 "org.freedesktop.login1.hibernate",
1571 "org.freedesktop.login1.hibernate-multiple-sessions",
1572 "org.freedesktop.login1.hibernate-ignore-inhibit",
1574 method_hybrid_sleep,
1578 static int method_can_shutdown_or_sleep(
1580 sd_bus_message *message,
1583 const char *action_multiple_sessions,
1584 const char *action_ignore_inhibit,
1585 const char *sleep_verb,
1586 sd_bus_error *error) {
1588 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1589 bool multiple_sessions, challenge, blocked;
1590 const char *result = NULL;
1597 assert(w <= _INHIBIT_WHAT_MAX);
1599 assert(action_multiple_sessions);
1600 assert(action_ignore_inhibit);
1603 r = can_sleep(sleep_verb);
1607 return sd_bus_reply_method_return(message, "s", "na");
1610 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1614 r = sd_bus_creds_get_uid(creds, &uid);
1618 r = have_multiple_sessions(m, uid);
1622 multiple_sessions = r > 0;
1623 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1625 if (multiple_sessions) {
1626 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1633 result = "challenge";
1639 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1643 if (r > 0 && !result)
1645 else if (challenge && (!result || streq(result, "yes")))
1646 result = "challenge";
1651 if (!multiple_sessions && !blocked) {
1652 /* If neither inhibit nor multiple sessions
1653 * apply then just check the normal policy */
1655 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1662 result = "challenge";
1667 return sd_bus_reply_method_return(message, "s", result);
1670 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1671 Manager *m = userdata;
1673 return method_can_shutdown_or_sleep(
1676 "org.freedesktop.login1.power-off",
1677 "org.freedesktop.login1.power-off-multiple-sessions",
1678 "org.freedesktop.login1.power-off-ignore-inhibit",
1683 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1684 Manager *m = userdata;
1686 return method_can_shutdown_or_sleep(
1689 "org.freedesktop.login1.reboot",
1690 "org.freedesktop.login1.reboot-multiple-sessions",
1691 "org.freedesktop.login1.reboot-ignore-inhibit",
1696 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1697 Manager *m = userdata;
1699 return method_can_shutdown_or_sleep(
1702 "org.freedesktop.login1.suspend",
1703 "org.freedesktop.login1.suspend-multiple-sessions",
1704 "org.freedesktop.login1.suspend-ignore-inhibit",
1709 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1710 Manager *m = userdata;
1712 return method_can_shutdown_or_sleep(
1715 "org.freedesktop.login1.hibernate",
1716 "org.freedesktop.login1.hibernate-multiple-sessions",
1717 "org.freedesktop.login1.hibernate-ignore-inhibit",
1722 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1723 Manager *m = userdata;
1725 return method_can_shutdown_or_sleep(
1728 "org.freedesktop.login1.hibernate",
1729 "org.freedesktop.login1.hibernate-multiple-sessions",
1730 "org.freedesktop.login1.hibernate-ignore-inhibit",
1735 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1736 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1737 const char *who, *why, *what, *mode;
1738 _cleanup_free_ char *id = NULL;
1739 _cleanup_close_ int fifo_fd = -1;
1740 Manager *m = userdata;
1741 Inhibitor *i = NULL;
1752 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1756 w = inhibit_what_from_string(what);
1758 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1760 mm = inhibit_mode_from_string(mode);
1762 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1764 /* Delay is only supported for shutdown/sleep */
1765 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1766 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1768 /* Don't allow taking delay locks while we are already
1769 * executing the operation. We shouldn't create the impression
1770 * that the lock was successful if the machine is about to go
1771 * down/suspend any moment. */
1772 if (m->action_what & w)
1773 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1775 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1776 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1777 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1778 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1779 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1780 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1781 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1782 "org.freedesktop.login1.inhibit-handle-lid-switch",
1783 false, error, method_inhibit, m);
1787 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1789 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1793 r = sd_bus_creds_get_uid(creds, &uid);
1797 r = sd_bus_creds_get_pid(creds, &pid);
1805 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1808 } while (hashmap_get(m->inhibitors, id));
1810 r = manager_add_inhibitor(m, id, &i);
1818 i->why = strdup(why);
1819 i->who = strdup(who);
1821 if (!i->why || !i->who) {
1826 fifo_fd = inhibitor_create_fifo(i);
1834 return sd_bus_reply_method_return(message, "h", fifo_fd);
1843 const sd_bus_vtable manager_vtable[] = {
1844 SD_BUS_VTABLE_START(0),
1846 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1847 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1848 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1849 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1850 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1851 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1852 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1853 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1854 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1855 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1856 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1857 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1858 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1859 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1860 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1861 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1862 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1863 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1865 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1866 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1867 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1868 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1869 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1870 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1871 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1872 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1873 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1874 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1875 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1876 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1877 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1878 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1879 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1880 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1881 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1882 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1883 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1884 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1885 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1886 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1887 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1888 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1889 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1890 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1893 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1894 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1895 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1896 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1897 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1899 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1900 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1902 SD_BUS_SIGNAL("SessionNew", "so", 0),
1903 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1904 SD_BUS_SIGNAL("UserNew", "uo", 0),
1905 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1906 SD_BUS_SIGNAL("SeatNew", "so", 0),
1907 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1908 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1909 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1914 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1923 if (streq(result, "done"))
1924 r = session_send_create_reply(s, NULL);
1926 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1928 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1929 r = session_send_create_reply(s, &e);
1935 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1936 const char *path, *result, *unit;
1937 Manager *m = userdata;
1947 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1949 bus_log_parse_error(r);
1953 if (m->action_job && streq(m->action_job, path)) {
1954 log_info("Operation finished.");
1956 /* Tell people that they now may take a lock again */
1957 send_prepare_for(m, m->action_what, false);
1959 free(m->action_job);
1960 m->action_job = NULL;
1961 m->action_unit = NULL;
1966 session = hashmap_get(m->session_units, unit);
1969 if (streq_ptr(path, session->scope_job)) {
1970 free(session->scope_job);
1971 session->scope_job = NULL;
1974 session_jobs_reply(session, unit, result);
1976 session_save(session);
1977 session_add_to_gc_queue(session);
1980 user = hashmap_get(m->user_units, unit);
1983 if (streq_ptr(path, user->service_job)) {
1984 free(user->service_job);
1985 user->service_job = NULL;
1988 if (streq_ptr(path, user->slice_job)) {
1989 free(user->slice_job);
1990 user->slice_job = NULL;
1993 LIST_FOREACH(sessions_by_user, session, user->sessions) {
1994 session_jobs_reply(session, unit, result);
1998 user_add_to_gc_queue(user);
2004 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2005 const char *path, *unit;
2006 Manager *m = userdata;
2015 r = sd_bus_message_read(message, "so", &unit, &path);
2017 bus_log_parse_error(r);
2021 session = hashmap_get(m->session_units, unit);
2023 session_add_to_gc_queue(session);
2025 user = hashmap_get(m->user_units, unit);
2027 user_add_to_gc_queue(user);
2032 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2033 _cleanup_free_ char *unit = NULL;
2034 Manager *m = userdata;
2044 path = sd_bus_message_get_path(message);
2048 r = unit_name_from_dbus_path(path, &unit);
2052 session = hashmap_get(m->session_units, unit);
2054 session_add_to_gc_queue(session);
2056 user = hashmap_get(m->user_units, unit);
2058 user_add_to_gc_queue(user);
2063 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2064 Manager *m = userdata;
2071 r = sd_bus_message_read(message, "b", &b);
2073 bus_log_parse_error(r);
2080 /* systemd finished reloading, let's recheck all our sessions */
2081 log_debug("System manager has been reloaded, rechecking sessions...");
2083 HASHMAP_FOREACH(session, m->sessions, i)
2084 session_add_to_gc_queue(session);
2089 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2090 const char *name, *old, *new;
2091 Manager *m = userdata;
2099 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2101 bus_log_parse_error(r);
2105 if (isempty(old) || !isempty(new))
2108 key = set_remove(m->busnames, (char*) old);
2112 /* Drop all controllers owned by this name */
2116 HASHMAP_FOREACH(session, m->sessions, i)
2117 if (session_is_controller(session, old))
2118 session_drop_controller(session);
2123 int manager_send_changed(Manager *manager, const char *property, ...) {
2128 l = strv_from_stdarg_alloca(property);
2130 return sd_bus_emit_properties_changed_strv(
2132 "/org/freedesktop/login1",
2133 "org.freedesktop.login1.Manager",
2137 int manager_dispatch_delayed(Manager *manager) {
2138 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2139 Inhibitor *offending = NULL;
2144 if (manager->action_what == 0 || manager->action_job)
2147 /* Continue delay? */
2148 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2149 _cleanup_free_ char *comm = NULL, *u = NULL;
2151 get_process_comm(offending->pid, &comm);
2152 u = uid_to_name(offending->uid);
2154 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2157 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2158 (unsigned long) offending->uid, strna(u),
2159 (unsigned long) offending->pid, strna(comm));
2162 /* Actually do the operation */
2163 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2165 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2167 manager->action_unit = NULL;
2168 manager->action_what = 0;
2175 int manager_start_scope(
2180 const char *description,
2181 const char *after, const char *after2,
2182 sd_bus_error *error,
2185 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2192 r = sd_bus_message_new_method_call(
2194 "org.freedesktop.systemd1",
2195 "/org/freedesktop/systemd1",
2196 "org.freedesktop.systemd1.Manager",
2197 "StartTransientUnit",
2202 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2206 r = sd_bus_message_open_container(m, 'a', "(sv)");
2210 if (!isempty(slice)) {
2211 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2216 if (!isempty(description)) {
2217 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2222 if (!isempty(after)) {
2223 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2228 if (!isempty(after2)) {
2229 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2234 /* cgroup empty notification is not available in containers
2235 * currently. To make this less problematic, let's shorten the
2236 * stop timeout for sessions, so that we don't wait
2239 /* Make sure that the session shells are terminated with
2240 * SIGHUP since bash and friends tend to ignore SIGTERM */
2241 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2245 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2249 r = sd_bus_message_close_container(m);
2253 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2257 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2265 r = sd_bus_message_read(reply, "o", &j);
2279 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2280 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2286 r = sd_bus_call_method(
2288 "org.freedesktop.systemd1",
2289 "/org/freedesktop/systemd1",
2290 "org.freedesktop.systemd1.Manager",
2294 "ss", unit, "fail");
2302 r = sd_bus_message_read(reply, "o", &j);
2316 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2317 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2323 r = sd_bus_call_method(
2325 "org.freedesktop.systemd1",
2326 "/org/freedesktop/systemd1",
2327 "org.freedesktop.systemd1.Manager",
2331 "ss", unit, "fail");
2333 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2334 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2339 sd_bus_error_free(error);
2350 r = sd_bus_message_read(reply, "o", &j);
2364 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2365 _cleanup_free_ char *path = NULL;
2371 path = unit_dbus_path_from_name(scope);
2375 r = sd_bus_call_method(
2377 "org.freedesktop.systemd1",
2379 "org.freedesktop.systemd1.Scope",
2385 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2386 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2387 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2388 sd_bus_error_free(error);
2398 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2402 return sd_bus_call_method(
2404 "org.freedesktop.systemd1",
2405 "/org/freedesktop/systemd1",
2406 "org.freedesktop.systemd1.Manager",
2410 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2413 int manager_unit_is_active(Manager *manager, const char *unit) {
2414 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2415 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2416 _cleanup_free_ char *path = NULL;
2423 path = unit_dbus_path_from_name(unit);
2427 r = sd_bus_get_property(
2429 "org.freedesktop.systemd1",
2431 "org.freedesktop.systemd1.Unit",
2437 /* systemd might have droppped off momentarily, let's
2438 * not make this an error */
2439 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2440 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2443 /* If the unit is already unloaded then it's not
2445 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2446 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2452 r = sd_bus_message_read(reply, "s", &state);
2456 return !streq(state, "inactive") && !streq(state, "failed");
2459 int manager_job_is_active(Manager *manager, const char *path) {
2460 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2461 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2467 r = sd_bus_get_property(
2469 "org.freedesktop.systemd1",
2471 "org.freedesktop.systemd1.Job",
2477 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2478 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2481 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2487 /* We don't actually care about the state really. The fact
2488 * that we could read the job state is enough for us */