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/>.
28 #include "sd-messages.h"
31 #include "path-util.h"
33 #include "sleep-config.h"
34 #include "fileio-label.h"
37 #include "unit-name.h"
41 #include "bus-error.h"
43 #include "bus-errors.h"
45 static int property_get_idle_hint(
48 const char *interface,
50 sd_bus_message *reply,
52 sd_bus_error *error) {
54 Manager *m = userdata;
60 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
63 static int property_get_idle_since_hint(
66 const char *interface,
68 sd_bus_message *reply,
70 sd_bus_error *error) {
72 Manager *m = userdata;
79 manager_get_idle_hint(m, &t);
81 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
84 static int property_get_inhibited(
87 const char *interface,
89 sd_bus_message *reply,
91 sd_bus_error *error) {
93 Manager *m = userdata;
100 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
102 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
105 static int property_get_preparing(
108 const char *interface,
109 const char *property,
110 sd_bus_message *reply,
112 sd_bus_error *error) {
114 Manager *m = userdata;
121 if (streq(property, "PreparingForShutdown"))
122 b = !!(m->action_what & INHIBIT_SHUTDOWN);
124 b = !!(m->action_what & INHIBIT_SLEEP);
126 return sd_bus_message_append(reply, "b", b);
129 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
131 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
132 _cleanup_free_ char *p = NULL;
133 Manager *m = userdata;
142 r = sd_bus_message_read(message, "s", &name);
146 session = hashmap_get(m->sessions, name);
148 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
150 p = session_bus_path(session);
154 return sd_bus_reply_method_return(message, "o", p);
157 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
158 _cleanup_free_ char *p = NULL;
159 Session *session = NULL;
160 Manager *m = userdata;
168 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
170 r = sd_bus_message_read(message, "u", &pid);
175 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
180 r = manager_get_session_by_pid(m, pid, &session);
184 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
186 p = session_bus_path(session);
190 return sd_bus_reply_method_return(message, "o", p);
193 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
194 _cleanup_free_ char *p = NULL;
195 Manager *m = userdata;
204 r = sd_bus_message_read(message, "u", &uid);
208 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
210 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
212 p = user_bus_path(user);
216 return sd_bus_reply_method_return(message, "o", p);
219 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
220 _cleanup_free_ char *p = NULL;
221 Manager *m = userdata;
230 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
232 r = sd_bus_message_read(message, "u", &pid);
237 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
242 r = manager_get_user_by_pid(m, pid, &user);
246 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);
248 p = user_bus_path(user);
252 return sd_bus_reply_method_return(message, "o", p);
255 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
256 _cleanup_free_ char *p = NULL;
257 Manager *m = userdata;
266 r = sd_bus_message_read(message, "s", &name);
270 seat = hashmap_get(m->seats, name);
272 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
274 p = seat_bus_path(seat);
278 return sd_bus_reply_method_return(message, "o", p);
281 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
282 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
283 Manager *m = userdata;
292 r = sd_bus_message_new_method_return(message, &reply);
296 r = sd_bus_message_open_container(reply, 'a', "(susso)");
300 HASHMAP_FOREACH(session, m->sessions, i) {
301 _cleanup_free_ char *p = NULL;
303 p = session_bus_path(session);
307 r = sd_bus_message_append(reply, "(susso)",
309 (uint32_t) session->user->uid,
311 session->seat ? session->seat->id : "",
317 r = sd_bus_message_close_container(reply);
321 return sd_bus_send(bus, reply, NULL);
324 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
325 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
326 Manager *m = userdata;
335 r = sd_bus_message_new_method_return(message, &reply);
339 r = sd_bus_message_open_container(reply, 'a', "(uso)");
343 HASHMAP_FOREACH(user, m->users, i) {
344 _cleanup_free_ char *p = NULL;
346 p = user_bus_path(user);
350 r = sd_bus_message_append(reply, "(uso)",
351 (uint32_t) user->uid,
358 r = sd_bus_message_close_container(reply);
362 return sd_bus_send(bus, reply, NULL);
365 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
366 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
367 Manager *m = userdata;
376 r = sd_bus_message_new_method_return(message, &reply);
380 r = sd_bus_message_open_container(reply, 'a', "(so)");
384 HASHMAP_FOREACH(seat, m->seats, i) {
385 _cleanup_free_ char *p = NULL;
387 p = seat_bus_path(seat);
391 r = sd_bus_message_append(reply, "(so)", seat->id, p);
396 r = sd_bus_message_close_container(reply);
400 return sd_bus_send(bus, reply, NULL);
403 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
404 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
405 Manager *m = userdata;
406 Inhibitor *inhibitor;
410 r = sd_bus_message_new_method_return(message, &reply);
414 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
418 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
420 r = sd_bus_message_append(reply, "(ssssuu)",
421 strempty(inhibit_what_to_string(inhibitor->what)),
422 strempty(inhibitor->who),
423 strempty(inhibitor->why),
424 strempty(inhibit_mode_to_string(inhibitor->mode)),
425 (uint32_t) inhibitor->uid,
426 (uint32_t) inhibitor->pid);
431 r = sd_bus_message_close_container(reply);
435 return sd_bus_send(bus, reply, NULL);
438 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
439 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
440 uint32_t uid, leader, audit_id = 0;
441 _cleanup_free_ char *id = NULL;
442 Session *session = NULL;
443 Manager *m = userdata;
456 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
461 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
464 t = _SESSION_TYPE_INVALID;
466 t = session_type_from_string(type);
468 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
472 c = _SESSION_CLASS_INVALID;
474 c = session_class_from_string(class);
476 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
482 seat = hashmap_get(m->seats, cseat);
484 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
487 if (tty_is_vc(tty)) {
492 else if (seat != m->seat0)
493 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
495 v = vtnr_from_tty(tty);
497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
501 else if (vtnr != (uint32_t) v)
502 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
504 } else if (tty_is_console(tty)) {
508 else if (seat != m->seat0)
509 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
512 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
516 if (seat_has_vts(seat)) {
518 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
521 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
525 r = sd_bus_message_enter_container(message, 'a', "(sv)");
529 if (t == _SESSION_TYPE_INVALID) {
530 if (!isempty(display))
532 else if (!isempty(tty))
535 t = SESSION_UNSPECIFIED;
538 if (c == _SESSION_CLASS_INVALID) {
539 if (!isempty(display) || !isempty(tty))
542 c = SESSION_BACKGROUND;
546 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
548 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
553 manager_get_session_by_pid(m, leader, &session);
555 _cleanup_free_ char *path = NULL;
556 _cleanup_close_ int fifo_fd = -1;
558 /* Session already exists, client is probably
559 * something like "su" which changes uid but is still
560 * the same session */
562 fifo_fd = session_create_fifo(session);
566 path = session_bus_path(session);
570 return sd_bus_reply_method_return(
574 session->user->runtime_path,
576 (uint32_t) session->user->uid,
577 session->seat ? session->seat->id : "",
578 (uint32_t) session->vtnr,
582 audit_session_from_pid(leader, &audit_id);
584 /* Keep our session IDs and the audit session IDs in sync */
586 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
589 /* Wut? There's already a session by this name and we
590 * didn't find it above? Weird, then let's not trust
591 * the audit data and let's better register a new
593 if (hashmap_get(m->sessions, id)) {
594 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
607 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
610 } while (hashmap_get(m->sessions, id));
613 r = manager_add_user_by_uid(m, uid, &user);
617 r = manager_add_session(m, id, &session);
621 session_set_user(session, user);
623 session->leader = leader;
624 session->audit_id = audit_id;
627 session->remote = remote;
628 session->vtnr = vtnr;
631 session->tty = strdup(tty);
638 if (!isempty(display)) {
639 session->display = strdup(display);
640 if (!session->display) {
646 if (!isempty(remote_user)) {
647 session->remote_user = strdup(remote_user);
648 if (!session->remote_user) {
654 if (!isempty(remote_host)) {
655 session->remote_host = strdup(remote_host);
656 if (!session->remote_host) {
662 if (!isempty(service)) {
663 session->service = strdup(service);
664 if (!session->service) {
671 r = seat_attach_session(seat, session);
676 r = session_start(session);
680 session->create_message = sd_bus_message_ref(message);
682 /* Now, let's wait until the slice unit and stuff got
683 * created. We send the reply back from
684 * session_send_create_reply().*/
690 session_add_to_gc_queue(session);
693 user_add_to_gc_queue(user);
698 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
699 Manager *m = userdata;
708 r = sd_bus_message_read(message, "s", &name);
712 session = hashmap_get(m->sessions, name);
714 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
716 /* We use the FIFO to detect stray sessions where the process
717 invoking PAM dies abnormally. We need to make sure that
718 that process is not killed if at the clean end of the
719 session it closes the FIFO. Hence, with this call
720 explicitly turn off the FIFO logic, so that the PAM code
721 can finish clean up on its own */
722 session_remove_fifo(session);
723 session_save(session);
724 user_save(session->user);
726 return sd_bus_reply_method_return(message, NULL);
729 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
730 Manager *m = userdata;
739 r = sd_bus_message_read(message, "s", &name);
743 session = hashmap_get(m->sessions, name);
745 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
747 r = session_activate(session);
751 return sd_bus_reply_method_return(message, NULL);
754 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
755 const char *session_name, *seat_name;
756 Manager *m = userdata;
765 /* Same as ActivateSession() but refuses to work if
766 * the seat doesn't match */
768 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
772 session = hashmap_get(m->sessions, session_name);
774 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
776 seat = hashmap_get(m->seats, seat_name);
778 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
780 if (session->seat != seat)
781 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
783 r = session_activate(session);
787 return sd_bus_reply_method_return(message, NULL);
790 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
791 Manager *m = userdata;
800 r = sd_bus_message_read(message, "s", &name);
804 session = hashmap_get(m->sessions, name);
806 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
808 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
812 return sd_bus_reply_method_return(message, NULL);
815 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
816 Manager *m = userdata;
823 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
827 return sd_bus_reply_method_return(message, NULL);
830 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
831 const char *name, *swho;
832 Manager *m = userdata;
842 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
849 who = kill_who_from_string(swho);
851 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
854 if (signo <= 0 || signo >= _NSIG)
855 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
857 session = hashmap_get(m->sessions, name);
859 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
861 r = session_kill(session, who, signo);
865 return sd_bus_reply_method_return(message, NULL);
868 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
869 Manager *m = userdata;
879 r = sd_bus_message_read(message, "ui", &uid, &signo);
883 if (signo <= 0 || signo >= _NSIG)
884 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
886 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
888 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
890 r = user_kill(user, signo);
894 return sd_bus_reply_method_return(message, NULL);
897 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
898 Manager *m = userdata;
907 r = sd_bus_message_read(message, "s", &name);
911 session = hashmap_get(m->sessions, name);
913 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
915 r = session_stop(session);
919 return sd_bus_reply_method_return(message, NULL);
922 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
923 Manager *m = userdata;
932 r = sd_bus_message_read(message, "u", &uid);
936 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
938 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
944 return sd_bus_reply_method_return(message, NULL);
947 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
948 Manager *m = userdata;
957 r = sd_bus_message_read(message, "s", &name);
961 seat = hashmap_get(m->seats, name);
963 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
965 r = seat_stop_sessions(seat);
969 return sd_bus_reply_method_return(message, NULL);
972 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
973 _cleanup_free_ char *cc = NULL;
974 Manager *m = userdata;
985 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
992 return errno ? -errno : -ENOENT;
994 r = bus_verify_polkit_async(bus,
997 "org.freedesktop.login1.set-user-linger",
1000 method_set_user_linger, m);
1004 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1006 mkdir_p_label("/var/lib/systemd", 0755);
1008 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1012 cc = cescape(pw->pw_name);
1016 path = strappenda("/var/lib/systemd/linger/", cc);
1024 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1031 if (r < 0 && errno != ENOENT)
1034 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1036 user_add_to_gc_queue(u);
1039 return sd_bus_reply_method_return(message, NULL);
1042 static int trigger_device(Manager *m, struct udev_device *d) {
1043 struct udev_enumerate *e;
1044 struct udev_list_entry *first, *item;
1049 e = udev_enumerate_new(m->udev);
1056 if (udev_enumerate_add_match_parent(e, d) < 0) {
1062 if (udev_enumerate_scan_devices(e) < 0) {
1067 first = udev_enumerate_get_list_entry(e);
1068 udev_list_entry_foreach(item, first) {
1069 _cleanup_free_ char *t = NULL;
1072 p = udev_list_entry_get_name(item);
1074 t = strappend(p, "/uevent");
1080 write_string_file(t, "change");
1087 udev_enumerate_unref(e);
1092 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1093 _cleanup_free_ char *rule = NULL, *file = NULL;
1094 const char *id_for_seat;
1095 struct udev_device *d;
1102 d = udev_device_new_from_syspath(m->udev, sysfs);
1106 if (!udev_device_has_tag(d, "seat")) {
1111 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1117 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
1122 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1127 mkdir_p_label("/etc/udev/rules.d", 0755);
1129 r = write_string_file_atomic_label(file, rule);
1133 r = trigger_device(m, d);
1137 udev_device_unref(d);
1142 static int flush_devices(Manager *m) {
1143 _cleanup_closedir_ DIR *d;
1147 d = opendir("/etc/udev/rules.d");
1149 if (errno != ENOENT)
1150 log_warning("Failed to open /etc/udev/rules.d: %m");
1154 while ((de = readdir(d))) {
1156 if (!dirent_is_file(de))
1159 if (!startswith(de->d_name, "72-seat-"))
1162 if (!endswith(de->d_name, ".rules"))
1165 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1166 log_warning("Failed to unlink %s: %m", de->d_name);
1170 return trigger_device(m, NULL);
1173 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1174 const char *sysfs, *seat;
1175 Manager *m = userdata;
1182 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1186 if (!path_startswith(sysfs, "/sys"))
1187 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1189 if (!seat_name_is_valid(seat))
1190 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1192 r = bus_verify_polkit_async(bus,
1193 &m->polkit_registry,
1195 "org.freedesktop.login1.attach-device",
1198 method_attach_device, m);
1202 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1204 r = attach_device(m, seat, sysfs);
1208 return sd_bus_reply_method_return(message, NULL);
1211 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1212 Manager *m = userdata;
1219 r = sd_bus_message_read(message, "b", &interactive);
1223 r = bus_verify_polkit_async(bus,
1224 &m->polkit_registry,
1226 "org.freedesktop.login1.flush-devices",
1229 method_flush_devices, m);
1233 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1235 r = flush_devices(m);
1239 return sd_bus_reply_method_return(message, NULL);
1242 static int have_multiple_sessions(
1251 /* Check for other users' sessions. Greeter sessions do not
1252 * count, and non-login sessions do not count either. */
1253 HASHMAP_FOREACH(session, m->sessions, i)
1254 if (session->class == SESSION_USER &&
1255 !session->closing &&
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 bool multiple_sessions, blocked;
1436 assert(w <= _INHIBIT_WHAT_MAX);
1438 assert(action_multiple_sessions);
1439 assert(action_ignore_inhibit);
1442 r = sd_bus_message_read(message, "b", &interactive);
1446 /* Don't allow multiple jobs being executed at the same time */
1448 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1451 r = can_sleep(sleep_verb);
1456 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1459 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1463 r = have_multiple_sessions(m, uid);
1467 multiple_sessions = r > 0;
1468 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1470 if (multiple_sessions) {
1471 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1472 action_multiple_sessions, interactive, error, method, m);
1478 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1479 action_ignore_inhibit, interactive, error, method, m);
1484 if (!multiple_sessions && !blocked) {
1485 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1486 action, interactive, error, method, m);
1491 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1495 return sd_bus_reply_method_return(message, NULL);
1498 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1499 Manager *m = userdata;
1501 return method_do_shutdown_or_sleep(
1503 SPECIAL_POWEROFF_TARGET,
1505 "org.freedesktop.login1.power-off",
1506 "org.freedesktop.login1.power-off-multiple-sessions",
1507 "org.freedesktop.login1.power-off-ignore-inhibit",
1513 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1514 Manager *m = userdata;
1516 return method_do_shutdown_or_sleep(
1518 SPECIAL_REBOOT_TARGET,
1520 "org.freedesktop.login1.reboot",
1521 "org.freedesktop.login1.reboot-multiple-sessions",
1522 "org.freedesktop.login1.reboot-ignore-inhibit",
1528 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1529 Manager *m = userdata;
1531 return method_do_shutdown_or_sleep(
1533 SPECIAL_SUSPEND_TARGET,
1535 "org.freedesktop.login1.suspend",
1536 "org.freedesktop.login1.suspend-multiple-sessions",
1537 "org.freedesktop.login1.suspend-ignore-inhibit",
1543 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1544 Manager *m = userdata;
1546 return method_do_shutdown_or_sleep(
1548 SPECIAL_HIBERNATE_TARGET,
1550 "org.freedesktop.login1.hibernate",
1551 "org.freedesktop.login1.hibernate-multiple-sessions",
1552 "org.freedesktop.login1.hibernate-ignore-inhibit",
1558 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1559 Manager *m = userdata;
1561 return method_do_shutdown_or_sleep(
1563 SPECIAL_HYBRID_SLEEP_TARGET,
1565 "org.freedesktop.login1.hibernate",
1566 "org.freedesktop.login1.hibernate-multiple-sessions",
1567 "org.freedesktop.login1.hibernate-ignore-inhibit",
1569 method_hybrid_sleep,
1573 static int method_can_shutdown_or_sleep(
1575 sd_bus_message *message,
1578 const char *action_multiple_sessions,
1579 const char *action_ignore_inhibit,
1580 const char *sleep_verb,
1581 sd_bus_error *error) {
1583 bool multiple_sessions, challenge, blocked;
1584 const char *result = NULL;
1591 assert(w <= _INHIBIT_WHAT_MAX);
1593 assert(action_multiple_sessions);
1594 assert(action_ignore_inhibit);
1597 r = can_sleep(sleep_verb);
1601 return sd_bus_reply_method_return(message, "s", "na");
1604 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1608 r = have_multiple_sessions(m, uid);
1612 multiple_sessions = r > 0;
1613 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1615 if (multiple_sessions) {
1616 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1623 result = "challenge";
1629 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1633 if (r > 0 && !result)
1635 else if (challenge && (!result || streq(result, "yes")))
1636 result = "challenge";
1641 if (!multiple_sessions && !blocked) {
1642 /* If neither inhibit nor multiple sessions
1643 * apply then just check the normal policy */
1645 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1652 result = "challenge";
1657 return sd_bus_reply_method_return(message, "s", result);
1660 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1661 Manager *m = userdata;
1663 return method_can_shutdown_or_sleep(
1666 "org.freedesktop.login1.power-off",
1667 "org.freedesktop.login1.power-off-multiple-sessions",
1668 "org.freedesktop.login1.power-off-ignore-inhibit",
1673 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1674 Manager *m = userdata;
1676 return method_can_shutdown_or_sleep(
1679 "org.freedesktop.login1.reboot",
1680 "org.freedesktop.login1.reboot-multiple-sessions",
1681 "org.freedesktop.login1.reboot-ignore-inhibit",
1686 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1687 Manager *m = userdata;
1689 return method_can_shutdown_or_sleep(
1692 "org.freedesktop.login1.suspend",
1693 "org.freedesktop.login1.suspend-multiple-sessions",
1694 "org.freedesktop.login1.suspend-ignore-inhibit",
1699 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1700 Manager *m = userdata;
1702 return method_can_shutdown_or_sleep(
1705 "org.freedesktop.login1.hibernate",
1706 "org.freedesktop.login1.hibernate-multiple-sessions",
1707 "org.freedesktop.login1.hibernate-ignore-inhibit",
1712 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1713 Manager *m = userdata;
1715 return method_can_shutdown_or_sleep(
1718 "org.freedesktop.login1.hibernate",
1719 "org.freedesktop.login1.hibernate-multiple-sessions",
1720 "org.freedesktop.login1.hibernate-ignore-inhibit",
1725 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1726 const char *who, *why, *what, *mode;
1727 _cleanup_free_ char *id = NULL;
1728 _cleanup_close_ int fifo_fd = -1;
1729 Manager *m = userdata;
1730 Inhibitor *i = NULL;
1741 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1745 w = inhibit_what_from_string(what);
1747 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1749 mm = inhibit_mode_from_string(mode);
1751 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1753 /* Delay is only supported for shutdown/sleep */
1754 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1755 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1757 /* Don't allow taking delay locks while we are already
1758 * executing the operation. We shouldn't create the impression
1759 * that the lock was successful if the machine is about to go
1760 * down/suspend any moment. */
1761 if (m->action_what & w)
1762 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1764 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1765 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1766 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1767 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1768 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1769 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1770 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1771 "org.freedesktop.login1.inhibit-handle-lid-switch",
1772 false, error, method_inhibit, m);
1776 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1778 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1782 r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
1790 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1793 } while (hashmap_get(m->inhibitors, id));
1795 r = manager_add_inhibitor(m, id, &i);
1803 i->why = strdup(why);
1804 i->who = strdup(who);
1806 if (!i->why || !i->who) {
1811 fifo_fd = inhibitor_create_fifo(i);
1819 return sd_bus_reply_method_return(message, "h", fifo_fd);
1828 const sd_bus_vtable manager_vtable[] = {
1829 SD_BUS_VTABLE_START(0),
1831 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1832 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1833 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1834 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1835 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1836 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1837 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1838 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1839 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1840 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1841 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1842 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1843 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1844 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1845 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1846 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1847 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1848 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1850 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1851 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1852 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1853 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1854 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1855 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1856 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1857 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1858 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1859 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
1860 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1861 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1862 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1863 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1864 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1865 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1866 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1867 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1868 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1869 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1870 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1871 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1872 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1873 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1874 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1875 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1876 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1877 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1878 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1879 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1880 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1881 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1882 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1883 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1884 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1885 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1887 SD_BUS_SIGNAL("SessionNew", "so", 0),
1888 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1889 SD_BUS_SIGNAL("UserNew", "uo", 0),
1890 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1891 SD_BUS_SIGNAL("SeatNew", "so", 0),
1892 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1893 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1894 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1899 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1900 const char *path, *result, *unit;
1901 Manager *m = userdata;
1911 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1913 bus_log_parse_error(r);
1917 if (m->action_job && streq(m->action_job, path)) {
1918 log_info("Operation finished.");
1920 /* Tell people that they now may take a lock again */
1921 send_prepare_for(m, m->action_what, false);
1923 free(m->action_job);
1924 m->action_job = NULL;
1925 m->action_unit = NULL;
1930 session = hashmap_get(m->session_units, unit);
1933 if (streq_ptr(path, session->scope_job)) {
1934 free(session->scope_job);
1935 session->scope_job = NULL;
1938 if (session->started) {
1939 if (streq(result, "done"))
1940 session_send_create_reply(session, NULL);
1942 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1944 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1945 session_send_create_reply(session, &e);
1948 session_save(session);
1950 session_add_to_gc_queue(session);
1953 user = hashmap_get(m->user_units, unit);
1956 if (streq_ptr(path, user->service_job)) {
1957 free(user->service_job);
1958 user->service_job = NULL;
1961 if (streq_ptr(path, user->slice_job)) {
1962 free(user->slice_job);
1963 user->slice_job = NULL;
1967 user_add_to_gc_queue(user);
1973 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1974 const char *path, *unit;
1975 Manager *m = userdata;
1984 r = sd_bus_message_read(message, "so", &unit, &path);
1986 bus_log_parse_error(r);
1990 session = hashmap_get(m->session_units, unit);
1992 session_add_to_gc_queue(session);
1994 user = hashmap_get(m->user_units, unit);
1996 user_add_to_gc_queue(user);
2001 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2002 _cleanup_free_ char *unit = NULL;
2003 Manager *m = userdata;
2013 path = sd_bus_message_get_path(message);
2017 r = unit_name_from_dbus_path(path, &unit);
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_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2033 Manager *m = userdata;
2040 r = sd_bus_message_read(message, "b", &b);
2042 bus_log_parse_error(r);
2049 /* systemd finished reloading, let's recheck all our sessions */
2050 log_debug("System manager has been reloaded, rechecking sessions...");
2052 HASHMAP_FOREACH(session, m->sessions, i)
2053 session_add_to_gc_queue(session);
2058 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2059 const char *name, *old, *new;
2060 Manager *m = userdata;
2068 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2070 bus_log_parse_error(r);
2074 if (isempty(old) || !isempty(new))
2077 key = set_remove(m->busnames, (char*) old);
2081 /* Drop all controllers owned by this name */
2085 HASHMAP_FOREACH(session, m->sessions, i)
2086 if (session_is_controller(session, old))
2087 session_drop_controller(session);
2092 int manager_send_changed(Manager *manager, const char *property, ...) {
2097 l = strv_from_stdarg_alloca(property);
2099 return sd_bus_emit_properties_changed_strv(
2101 "/org/freedesktop/login1",
2102 "org.freedesktop.login1.Manager",
2106 int manager_dispatch_delayed(Manager *manager) {
2107 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2108 Inhibitor *offending = NULL;
2113 if (manager->action_what == 0 || manager->action_job)
2116 /* Continue delay? */
2117 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2118 _cleanup_free_ char *comm = NULL, *u = NULL;
2120 get_process_comm(offending->pid, &comm);
2121 u = uid_to_name(offending->uid);
2123 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2126 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2127 (unsigned long) offending->uid, strna(u),
2128 (unsigned long) offending->pid, strna(comm));
2131 /* Actually do the operation */
2132 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2134 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2136 manager->action_unit = NULL;
2137 manager->action_what = 0;
2144 int manager_start_scope(
2149 const char *description,
2151 const char *kill_mode,
2152 sd_bus_error *error,
2155 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2162 r = sd_bus_message_new_method_call(
2164 "org.freedesktop.systemd1",
2165 "/org/freedesktop/systemd1",
2166 "org.freedesktop.systemd1.Manager",
2167 "StartTransientUnit",
2172 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2176 r = sd_bus_message_open_container(m, 'a', "(sv)");
2180 if (!isempty(slice)) {
2181 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2186 if (!isempty(description)) {
2187 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2192 if (!isempty(description)) {
2193 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2198 if (!isempty(kill_mode)) {
2199 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2204 /* cgroup empty notification is not available in containers
2205 * currently. To make this less problematic, let's shorten the
2206 * stop timeout for sessions, so that we don't wait
2209 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2213 /* Make sure that the session shells are terminated with
2214 * SIGHUP since bash and friends tend to ignore SIGTERM */
2215 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2219 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2223 r = sd_bus_message_close_container(m);
2227 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2231 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2239 r = sd_bus_message_read(reply, "o", &j);
2253 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2254 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2260 r = sd_bus_call_method(
2262 "org.freedesktop.systemd1",
2263 "/org/freedesktop/systemd1",
2264 "org.freedesktop.systemd1.Manager",
2268 "ss", unit, "fail");
2276 r = sd_bus_message_read(reply, "o", &j);
2290 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2291 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2297 r = sd_bus_call_method(
2299 "org.freedesktop.systemd1",
2300 "/org/freedesktop/systemd1",
2301 "org.freedesktop.systemd1.Manager",
2305 "ss", unit, "fail");
2307 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2308 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2313 sd_bus_error_free(error);
2324 r = sd_bus_message_read(reply, "o", &j);
2338 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2342 return sd_bus_call_method(
2344 "org.freedesktop.systemd1",
2345 "/org/freedesktop/systemd1",
2346 "org.freedesktop.systemd1.Manager",
2350 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2353 int manager_unit_is_active(Manager *manager, const char *unit) {
2354 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2355 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2356 _cleanup_free_ char *path = NULL;
2363 path = unit_dbus_path_from_name(unit);
2367 r = sd_bus_get_property(
2369 "org.freedesktop.systemd1",
2371 "org.freedesktop.systemd1.Unit",
2377 /* systemd might have droppped off momentarily, let's
2378 * not make this an error */
2379 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2380 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2383 /* If the unit is already unloaded then it's not
2385 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2386 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2392 r = sd_bus_message_read(reply, "s", &state);
2396 return !streq(state, "inactive") && !streq(state, "failed");
2399 int manager_job_is_active(Manager *manager, const char *path) {
2400 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2401 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2407 r = sd_bus_get_property(
2409 "org.freedesktop.systemd1",
2411 "org.freedesktop.systemd1.Job",
2417 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2418 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2421 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2427 /* We don't actually care about the state really. The fact
2428 * that we could read the job state is enough for us */