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"
46 static int property_get_idle_hint(
49 const char *interface,
51 sd_bus_message *reply,
53 sd_bus_error *error) {
55 Manager *m = userdata;
61 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
64 static int property_get_idle_since_hint(
67 const char *interface,
69 sd_bus_message *reply,
71 sd_bus_error *error) {
73 Manager *m = userdata;
80 manager_get_idle_hint(m, &t);
82 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
85 static int property_get_inhibited(
88 const char *interface,
90 sd_bus_message *reply,
92 sd_bus_error *error) {
94 Manager *m = userdata;
101 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
103 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
106 static int property_get_preparing(
109 const char *interface,
110 const char *property,
111 sd_bus_message *reply,
113 sd_bus_error *error) {
115 Manager *m = userdata;
122 if (streq(property, "PreparingForShutdown"))
123 b = !!(m->action_what & INHIBIT_SHUTDOWN);
125 b = !!(m->action_what & INHIBIT_SLEEP);
127 return sd_bus_message_append(reply, "b", b);
130 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
132 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
133 _cleanup_free_ char *p = NULL;
134 Manager *m = userdata;
143 r = sd_bus_message_read(message, "s", &name);
147 session = hashmap_get(m->sessions, name);
149 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
151 p = session_bus_path(session);
155 return sd_bus_reply_method_return(message, "o", p);
158 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
159 _cleanup_free_ char *p = NULL;
160 Session *session = NULL;
161 Manager *m = userdata;
169 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
171 r = sd_bus_message_read(message, "u", &pid);
176 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
178 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
182 r = sd_bus_creds_get_pid(creds, &pid);
187 r = manager_get_session_by_pid(m, pid, &session);
191 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
193 p = session_bus_path(session);
197 return sd_bus_reply_method_return(message, "o", p);
200 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
201 _cleanup_free_ char *p = NULL;
202 Manager *m = userdata;
211 r = sd_bus_message_read(message, "u", &uid);
215 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
217 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
219 p = user_bus_path(user);
223 return sd_bus_reply_method_return(message, "o", p);
226 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
227 _cleanup_free_ char *p = NULL;
228 Manager *m = userdata;
237 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
239 r = sd_bus_message_read(message, "u", &pid);
244 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
246 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
250 r = sd_bus_creds_get_pid(creds, &pid);
255 r = manager_get_user_by_pid(m, pid, &user);
259 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);
261 p = user_bus_path(user);
265 return sd_bus_reply_method_return(message, "o", p);
268 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
269 _cleanup_free_ char *p = NULL;
270 Manager *m = userdata;
279 r = sd_bus_message_read(message, "s", &name);
283 seat = hashmap_get(m->seats, name);
285 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
287 p = seat_bus_path(seat);
291 return sd_bus_reply_method_return(message, "o", p);
294 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
295 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
296 Manager *m = userdata;
305 r = sd_bus_message_new_method_return(message, &reply);
309 r = sd_bus_message_open_container(reply, 'a', "(susso)");
313 HASHMAP_FOREACH(session, m->sessions, i) {
314 _cleanup_free_ char *p = NULL;
316 p = session_bus_path(session);
320 r = sd_bus_message_append(reply, "(susso)",
322 (uint32_t) session->user->uid,
324 session->seat ? session->seat->id : "",
330 r = sd_bus_message_close_container(reply);
334 return sd_bus_send(bus, reply, NULL);
337 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
338 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
339 Manager *m = userdata;
348 r = sd_bus_message_new_method_return(message, &reply);
352 r = sd_bus_message_open_container(reply, 'a', "(uso)");
356 HASHMAP_FOREACH(user, m->users, i) {
357 _cleanup_free_ char *p = NULL;
359 p = user_bus_path(user);
363 r = sd_bus_message_append(reply, "(uso)",
364 (uint32_t) user->uid,
371 r = sd_bus_message_close_container(reply);
375 return sd_bus_send(bus, reply, NULL);
378 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
379 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
380 Manager *m = userdata;
389 r = sd_bus_message_new_method_return(message, &reply);
393 r = sd_bus_message_open_container(reply, 'a', "(so)");
397 HASHMAP_FOREACH(seat, m->seats, i) {
398 _cleanup_free_ char *p = NULL;
400 p = seat_bus_path(seat);
404 r = sd_bus_message_append(reply, "(so)", seat->id, p);
409 r = sd_bus_message_close_container(reply);
413 return sd_bus_send(bus, reply, NULL);
416 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
417 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
418 Manager *m = userdata;
419 Inhibitor *inhibitor;
423 r = sd_bus_message_new_method_return(message, &reply);
427 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
431 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
433 r = sd_bus_message_append(reply, "(ssssuu)",
434 strempty(inhibit_what_to_string(inhibitor->what)),
435 strempty(inhibitor->who),
436 strempty(inhibitor->why),
437 strempty(inhibit_mode_to_string(inhibitor->mode)),
438 (uint32_t) inhibitor->uid,
439 (uint32_t) inhibitor->pid);
444 r = sd_bus_message_close_container(reply);
448 return sd_bus_send(bus, reply, NULL);
451 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
452 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
453 uint32_t uid, leader, audit_id = 0;
454 _cleanup_free_ char *id = NULL;
455 Session *session = NULL;
456 Manager *m = userdata;
469 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
474 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
477 t = _SESSION_TYPE_INVALID;
479 t = session_type_from_string(type);
481 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
485 c = _SESSION_CLASS_INVALID;
487 c = session_class_from_string(class);
489 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
495 seat = hashmap_get(m->seats, cseat);
497 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
500 if (tty_is_vc(tty)) {
505 else if (seat != m->seat0)
506 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
508 v = vtnr_from_tty(tty);
510 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
514 else if (vtnr != (uint32_t) v)
515 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
517 } else if (tty_is_console(tty)) {
521 else if (seat != m->seat0)
522 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
525 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
529 if (seat_has_vts(seat)) {
530 if (!vtnr || vtnr > 63)
531 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
534 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
538 r = sd_bus_message_enter_container(message, 'a', "(sv)");
542 if (t == _SESSION_TYPE_INVALID) {
543 if (!isempty(display))
545 else if (!isempty(tty))
548 t = SESSION_UNSPECIFIED;
551 if (c == _SESSION_CLASS_INVALID) {
552 if (!isempty(display) || !isempty(tty))
555 c = SESSION_BACKGROUND;
559 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
561 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
565 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
567 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
572 manager_get_session_by_pid(m, leader, &session);
574 _cleanup_free_ char *path = NULL;
575 _cleanup_close_ int fifo_fd = -1;
577 /* Session already exists, client is probably
578 * something like "su" which changes uid but is still
579 * the same session */
581 fifo_fd = session_create_fifo(session);
585 path = session_bus_path(session);
589 return sd_bus_reply_method_return(
593 session->user->runtime_path,
595 (uint32_t) session->user->uid,
596 session->seat ? session->seat->id : "",
597 (uint32_t) session->vtnr,
601 audit_session_from_pid(leader, &audit_id);
603 /* Keep our session IDs and the audit session IDs in sync */
605 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
608 /* Wut? There's already a session by this name and we
609 * didn't find it above? Weird, then let's not trust
610 * the audit data and let's better register a new
612 if (hashmap_get(m->sessions, id)) {
613 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
626 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
629 } while (hashmap_get(m->sessions, id));
632 r = manager_add_user_by_uid(m, uid, &user);
636 r = manager_add_session(m, id, &session);
640 session_set_user(session, user);
642 session->leader = leader;
643 session->audit_id = audit_id;
646 session->remote = remote;
647 session->vtnr = vtnr;
650 session->tty = strdup(tty);
657 if (!isempty(display)) {
658 session->display = strdup(display);
659 if (!session->display) {
665 if (!isempty(remote_user)) {
666 session->remote_user = strdup(remote_user);
667 if (!session->remote_user) {
673 if (!isempty(remote_host)) {
674 session->remote_host = strdup(remote_host);
675 if (!session->remote_host) {
681 if (!isempty(service)) {
682 session->service = strdup(service);
683 if (!session->service) {
690 r = seat_attach_session(seat, session);
695 r = session_start(session);
699 session->create_message = sd_bus_message_ref(message);
701 /* Now, let's wait until the slice unit and stuff got
702 * created. We send the reply back from
703 * session_send_create_reply().*/
709 session_add_to_gc_queue(session);
712 user_add_to_gc_queue(user);
717 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
718 Manager *m = userdata;
727 r = sd_bus_message_read(message, "s", &name);
731 session = hashmap_get(m->sessions, name);
733 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
735 /* We use the FIFO to detect stray sessions where the process
736 invoking PAM dies abnormally. We need to make sure that
737 that process is not killed if at the clean end of the
738 session it closes the FIFO. Hence, with this call
739 explicitly turn off the FIFO logic, so that the PAM code
740 can finish clean up on its own */
741 session_remove_fifo(session);
742 session_save(session);
743 user_save(session->user);
745 return sd_bus_reply_method_return(message, NULL);
748 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
749 Manager *m = userdata;
758 r = sd_bus_message_read(message, "s", &name);
762 session = hashmap_get(m->sessions, name);
764 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
766 r = session_activate(session);
770 return sd_bus_reply_method_return(message, NULL);
773 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
774 const char *session_name, *seat_name;
775 Manager *m = userdata;
784 /* Same as ActivateSession() but refuses to work if
785 * the seat doesn't match */
787 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
791 session = hashmap_get(m->sessions, session_name);
793 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
795 seat = hashmap_get(m->seats, seat_name);
797 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
799 if (session->seat != seat)
800 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
802 r = session_activate(session);
806 return sd_bus_reply_method_return(message, NULL);
809 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
810 Manager *m = userdata;
819 r = sd_bus_message_read(message, "s", &name);
823 session = hashmap_get(m->sessions, name);
825 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
827 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
831 return sd_bus_reply_method_return(message, NULL);
834 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
835 Manager *m = userdata;
842 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
846 return sd_bus_reply_method_return(message, NULL);
849 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
850 const char *name, *swho;
851 Manager *m = userdata;
861 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
868 who = kill_who_from_string(swho);
870 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
873 if (signo <= 0 || signo >= _NSIG)
874 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
876 session = hashmap_get(m->sessions, name);
878 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
880 r = session_kill(session, who, signo);
884 return sd_bus_reply_method_return(message, NULL);
887 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
888 Manager *m = userdata;
898 r = sd_bus_message_read(message, "ui", &uid, &signo);
902 if (signo <= 0 || signo >= _NSIG)
903 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
905 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
907 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
909 r = user_kill(user, signo);
913 return sd_bus_reply_method_return(message, NULL);
916 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
917 Manager *m = userdata;
926 r = sd_bus_message_read(message, "s", &name);
930 session = hashmap_get(m->sessions, name);
932 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
934 r = session_stop(session);
938 return sd_bus_reply_method_return(message, NULL);
941 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
942 Manager *m = userdata;
951 r = sd_bus_message_read(message, "u", &uid);
955 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
957 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
963 return sd_bus_reply_method_return(message, NULL);
966 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
967 Manager *m = userdata;
976 r = sd_bus_message_read(message, "s", &name);
980 seat = hashmap_get(m->seats, name);
982 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
984 r = seat_stop_sessions(seat);
988 return sd_bus_reply_method_return(message, NULL);
991 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
992 _cleanup_free_ char *cc = NULL;
993 Manager *m = userdata;
1004 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1011 return errno ? -errno : -ENOENT;
1013 r = bus_verify_polkit_async(bus,
1014 &m->polkit_registry,
1016 "org.freedesktop.login1.set-user-linger",
1019 method_set_user_linger, m);
1023 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1025 mkdir_p_label("/var/lib/systemd", 0755);
1027 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1031 cc = cescape(pw->pw_name);
1035 path = strappenda("/var/lib/systemd/linger/", cc);
1043 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1050 if (r < 0 && errno != ENOENT)
1053 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1055 user_add_to_gc_queue(u);
1058 return sd_bus_reply_method_return(message, NULL);
1061 static int trigger_device(Manager *m, struct udev_device *d) {
1062 struct udev_enumerate *e;
1063 struct udev_list_entry *first, *item;
1068 e = udev_enumerate_new(m->udev);
1075 if (udev_enumerate_add_match_parent(e, d) < 0) {
1081 if (udev_enumerate_scan_devices(e) < 0) {
1086 first = udev_enumerate_get_list_entry(e);
1087 udev_list_entry_foreach(item, first) {
1088 _cleanup_free_ char *t = NULL;
1091 p = udev_list_entry_get_name(item);
1093 t = strappend(p, "/uevent");
1099 write_string_file(t, "change");
1106 udev_enumerate_unref(e);
1111 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1112 _cleanup_free_ char *rule = NULL, *file = NULL;
1113 const char *id_for_seat;
1114 struct udev_device *d;
1121 d = udev_device_new_from_syspath(m->udev, sysfs);
1125 if (!udev_device_has_tag(d, "seat")) {
1130 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) {
1141 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1146 mkdir_p_label("/etc/udev/rules.d", 0755);
1148 r = write_string_file_atomic_label(file, rule);
1152 r = trigger_device(m, d);
1156 udev_device_unref(d);
1161 static int flush_devices(Manager *m) {
1162 _cleanup_closedir_ DIR *d;
1166 d = opendir("/etc/udev/rules.d");
1168 if (errno != ENOENT)
1169 log_warning("Failed to open /etc/udev/rules.d: %m");
1173 while ((de = readdir(d))) {
1175 if (!dirent_is_file(de))
1178 if (!startswith(de->d_name, "72-seat-"))
1181 if (!endswith(de->d_name, ".rules"))
1184 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1185 log_warning("Failed to unlink %s: %m", de->d_name);
1189 return trigger_device(m, NULL);
1192 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1193 const char *sysfs, *seat;
1194 Manager *m = userdata;
1201 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1205 if (!path_startswith(sysfs, "/sys"))
1206 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1208 if (!seat_name_is_valid(seat))
1209 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1211 r = bus_verify_polkit_async(bus,
1212 &m->polkit_registry,
1214 "org.freedesktop.login1.attach-device",
1217 method_attach_device, m);
1221 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1223 r = attach_device(m, seat, sysfs);
1227 return sd_bus_reply_method_return(message, NULL);
1230 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1231 Manager *m = userdata;
1238 r = sd_bus_message_read(message, "b", &interactive);
1242 r = bus_verify_polkit_async(bus,
1243 &m->polkit_registry,
1245 "org.freedesktop.login1.flush-devices",
1248 method_flush_devices, m);
1252 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1254 r = flush_devices(m);
1258 return sd_bus_reply_method_return(message, NULL);
1261 static int have_multiple_sessions(
1270 /* Check for other users' sessions. Greeter sessions do not
1271 * count, and non-login sessions do not count either. */
1272 HASHMAP_FOREACH(session, m->sessions, i)
1273 if (session->class == SESSION_USER &&
1274 session->user->uid != uid)
1280 static int bus_manager_log_shutdown(
1283 const char *unit_name) {
1290 if (w != INHIBIT_SHUTDOWN)
1293 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1294 p = "MESSAGE=System is powering down.";
1295 q = "SHUTDOWN=power-off";
1296 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1297 p = "MESSAGE=System is halting.";
1298 q = "SHUTDOWN=halt";
1299 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1300 p = "MESSAGE=System is rebooting.";
1301 q = "SHUTDOWN=reboot";
1302 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1303 p = "MESSAGE=System is rebooting with kexec.";
1304 q = "SHUTDOWN=kexec";
1306 p = "MESSAGE=System is shutting down.";
1310 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1315 static int execute_shutdown_or_sleep(
1318 const char *unit_name,
1319 sd_bus_error *error) {
1321 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1328 assert(w < _INHIBIT_WHAT_MAX);
1331 bus_manager_log_shutdown(m, w, unit_name);
1333 r = sd_bus_call_method(
1335 "org.freedesktop.systemd1",
1336 "/org/freedesktop/systemd1",
1337 "org.freedesktop.systemd1.Manager",
1341 "ss", unit_name, "replace-irreversibly");
1345 r = sd_bus_message_read(reply, "o", &p);
1353 m->action_unit = unit_name;
1354 free(m->action_job);
1361 static int delay_shutdown_or_sleep(
1364 const char *unit_name) {
1368 assert(w < _INHIBIT_WHAT_MAX);
1371 m->action_timestamp = now(CLOCK_MONOTONIC);
1372 m->action_unit = unit_name;
1378 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1380 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1381 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1382 [INHIBIT_SLEEP] = "PrepareForSleep"
1385 int active = _active;
1389 assert(w < _INHIBIT_WHAT_MAX);
1390 assert(signal_name[w]);
1392 return sd_bus_emit_signal(m->bus,
1393 "/org/freedesktop/login1",
1394 "org.freedesktop.login1.Manager",
1400 int bus_manager_shutdown_or_sleep_now_or_later(
1402 const char *unit_name,
1404 sd_bus_error *error) {
1412 assert(w <= _INHIBIT_WHAT_MAX);
1413 assert(!m->action_job);
1415 /* Tell everybody to prepare for shutdown/sleep */
1416 send_prepare_for(m, w, true);
1419 m->inhibit_delay_max > 0 &&
1420 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1423 /* Shutdown is delayed, keep in mind what we
1424 * want to do, and start a timeout */
1425 r = delay_shutdown_or_sleep(m, w, unit_name);
1427 /* Shutdown is not delayed, execute it
1429 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1434 static int method_do_shutdown_or_sleep(
1436 sd_bus_message *message,
1437 const char *unit_name,
1440 const char *action_multiple_sessions,
1441 const char *action_ignore_inhibit,
1442 const char *sleep_verb,
1443 sd_bus_message_handler_t method,
1444 sd_bus_error *error) {
1446 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1447 bool multiple_sessions, blocked;
1455 assert(w <= _INHIBIT_WHAT_MAX);
1457 assert(action_multiple_sessions);
1458 assert(action_ignore_inhibit);
1461 r = sd_bus_message_read(message, "b", &interactive);
1465 /* Don't allow multiple jobs being executed at the same time */
1467 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1470 r = can_sleep(sleep_verb);
1475 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1478 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1482 r = sd_bus_creds_get_uid(creds, &uid);
1486 r = have_multiple_sessions(m, uid);
1490 multiple_sessions = r > 0;
1491 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1493 if (multiple_sessions) {
1494 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1495 action_multiple_sessions, interactive, error, method, m);
1501 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1502 action_ignore_inhibit, interactive, error, method, m);
1507 if (!multiple_sessions && !blocked) {
1508 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1509 action, interactive, error, method, m);
1514 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1518 return sd_bus_reply_method_return(message, NULL);
1521 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1522 Manager *m = userdata;
1524 return method_do_shutdown_or_sleep(
1526 SPECIAL_POWEROFF_TARGET,
1528 "org.freedesktop.login1.power-off",
1529 "org.freedesktop.login1.power-off-multiple-sessions",
1530 "org.freedesktop.login1.power-off-ignore-inhibit",
1536 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1537 Manager *m = userdata;
1539 return method_do_shutdown_or_sleep(
1541 SPECIAL_REBOOT_TARGET,
1543 "org.freedesktop.login1.reboot",
1544 "org.freedesktop.login1.reboot-multiple-sessions",
1545 "org.freedesktop.login1.reboot-ignore-inhibit",
1551 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1552 Manager *m = userdata;
1554 return method_do_shutdown_or_sleep(
1556 SPECIAL_SUSPEND_TARGET,
1558 "org.freedesktop.login1.suspend",
1559 "org.freedesktop.login1.suspend-multiple-sessions",
1560 "org.freedesktop.login1.suspend-ignore-inhibit",
1566 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1567 Manager *m = userdata;
1569 return method_do_shutdown_or_sleep(
1571 SPECIAL_HIBERNATE_TARGET,
1573 "org.freedesktop.login1.hibernate",
1574 "org.freedesktop.login1.hibernate-multiple-sessions",
1575 "org.freedesktop.login1.hibernate-ignore-inhibit",
1581 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1582 Manager *m = userdata;
1584 return method_do_shutdown_or_sleep(
1586 SPECIAL_HYBRID_SLEEP_TARGET,
1588 "org.freedesktop.login1.hibernate",
1589 "org.freedesktop.login1.hibernate-multiple-sessions",
1590 "org.freedesktop.login1.hibernate-ignore-inhibit",
1592 method_hybrid_sleep,
1596 static int method_can_shutdown_or_sleep(
1598 sd_bus_message *message,
1601 const char *action_multiple_sessions,
1602 const char *action_ignore_inhibit,
1603 const char *sleep_verb,
1604 sd_bus_error *error) {
1606 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1607 bool multiple_sessions, challenge, blocked;
1608 const char *result = NULL;
1615 assert(w <= _INHIBIT_WHAT_MAX);
1617 assert(action_multiple_sessions);
1618 assert(action_ignore_inhibit);
1621 r = can_sleep(sleep_verb);
1625 return sd_bus_reply_method_return(message, "s", "na");
1628 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1632 r = sd_bus_creds_get_uid(creds, &uid);
1636 r = have_multiple_sessions(m, uid);
1640 multiple_sessions = r > 0;
1641 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1643 if (multiple_sessions) {
1644 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1651 result = "challenge";
1657 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1661 if (r > 0 && !result)
1663 else if (challenge && (!result || streq(result, "yes")))
1664 result = "challenge";
1669 if (!multiple_sessions && !blocked) {
1670 /* If neither inhibit nor multiple sessions
1671 * apply then just check the normal policy */
1673 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1680 result = "challenge";
1685 return sd_bus_reply_method_return(message, "s", result);
1688 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1689 Manager *m = userdata;
1691 return method_can_shutdown_or_sleep(
1694 "org.freedesktop.login1.power-off",
1695 "org.freedesktop.login1.power-off-multiple-sessions",
1696 "org.freedesktop.login1.power-off-ignore-inhibit",
1701 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1702 Manager *m = userdata;
1704 return method_can_shutdown_or_sleep(
1707 "org.freedesktop.login1.reboot",
1708 "org.freedesktop.login1.reboot-multiple-sessions",
1709 "org.freedesktop.login1.reboot-ignore-inhibit",
1714 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1715 Manager *m = userdata;
1717 return method_can_shutdown_or_sleep(
1720 "org.freedesktop.login1.suspend",
1721 "org.freedesktop.login1.suspend-multiple-sessions",
1722 "org.freedesktop.login1.suspend-ignore-inhibit",
1727 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1728 Manager *m = userdata;
1730 return method_can_shutdown_or_sleep(
1733 "org.freedesktop.login1.hibernate",
1734 "org.freedesktop.login1.hibernate-multiple-sessions",
1735 "org.freedesktop.login1.hibernate-ignore-inhibit",
1740 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1741 Manager *m = userdata;
1743 return method_can_shutdown_or_sleep(
1746 "org.freedesktop.login1.hibernate",
1747 "org.freedesktop.login1.hibernate-multiple-sessions",
1748 "org.freedesktop.login1.hibernate-ignore-inhibit",
1753 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1754 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1755 const char *who, *why, *what, *mode;
1756 _cleanup_free_ char *id = NULL;
1757 _cleanup_close_ int fifo_fd = -1;
1758 Manager *m = userdata;
1759 Inhibitor *i = NULL;
1770 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1774 w = inhibit_what_from_string(what);
1776 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1778 mm = inhibit_mode_from_string(mode);
1780 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1782 /* Delay is only supported for shutdown/sleep */
1783 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1784 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1786 /* Don't allow taking delay locks while we are already
1787 * executing the operation. We shouldn't create the impression
1788 * that the lock was successful if the machine is about to go
1789 * down/suspend any moment. */
1790 if (m->action_what & w)
1791 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1793 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1794 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1795 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1796 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1797 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1798 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1799 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1800 "org.freedesktop.login1.inhibit-handle-lid-switch",
1801 false, error, method_inhibit, m);
1805 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1807 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1811 r = sd_bus_creds_get_uid(creds, &uid);
1815 r = sd_bus_creds_get_pid(creds, &pid);
1823 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1826 } while (hashmap_get(m->inhibitors, id));
1828 r = manager_add_inhibitor(m, id, &i);
1836 i->why = strdup(why);
1837 i->who = strdup(who);
1839 if (!i->why || !i->who) {
1844 fifo_fd = inhibitor_create_fifo(i);
1852 return sd_bus_reply_method_return(message, "h", fifo_fd);
1861 const sd_bus_vtable manager_vtable[] = {
1862 SD_BUS_VTABLE_START(0),
1864 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1865 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1866 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1867 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1868 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1869 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1870 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1871 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1872 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1873 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1874 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1875 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1876 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1877 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1878 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1879 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1880 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1881 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1883 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1884 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1885 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1887 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1888 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1889 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1890 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
1893 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1894 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1895 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1896 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1897 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1898 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1899 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1900 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1901 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1902 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1903 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1904 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1905 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1906 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1907 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1908 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1909 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1910 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1911 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1912 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1913 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1914 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1915 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1916 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1917 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1918 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1920 SD_BUS_SIGNAL("SessionNew", "so", 0),
1921 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1922 SD_BUS_SIGNAL("UserNew", "uo", 0),
1923 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1924 SD_BUS_SIGNAL("SeatNew", "so", 0),
1925 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1926 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1927 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1932 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1933 const char *path, *result, *unit;
1934 Manager *m = userdata;
1944 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1946 bus_log_parse_error(r);
1950 if (m->action_job && streq(m->action_job, path)) {
1951 log_info("Operation finished.");
1953 /* Tell people that they now may take a lock again */
1954 send_prepare_for(m, m->action_what, false);
1956 free(m->action_job);
1957 m->action_job = NULL;
1958 m->action_unit = NULL;
1963 session = hashmap_get(m->session_units, unit);
1966 if (streq_ptr(path, session->scope_job)) {
1967 free(session->scope_job);
1968 session->scope_job = NULL;
1971 if (session->started) {
1972 if (streq(result, "done"))
1973 session_send_create_reply(session, NULL);
1975 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1977 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1978 session_send_create_reply(session, &e);
1981 session_save(session);
1983 session_add_to_gc_queue(session);
1986 user = hashmap_get(m->user_units, unit);
1989 if (streq_ptr(path, user->service_job)) {
1990 free(user->service_job);
1991 user->service_job = NULL;
1994 if (streq_ptr(path, user->slice_job)) {
1995 free(user->slice_job);
1996 user->slice_job = NULL;
2000 user_add_to_gc_queue(user);
2006 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2007 const char *path, *unit;
2008 Manager *m = userdata;
2017 r = sd_bus_message_read(message, "so", &unit, &path);
2019 bus_log_parse_error(r);
2023 session = hashmap_get(m->session_units, unit);
2025 session_add_to_gc_queue(session);
2027 user = hashmap_get(m->user_units, unit);
2029 user_add_to_gc_queue(user);
2034 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2035 _cleanup_free_ char *unit = NULL;
2036 Manager *m = userdata;
2046 path = sd_bus_message_get_path(message);
2050 r = unit_name_from_dbus_path(path, &unit);
2054 session = hashmap_get(m->session_units, unit);
2056 session_add_to_gc_queue(session);
2058 user = hashmap_get(m->user_units, unit);
2060 user_add_to_gc_queue(user);
2065 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2066 Manager *m = userdata;
2073 r = sd_bus_message_read(message, "b", &b);
2075 bus_log_parse_error(r);
2082 /* systemd finished reloading, let's recheck all our sessions */
2083 log_debug("System manager has been reloaded, rechecking sessions...");
2085 HASHMAP_FOREACH(session, m->sessions, i)
2086 session_add_to_gc_queue(session);
2091 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2092 const char *name, *old, *new;
2093 Manager *m = userdata;
2101 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2103 bus_log_parse_error(r);
2107 if (isempty(old) || !isempty(new))
2110 key = set_remove(m->busnames, (char*) old);
2114 /* Drop all controllers owned by this name */
2118 HASHMAP_FOREACH(session, m->sessions, i)
2119 if (session_is_controller(session, old))
2120 session_drop_controller(session);
2125 int manager_send_changed(Manager *manager, const char *property, ...) {
2130 l = strv_from_stdarg_alloca(property);
2132 return sd_bus_emit_properties_changed_strv(
2134 "/org/freedesktop/login1",
2135 "org.freedesktop.login1.Manager",
2139 int manager_dispatch_delayed(Manager *manager) {
2140 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2141 Inhibitor *offending = NULL;
2146 if (manager->action_what == 0 || manager->action_job)
2149 /* Continue delay? */
2150 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2151 _cleanup_free_ char *comm = NULL, *u = NULL;
2153 get_process_comm(offending->pid, &comm);
2154 u = uid_to_name(offending->uid);
2156 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2159 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2160 (unsigned long) offending->uid, strna(u),
2161 (unsigned long) offending->pid, strna(comm));
2164 /* Actually do the operation */
2165 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2167 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2169 manager->action_unit = NULL;
2170 manager->action_what = 0;
2177 int manager_start_scope(
2182 const char *description,
2184 const char *kill_mode,
2185 sd_bus_error *error,
2188 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2195 r = sd_bus_message_new_method_call(
2197 "org.freedesktop.systemd1",
2198 "/org/freedesktop/systemd1",
2199 "org.freedesktop.systemd1.Manager",
2200 "StartTransientUnit",
2205 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2209 r = sd_bus_message_open_container(m, 'a', "(sv)");
2213 if (!isempty(slice)) {
2214 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2219 if (!isempty(description)) {
2220 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2225 if (!isempty(description)) {
2226 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2231 if (!isempty(kill_mode)) {
2232 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2237 /* cgroup empty notification is not available in containers
2238 * currently. To make this less problematic, let's shorten the
2239 * stop timeout for sessions, so that we don't wait
2242 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2246 /* Make sure that the session shells are terminated with
2247 * SIGHUP since bash and friends tend to ignore SIGTERM */
2248 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2252 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2256 r = sd_bus_message_close_container(m);
2260 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2264 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2272 r = sd_bus_message_read(reply, "o", &j);
2286 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2287 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2293 r = sd_bus_call_method(
2295 "org.freedesktop.systemd1",
2296 "/org/freedesktop/systemd1",
2297 "org.freedesktop.systemd1.Manager",
2301 "ss", unit, "fail");
2309 r = sd_bus_message_read(reply, "o", &j);
2323 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2324 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2330 r = sd_bus_call_method(
2332 "org.freedesktop.systemd1",
2333 "/org/freedesktop/systemd1",
2334 "org.freedesktop.systemd1.Manager",
2338 "ss", unit, "fail");
2340 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2341 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2346 sd_bus_error_free(error);
2357 r = sd_bus_message_read(reply, "o", &j);
2371 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2375 return sd_bus_call_method(
2377 "org.freedesktop.systemd1",
2378 "/org/freedesktop/systemd1",
2379 "org.freedesktop.systemd1.Manager",
2383 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2386 int manager_unit_is_active(Manager *manager, const char *unit) {
2387 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2388 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2389 _cleanup_free_ char *path = NULL;
2396 path = unit_dbus_path_from_name(unit);
2400 r = sd_bus_get_property(
2402 "org.freedesktop.systemd1",
2404 "org.freedesktop.systemd1.Unit",
2410 /* systemd might have droppped off momentarily, let's
2411 * not make this an error */
2412 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2413 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2416 /* If the unit is already unloaded then it's not
2418 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2419 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2425 r = sd_bus_message_read(reply, "s", &state);
2429 return !streq(state, "inactive") && !streq(state, "failed");
2432 int manager_job_is_active(Manager *manager, const char *path) {
2433 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2434 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2440 r = sd_bus_get_property(
2442 "org.freedesktop.systemd1",
2444 "org.freedesktop.systemd1.Job",
2450 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2451 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2454 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2460 /* We don't actually care about the state really. The fact
2461 * that we could read the job state is enough for us */