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)) {
517 if (!vtnr || vtnr > 63)
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->user->uid != uid)
1261 static int bus_manager_log_shutdown(
1264 const char *unit_name) {
1271 if (w != INHIBIT_SHUTDOWN)
1274 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1275 p = "MESSAGE=System is powering down.";
1276 q = "SHUTDOWN=power-off";
1277 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1278 p = "MESSAGE=System is halting.";
1279 q = "SHUTDOWN=halt";
1280 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1281 p = "MESSAGE=System is rebooting.";
1282 q = "SHUTDOWN=reboot";
1283 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1284 p = "MESSAGE=System is rebooting with kexec.";
1285 q = "SHUTDOWN=kexec";
1287 p = "MESSAGE=System is shutting down.";
1291 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1296 static int execute_shutdown_or_sleep(
1299 const char *unit_name,
1300 sd_bus_error *error) {
1302 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1309 assert(w < _INHIBIT_WHAT_MAX);
1312 bus_manager_log_shutdown(m, w, unit_name);
1314 r = sd_bus_call_method(
1316 "org.freedesktop.systemd1",
1317 "/org/freedesktop/systemd1",
1318 "org.freedesktop.systemd1.Manager",
1322 "ss", unit_name, "replace-irreversibly");
1326 r = sd_bus_message_read(reply, "o", &p);
1334 m->action_unit = unit_name;
1335 free(m->action_job);
1342 static int delay_shutdown_or_sleep(
1345 const char *unit_name) {
1349 assert(w < _INHIBIT_WHAT_MAX);
1352 m->action_timestamp = now(CLOCK_MONOTONIC);
1353 m->action_unit = unit_name;
1359 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1361 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1362 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1363 [INHIBIT_SLEEP] = "PrepareForSleep"
1366 int active = _active;
1370 assert(w < _INHIBIT_WHAT_MAX);
1371 assert(signal_name[w]);
1373 return sd_bus_emit_signal(m->bus,
1374 "/org/freedesktop/login1",
1375 "org.freedesktop.login1.Manager",
1381 int bus_manager_shutdown_or_sleep_now_or_later(
1383 const char *unit_name,
1385 sd_bus_error *error) {
1393 assert(w <= _INHIBIT_WHAT_MAX);
1394 assert(!m->action_job);
1396 /* Tell everybody to prepare for shutdown/sleep */
1397 send_prepare_for(m, w, true);
1400 m->inhibit_delay_max > 0 &&
1401 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1404 /* Shutdown is delayed, keep in mind what we
1405 * want to do, and start a timeout */
1406 r = delay_shutdown_or_sleep(m, w, unit_name);
1408 /* Shutdown is not delayed, execute it
1410 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1415 static int method_do_shutdown_or_sleep(
1417 sd_bus_message *message,
1418 const char *unit_name,
1421 const char *action_multiple_sessions,
1422 const char *action_ignore_inhibit,
1423 const char *sleep_verb,
1424 sd_bus_message_handler_t method,
1425 sd_bus_error *error) {
1427 bool multiple_sessions, blocked;
1435 assert(w <= _INHIBIT_WHAT_MAX);
1437 assert(action_multiple_sessions);
1438 assert(action_ignore_inhibit);
1441 r = sd_bus_message_read(message, "b", &interactive);
1445 /* Don't allow multiple jobs being executed at the same time */
1447 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1450 r = can_sleep(sleep_verb);
1455 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1458 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1462 r = have_multiple_sessions(m, uid);
1466 multiple_sessions = r > 0;
1467 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1469 if (multiple_sessions) {
1470 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1471 action_multiple_sessions, interactive, error, method, m);
1477 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1478 action_ignore_inhibit, interactive, error, method, m);
1483 if (!multiple_sessions && !blocked) {
1484 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1485 action, interactive, error, method, m);
1490 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1494 return sd_bus_reply_method_return(message, NULL);
1497 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1498 Manager *m = userdata;
1500 return method_do_shutdown_or_sleep(
1502 SPECIAL_POWEROFF_TARGET,
1504 "org.freedesktop.login1.power-off",
1505 "org.freedesktop.login1.power-off-multiple-sessions",
1506 "org.freedesktop.login1.power-off-ignore-inhibit",
1512 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1513 Manager *m = userdata;
1515 return method_do_shutdown_or_sleep(
1517 SPECIAL_REBOOT_TARGET,
1519 "org.freedesktop.login1.reboot",
1520 "org.freedesktop.login1.reboot-multiple-sessions",
1521 "org.freedesktop.login1.reboot-ignore-inhibit",
1527 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1528 Manager *m = userdata;
1530 return method_do_shutdown_or_sleep(
1532 SPECIAL_SUSPEND_TARGET,
1534 "org.freedesktop.login1.suspend",
1535 "org.freedesktop.login1.suspend-multiple-sessions",
1536 "org.freedesktop.login1.suspend-ignore-inhibit",
1542 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1543 Manager *m = userdata;
1545 return method_do_shutdown_or_sleep(
1547 SPECIAL_HIBERNATE_TARGET,
1549 "org.freedesktop.login1.hibernate",
1550 "org.freedesktop.login1.hibernate-multiple-sessions",
1551 "org.freedesktop.login1.hibernate-ignore-inhibit",
1557 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1558 Manager *m = userdata;
1560 return method_do_shutdown_or_sleep(
1562 SPECIAL_HYBRID_SLEEP_TARGET,
1564 "org.freedesktop.login1.hibernate",
1565 "org.freedesktop.login1.hibernate-multiple-sessions",
1566 "org.freedesktop.login1.hibernate-ignore-inhibit",
1568 method_hybrid_sleep,
1572 static int method_can_shutdown_or_sleep(
1574 sd_bus_message *message,
1577 const char *action_multiple_sessions,
1578 const char *action_ignore_inhibit,
1579 const char *sleep_verb,
1580 sd_bus_error *error) {
1582 bool multiple_sessions, challenge, blocked;
1583 const char *result = NULL;
1590 assert(w <= _INHIBIT_WHAT_MAX);
1592 assert(action_multiple_sessions);
1593 assert(action_ignore_inhibit);
1596 r = can_sleep(sleep_verb);
1600 return sd_bus_reply_method_return(message, "s", "na");
1603 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1607 r = have_multiple_sessions(m, uid);
1611 multiple_sessions = r > 0;
1612 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1614 if (multiple_sessions) {
1615 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1622 result = "challenge";
1628 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1632 if (r > 0 && !result)
1634 else if (challenge && (!result || streq(result, "yes")))
1635 result = "challenge";
1640 if (!multiple_sessions && !blocked) {
1641 /* If neither inhibit nor multiple sessions
1642 * apply then just check the normal policy */
1644 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1651 result = "challenge";
1656 return sd_bus_reply_method_return(message, "s", result);
1659 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1660 Manager *m = userdata;
1662 return method_can_shutdown_or_sleep(
1665 "org.freedesktop.login1.power-off",
1666 "org.freedesktop.login1.power-off-multiple-sessions",
1667 "org.freedesktop.login1.power-off-ignore-inhibit",
1672 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1673 Manager *m = userdata;
1675 return method_can_shutdown_or_sleep(
1678 "org.freedesktop.login1.reboot",
1679 "org.freedesktop.login1.reboot-multiple-sessions",
1680 "org.freedesktop.login1.reboot-ignore-inhibit",
1685 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1686 Manager *m = userdata;
1688 return method_can_shutdown_or_sleep(
1691 "org.freedesktop.login1.suspend",
1692 "org.freedesktop.login1.suspend-multiple-sessions",
1693 "org.freedesktop.login1.suspend-ignore-inhibit",
1698 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1699 Manager *m = userdata;
1701 return method_can_shutdown_or_sleep(
1704 "org.freedesktop.login1.hibernate",
1705 "org.freedesktop.login1.hibernate-multiple-sessions",
1706 "org.freedesktop.login1.hibernate-ignore-inhibit",
1711 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1712 Manager *m = userdata;
1714 return method_can_shutdown_or_sleep(
1717 "org.freedesktop.login1.hibernate",
1718 "org.freedesktop.login1.hibernate-multiple-sessions",
1719 "org.freedesktop.login1.hibernate-ignore-inhibit",
1724 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1725 const char *who, *why, *what, *mode;
1726 _cleanup_free_ char *id = NULL;
1727 _cleanup_close_ int fifo_fd = -1;
1728 Manager *m = userdata;
1729 Inhibitor *i = NULL;
1740 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1744 w = inhibit_what_from_string(what);
1746 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1748 mm = inhibit_mode_from_string(mode);
1750 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1752 /* Delay is only supported for shutdown/sleep */
1753 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1754 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1756 /* Don't allow taking delay locks while we are already
1757 * executing the operation. We shouldn't create the impression
1758 * that the lock was successful if the machine is about to go
1759 * down/suspend any moment. */
1760 if (m->action_what & w)
1761 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1763 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1764 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1765 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1766 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1767 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1768 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1769 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1770 "org.freedesktop.login1.inhibit-handle-lid-switch",
1771 false, error, method_inhibit, m);
1775 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1777 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1781 r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
1789 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1792 } while (hashmap_get(m->inhibitors, id));
1794 r = manager_add_inhibitor(m, id, &i);
1802 i->why = strdup(why);
1803 i->who = strdup(who);
1805 if (!i->why || !i->who) {
1810 fifo_fd = inhibitor_create_fifo(i);
1818 return sd_bus_reply_method_return(message, "h", fifo_fd);
1827 const sd_bus_vtable manager_vtable[] = {
1828 SD_BUS_VTABLE_START(0),
1830 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1831 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1832 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1833 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1834 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1835 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1836 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1837 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1838 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1839 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1840 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1841 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1842 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1843 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1844 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1845 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1846 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1847 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1849 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1850 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1851 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1852 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1853 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1854 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1855 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1856 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1857 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1858 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
1859 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1860 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1861 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1862 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1863 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1864 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1865 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1866 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1867 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1868 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1869 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1870 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1871 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1872 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1873 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1874 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1875 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1876 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1877 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1878 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1879 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1880 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1881 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1882 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1883 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1884 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1886 SD_BUS_SIGNAL("SessionNew", "so", 0),
1887 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1888 SD_BUS_SIGNAL("UserNew", "uo", 0),
1889 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1890 SD_BUS_SIGNAL("SeatNew", "so", 0),
1891 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1892 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1893 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1898 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1899 const char *path, *result, *unit;
1900 Manager *m = userdata;
1910 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1912 bus_log_parse_error(r);
1916 if (m->action_job && streq(m->action_job, path)) {
1917 log_info("Operation finished.");
1919 /* Tell people that they now may take a lock again */
1920 send_prepare_for(m, m->action_what, false);
1922 free(m->action_job);
1923 m->action_job = NULL;
1924 m->action_unit = NULL;
1929 session = hashmap_get(m->session_units, unit);
1932 if (streq_ptr(path, session->scope_job)) {
1933 free(session->scope_job);
1934 session->scope_job = NULL;
1937 if (session->started) {
1938 if (streq(result, "done"))
1939 session_send_create_reply(session, NULL);
1941 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1943 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1944 session_send_create_reply(session, &e);
1947 session_save(session);
1949 session_add_to_gc_queue(session);
1952 user = hashmap_get(m->user_units, unit);
1955 if (streq_ptr(path, user->service_job)) {
1956 free(user->service_job);
1957 user->service_job = NULL;
1960 if (streq_ptr(path, user->slice_job)) {
1961 free(user->slice_job);
1962 user->slice_job = NULL;
1966 user_add_to_gc_queue(user);
1972 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1973 const char *path, *unit;
1974 Manager *m = userdata;
1983 r = sd_bus_message_read(message, "so", &unit, &path);
1985 bus_log_parse_error(r);
1989 session = hashmap_get(m->session_units, unit);
1991 session_add_to_gc_queue(session);
1993 user = hashmap_get(m->user_units, unit);
1995 user_add_to_gc_queue(user);
2000 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2001 _cleanup_free_ char *unit = NULL;
2002 Manager *m = userdata;
2012 path = sd_bus_message_get_path(message);
2016 r = unit_name_from_dbus_path(path, &unit);
2020 session = hashmap_get(m->session_units, unit);
2022 session_add_to_gc_queue(session);
2024 user = hashmap_get(m->user_units, unit);
2026 user_add_to_gc_queue(user);
2031 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2032 Manager *m = userdata;
2039 r = sd_bus_message_read(message, "b", &b);
2041 bus_log_parse_error(r);
2048 /* systemd finished reloading, let's recheck all our sessions */
2049 log_debug("System manager has been reloaded, rechecking sessions...");
2051 HASHMAP_FOREACH(session, m->sessions, i)
2052 session_add_to_gc_queue(session);
2057 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2058 const char *name, *old, *new;
2059 Manager *m = userdata;
2067 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2069 bus_log_parse_error(r);
2073 if (isempty(old) || !isempty(new))
2076 key = set_remove(m->busnames, (char*) old);
2080 /* Drop all controllers owned by this name */
2084 HASHMAP_FOREACH(session, m->sessions, i)
2085 if (session_is_controller(session, old))
2086 session_drop_controller(session);
2091 int manager_send_changed(Manager *manager, const char *property, ...) {
2096 l = strv_from_stdarg_alloca(property);
2098 return sd_bus_emit_properties_changed_strv(
2100 "/org/freedesktop/login1",
2101 "org.freedesktop.login1.Manager",
2105 int manager_dispatch_delayed(Manager *manager) {
2106 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2107 Inhibitor *offending = NULL;
2112 if (manager->action_what == 0 || manager->action_job)
2115 /* Continue delay? */
2116 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2117 _cleanup_free_ char *comm = NULL, *u = NULL;
2119 get_process_comm(offending->pid, &comm);
2120 u = uid_to_name(offending->uid);
2122 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2125 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2126 (unsigned long) offending->uid, strna(u),
2127 (unsigned long) offending->pid, strna(comm));
2130 /* Actually do the operation */
2131 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2133 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2135 manager->action_unit = NULL;
2136 manager->action_what = 0;
2143 int manager_start_scope(
2148 const char *description,
2150 const char *kill_mode,
2151 sd_bus_error *error,
2154 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2161 r = sd_bus_message_new_method_call(
2163 "org.freedesktop.systemd1",
2164 "/org/freedesktop/systemd1",
2165 "org.freedesktop.systemd1.Manager",
2166 "StartTransientUnit",
2171 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2175 r = sd_bus_message_open_container(m, 'a', "(sv)");
2179 if (!isempty(slice)) {
2180 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2185 if (!isempty(description)) {
2186 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2191 if (!isempty(description)) {
2192 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2197 if (!isempty(kill_mode)) {
2198 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2203 /* cgroup empty notification is not available in containers
2204 * currently. To make this less problematic, let's shorten the
2205 * stop timeout for sessions, so that we don't wait
2208 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2212 /* Make sure that the session shells are terminated with
2213 * SIGHUP since bash and friends tend to ignore SIGTERM */
2214 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2218 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2222 r = sd_bus_message_close_container(m);
2226 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2230 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2238 r = sd_bus_message_read(reply, "o", &j);
2252 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2253 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2259 r = sd_bus_call_method(
2261 "org.freedesktop.systemd1",
2262 "/org/freedesktop/systemd1",
2263 "org.freedesktop.systemd1.Manager",
2267 "ss", unit, "fail");
2275 r = sd_bus_message_read(reply, "o", &j);
2289 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2290 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2296 r = sd_bus_call_method(
2298 "org.freedesktop.systemd1",
2299 "/org/freedesktop/systemd1",
2300 "org.freedesktop.systemd1.Manager",
2304 "ss", unit, "fail");
2306 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2307 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2312 sd_bus_error_free(error);
2323 r = sd_bus_message_read(reply, "o", &j);
2337 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2341 return sd_bus_call_method(
2343 "org.freedesktop.systemd1",
2344 "/org/freedesktop/systemd1",
2345 "org.freedesktop.systemd1.Manager",
2349 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2352 int manager_unit_is_active(Manager *manager, const char *unit) {
2353 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2354 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2355 _cleanup_free_ char *path = NULL;
2362 path = unit_dbus_path_from_name(unit);
2366 r = sd_bus_get_property(
2368 "org.freedesktop.systemd1",
2370 "org.freedesktop.systemd1.Unit",
2376 /* systemd might have droppped off momentarily, let's
2377 * not make this an error */
2378 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2379 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2382 /* If the unit is already unloaded then it's not
2384 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2385 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2391 r = sd_bus_message_read(reply, "s", &state);
2395 return !streq(state, "inactive") && !streq(state, "failed");
2398 int manager_job_is_active(Manager *manager, const char *path) {
2399 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2400 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2406 r = sd_bus_get_property(
2408 "org.freedesktop.systemd1",
2410 "org.freedesktop.systemd1.Job",
2416 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2417 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2420 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2426 /* We don't actually care about the state really. The fact
2427 * that we could read the job state is enough for us */