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 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
177 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
181 r = sd_bus_creds_get_pid(creds, &pid);
186 r = manager_get_session_by_pid(m, pid, &session);
190 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
192 p = session_bus_path(session);
196 return sd_bus_reply_method_return(message, "o", p);
199 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
200 _cleanup_free_ char *p = NULL;
201 Manager *m = userdata;
210 r = sd_bus_message_read(message, "u", &uid);
214 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
216 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
218 p = user_bus_path(user);
222 return sd_bus_reply_method_return(message, "o", p);
225 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
226 _cleanup_free_ char *p = NULL;
227 Manager *m = userdata;
236 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
238 r = sd_bus_message_read(message, "u", &pid);
243 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
245 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
249 r = sd_bus_creds_get_pid(creds, &pid);
254 r = manager_get_user_by_pid(m, pid, &user);
258 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);
260 p = user_bus_path(user);
264 return sd_bus_reply_method_return(message, "o", p);
267 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
268 _cleanup_free_ char *p = NULL;
269 Manager *m = userdata;
278 r = sd_bus_message_read(message, "s", &name);
282 seat = hashmap_get(m->seats, name);
284 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
286 p = seat_bus_path(seat);
290 return sd_bus_reply_method_return(message, "o", p);
293 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
294 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
295 Manager *m = userdata;
304 r = sd_bus_message_new_method_return(message, &reply);
308 r = sd_bus_message_open_container(reply, 'a', "(susso)");
312 HASHMAP_FOREACH(session, m->sessions, i) {
313 _cleanup_free_ char *p = NULL;
315 p = session_bus_path(session);
319 r = sd_bus_message_append(reply, "(susso)",
321 (uint32_t) session->user->uid,
323 session->seat ? session->seat->id : "",
329 r = sd_bus_message_close_container(reply);
333 return sd_bus_send(bus, reply, NULL);
336 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
337 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
338 Manager *m = userdata;
347 r = sd_bus_message_new_method_return(message, &reply);
351 r = sd_bus_message_open_container(reply, 'a', "(uso)");
355 HASHMAP_FOREACH(user, m->users, i) {
356 _cleanup_free_ char *p = NULL;
358 p = user_bus_path(user);
362 r = sd_bus_message_append(reply, "(uso)",
363 (uint32_t) user->uid,
370 r = sd_bus_message_close_container(reply);
374 return sd_bus_send(bus, reply, NULL);
377 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
378 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
379 Manager *m = userdata;
388 r = sd_bus_message_new_method_return(message, &reply);
392 r = sd_bus_message_open_container(reply, 'a', "(so)");
396 HASHMAP_FOREACH(seat, m->seats, i) {
397 _cleanup_free_ char *p = NULL;
399 p = seat_bus_path(seat);
403 r = sd_bus_message_append(reply, "(so)", seat->id, p);
408 r = sd_bus_message_close_container(reply);
412 return sd_bus_send(bus, reply, NULL);
415 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
416 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
417 Manager *m = userdata;
418 Inhibitor *inhibitor;
422 r = sd_bus_message_new_method_return(message, &reply);
426 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
430 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
432 r = sd_bus_message_append(reply, "(ssssuu)",
433 strempty(inhibit_what_to_string(inhibitor->what)),
434 strempty(inhibitor->who),
435 strempty(inhibitor->why),
436 strempty(inhibit_mode_to_string(inhibitor->mode)),
437 (uint32_t) inhibitor->uid,
438 (uint32_t) inhibitor->pid);
443 r = sd_bus_message_close_container(reply);
447 return sd_bus_send(bus, reply, NULL);
450 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
451 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
452 uint32_t uid, leader, audit_id = 0;
453 _cleanup_free_ char *id = NULL;
454 Session *session = NULL;
455 Manager *m = userdata;
468 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
473 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
476 t = _SESSION_TYPE_INVALID;
478 t = session_type_from_string(type);
480 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
484 c = _SESSION_CLASS_INVALID;
486 c = session_class_from_string(class);
488 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
494 seat = hashmap_get(m->seats, cseat);
496 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
499 if (tty_is_vc(tty)) {
504 else if (seat != m->seat0)
505 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
507 v = vtnr_from_tty(tty);
509 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
513 else if (vtnr != (uint32_t) v)
514 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
516 } else if (tty_is_console(tty)) {
520 else if (seat != m->seat0)
521 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
524 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
528 if (seat_has_vts(seat)) {
529 if (!vtnr || vtnr > 63)
530 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
533 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
537 r = sd_bus_message_enter_container(message, 'a', "(sv)");
541 if (t == _SESSION_TYPE_INVALID) {
542 if (!isempty(display))
544 else if (!isempty(tty))
547 t = SESSION_UNSPECIFIED;
550 if (c == _SESSION_CLASS_INVALID) {
551 if (!isempty(display) || !isempty(tty))
554 c = SESSION_BACKGROUND;
558 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
560 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
564 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
566 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
571 manager_get_session_by_pid(m, leader, &session);
573 _cleanup_free_ char *path = NULL;
574 _cleanup_close_ int fifo_fd = -1;
576 /* Session already exists, client is probably
577 * something like "su" which changes uid but is still
578 * the same session */
580 fifo_fd = session_create_fifo(session);
584 path = session_bus_path(session);
588 return sd_bus_reply_method_return(
592 session->user->runtime_path,
594 (uint32_t) session->user->uid,
595 session->seat ? session->seat->id : "",
596 (uint32_t) session->vtnr,
600 audit_session_from_pid(leader, &audit_id);
602 /* Keep our session IDs and the audit session IDs in sync */
604 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
607 /* Wut? There's already a session by this name and we
608 * didn't find it above? Weird, then let's not trust
609 * the audit data and let's better register a new
611 if (hashmap_get(m->sessions, id)) {
612 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
625 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
628 } while (hashmap_get(m->sessions, id));
631 r = manager_add_user_by_uid(m, uid, &user);
635 r = manager_add_session(m, id, &session);
639 session_set_user(session, user);
641 session->leader = leader;
642 session->audit_id = audit_id;
645 session->remote = remote;
646 session->vtnr = vtnr;
649 session->tty = strdup(tty);
656 if (!isempty(display)) {
657 session->display = strdup(display);
658 if (!session->display) {
664 if (!isempty(remote_user)) {
665 session->remote_user = strdup(remote_user);
666 if (!session->remote_user) {
672 if (!isempty(remote_host)) {
673 session->remote_host = strdup(remote_host);
674 if (!session->remote_host) {
680 if (!isempty(service)) {
681 session->service = strdup(service);
682 if (!session->service) {
689 r = seat_attach_session(seat, session);
694 r = session_start(session);
698 session->create_message = sd_bus_message_ref(message);
700 /* Now, let's wait until the slice unit and stuff got
701 * created. We send the reply back from
702 * session_send_create_reply().*/
708 session_add_to_gc_queue(session);
711 user_add_to_gc_queue(user);
716 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
717 Manager *m = userdata;
726 r = sd_bus_message_read(message, "s", &name);
730 session = hashmap_get(m->sessions, name);
732 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
734 /* We use the FIFO to detect stray sessions where the process
735 invoking PAM dies abnormally. We need to make sure that
736 that process is not killed if at the clean end of the
737 session it closes the FIFO. Hence, with this call
738 explicitly turn off the FIFO logic, so that the PAM code
739 can finish clean up on its own */
740 session_remove_fifo(session);
741 session_save(session);
742 user_save(session->user);
744 return sd_bus_reply_method_return(message, NULL);
747 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
748 Manager *m = userdata;
757 r = sd_bus_message_read(message, "s", &name);
761 session = hashmap_get(m->sessions, name);
763 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
765 r = session_activate(session);
769 return sd_bus_reply_method_return(message, NULL);
772 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
773 const char *session_name, *seat_name;
774 Manager *m = userdata;
783 /* Same as ActivateSession() but refuses to work if
784 * the seat doesn't match */
786 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
790 session = hashmap_get(m->sessions, session_name);
792 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
794 seat = hashmap_get(m->seats, seat_name);
796 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
798 if (session->seat != seat)
799 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
801 r = session_activate(session);
805 return sd_bus_reply_method_return(message, NULL);
808 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
809 Manager *m = userdata;
818 r = sd_bus_message_read(message, "s", &name);
822 session = hashmap_get(m->sessions, name);
824 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
826 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
830 return sd_bus_reply_method_return(message, NULL);
833 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
834 Manager *m = userdata;
841 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
845 return sd_bus_reply_method_return(message, NULL);
848 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
849 const char *name, *swho;
850 Manager *m = userdata;
860 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
867 who = kill_who_from_string(swho);
869 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
872 if (signo <= 0 || signo >= _NSIG)
873 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
875 session = hashmap_get(m->sessions, name);
877 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
879 r = session_kill(session, who, signo);
883 return sd_bus_reply_method_return(message, NULL);
886 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
887 Manager *m = userdata;
897 r = sd_bus_message_read(message, "ui", &uid, &signo);
901 if (signo <= 0 || signo >= _NSIG)
902 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
904 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
906 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
908 r = user_kill(user, signo);
912 return sd_bus_reply_method_return(message, NULL);
915 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
916 Manager *m = userdata;
925 r = sd_bus_message_read(message, "s", &name);
929 session = hashmap_get(m->sessions, name);
931 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
933 r = session_stop(session);
937 return sd_bus_reply_method_return(message, NULL);
940 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
941 Manager *m = userdata;
950 r = sd_bus_message_read(message, "u", &uid);
954 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
956 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
962 return sd_bus_reply_method_return(message, NULL);
965 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
966 Manager *m = userdata;
975 r = sd_bus_message_read(message, "s", &name);
979 seat = hashmap_get(m->seats, name);
981 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
983 r = seat_stop_sessions(seat);
987 return sd_bus_reply_method_return(message, NULL);
990 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
991 _cleanup_free_ char *cc = NULL;
992 Manager *m = userdata;
1003 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1010 return errno ? -errno : -ENOENT;
1012 r = bus_verify_polkit_async(bus,
1013 &m->polkit_registry,
1015 "org.freedesktop.login1.set-user-linger",
1018 method_set_user_linger, m);
1022 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1024 mkdir_p_label("/var/lib/systemd", 0755);
1026 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1030 cc = cescape(pw->pw_name);
1034 path = strappenda("/var/lib/systemd/linger/", cc);
1042 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1049 if (r < 0 && errno != ENOENT)
1052 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1054 user_add_to_gc_queue(u);
1057 return sd_bus_reply_method_return(message, NULL);
1060 static int trigger_device(Manager *m, struct udev_device *d) {
1061 struct udev_enumerate *e;
1062 struct udev_list_entry *first, *item;
1067 e = udev_enumerate_new(m->udev);
1074 if (udev_enumerate_add_match_parent(e, d) < 0) {
1080 if (udev_enumerate_scan_devices(e) < 0) {
1085 first = udev_enumerate_get_list_entry(e);
1086 udev_list_entry_foreach(item, first) {
1087 _cleanup_free_ char *t = NULL;
1090 p = udev_list_entry_get_name(item);
1092 t = strappend(p, "/uevent");
1098 write_string_file(t, "change");
1105 udev_enumerate_unref(e);
1110 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1111 _cleanup_free_ char *rule = NULL, *file = NULL;
1112 const char *id_for_seat;
1113 struct udev_device *d;
1120 d = udev_device_new_from_syspath(m->udev, sysfs);
1124 if (!udev_device_has_tag(d, "seat")) {
1129 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1135 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
1140 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1145 mkdir_p_label("/etc/udev/rules.d", 0755);
1147 r = write_string_file_atomic_label(file, rule);
1151 r = trigger_device(m, d);
1155 udev_device_unref(d);
1160 static int flush_devices(Manager *m) {
1161 _cleanup_closedir_ DIR *d;
1165 d = opendir("/etc/udev/rules.d");
1167 if (errno != ENOENT)
1168 log_warning("Failed to open /etc/udev/rules.d: %m");
1172 while ((de = readdir(d))) {
1174 if (!dirent_is_file(de))
1177 if (!startswith(de->d_name, "72-seat-"))
1180 if (!endswith(de->d_name, ".rules"))
1183 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1184 log_warning("Failed to unlink %s: %m", de->d_name);
1188 return trigger_device(m, NULL);
1191 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1192 const char *sysfs, *seat;
1193 Manager *m = userdata;
1200 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1204 if (!path_startswith(sysfs, "/sys"))
1205 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1207 if (!seat_name_is_valid(seat))
1208 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1210 r = bus_verify_polkit_async(bus,
1211 &m->polkit_registry,
1213 "org.freedesktop.login1.attach-device",
1216 method_attach_device, m);
1220 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1222 r = attach_device(m, seat, sysfs);
1226 return sd_bus_reply_method_return(message, NULL);
1229 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1230 Manager *m = userdata;
1237 r = sd_bus_message_read(message, "b", &interactive);
1241 r = bus_verify_polkit_async(bus,
1242 &m->polkit_registry,
1244 "org.freedesktop.login1.flush-devices",
1247 method_flush_devices, m);
1251 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1253 r = flush_devices(m);
1257 return sd_bus_reply_method_return(message, NULL);
1260 static int have_multiple_sessions(
1269 /* Check for other users' sessions. Greeter sessions do not
1270 * count, and non-login sessions do not count either. */
1271 HASHMAP_FOREACH(session, m->sessions, i)
1272 if (session->class == SESSION_USER &&
1273 session->user->uid != uid)
1279 static int bus_manager_log_shutdown(
1282 const char *unit_name) {
1289 if (w != INHIBIT_SHUTDOWN)
1292 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1293 p = "MESSAGE=System is powering down.";
1294 q = "SHUTDOWN=power-off";
1295 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1296 p = "MESSAGE=System is halting.";
1297 q = "SHUTDOWN=halt";
1298 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1299 p = "MESSAGE=System is rebooting.";
1300 q = "SHUTDOWN=reboot";
1301 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1302 p = "MESSAGE=System is rebooting with kexec.";
1303 q = "SHUTDOWN=kexec";
1305 p = "MESSAGE=System is shutting down.";
1309 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1314 static int execute_shutdown_or_sleep(
1317 const char *unit_name,
1318 sd_bus_error *error) {
1320 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1327 assert(w < _INHIBIT_WHAT_MAX);
1330 bus_manager_log_shutdown(m, w, unit_name);
1332 r = sd_bus_call_method(
1334 "org.freedesktop.systemd1",
1335 "/org/freedesktop/systemd1",
1336 "org.freedesktop.systemd1.Manager",
1340 "ss", unit_name, "replace-irreversibly");
1344 r = sd_bus_message_read(reply, "o", &p);
1352 m->action_unit = unit_name;
1353 free(m->action_job);
1360 static int delay_shutdown_or_sleep(
1363 const char *unit_name) {
1367 assert(w < _INHIBIT_WHAT_MAX);
1370 m->action_timestamp = now(CLOCK_MONOTONIC);
1371 m->action_unit = unit_name;
1377 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1379 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1380 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1381 [INHIBIT_SLEEP] = "PrepareForSleep"
1384 int active = _active;
1388 assert(w < _INHIBIT_WHAT_MAX);
1389 assert(signal_name[w]);
1391 return sd_bus_emit_signal(m->bus,
1392 "/org/freedesktop/login1",
1393 "org.freedesktop.login1.Manager",
1399 int bus_manager_shutdown_or_sleep_now_or_later(
1401 const char *unit_name,
1403 sd_bus_error *error) {
1411 assert(w <= _INHIBIT_WHAT_MAX);
1412 assert(!m->action_job);
1414 /* Tell everybody to prepare for shutdown/sleep */
1415 send_prepare_for(m, w, true);
1418 m->inhibit_delay_max > 0 &&
1419 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1422 /* Shutdown is delayed, keep in mind what we
1423 * want to do, and start a timeout */
1424 r = delay_shutdown_or_sleep(m, w, unit_name);
1426 /* Shutdown is not delayed, execute it
1428 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1433 static int method_do_shutdown_or_sleep(
1435 sd_bus_message *message,
1436 const char *unit_name,
1439 const char *action_multiple_sessions,
1440 const char *action_ignore_inhibit,
1441 const char *sleep_verb,
1442 sd_bus_message_handler_t method,
1443 sd_bus_error *error) {
1445 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1446 bool multiple_sessions, blocked;
1454 assert(w <= _INHIBIT_WHAT_MAX);
1456 assert(action_multiple_sessions);
1457 assert(action_ignore_inhibit);
1460 r = sd_bus_message_read(message, "b", &interactive);
1464 /* Don't allow multiple jobs being executed at the same time */
1466 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1469 r = can_sleep(sleep_verb);
1474 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1477 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1481 r = sd_bus_creds_get_uid(creds, &uid);
1485 r = have_multiple_sessions(m, uid);
1489 multiple_sessions = r > 0;
1490 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1492 if (multiple_sessions) {
1493 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1494 action_multiple_sessions, interactive, error, method, m);
1500 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1501 action_ignore_inhibit, interactive, error, method, m);
1506 if (!multiple_sessions && !blocked) {
1507 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1508 action, interactive, error, method, m);
1513 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1517 return sd_bus_reply_method_return(message, NULL);
1520 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1521 Manager *m = userdata;
1523 return method_do_shutdown_or_sleep(
1525 SPECIAL_POWEROFF_TARGET,
1527 "org.freedesktop.login1.power-off",
1528 "org.freedesktop.login1.power-off-multiple-sessions",
1529 "org.freedesktop.login1.power-off-ignore-inhibit",
1535 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1536 Manager *m = userdata;
1538 return method_do_shutdown_or_sleep(
1540 SPECIAL_REBOOT_TARGET,
1542 "org.freedesktop.login1.reboot",
1543 "org.freedesktop.login1.reboot-multiple-sessions",
1544 "org.freedesktop.login1.reboot-ignore-inhibit",
1550 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1551 Manager *m = userdata;
1553 return method_do_shutdown_or_sleep(
1555 SPECIAL_SUSPEND_TARGET,
1557 "org.freedesktop.login1.suspend",
1558 "org.freedesktop.login1.suspend-multiple-sessions",
1559 "org.freedesktop.login1.suspend-ignore-inhibit",
1565 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1566 Manager *m = userdata;
1568 return method_do_shutdown_or_sleep(
1570 SPECIAL_HIBERNATE_TARGET,
1572 "org.freedesktop.login1.hibernate",
1573 "org.freedesktop.login1.hibernate-multiple-sessions",
1574 "org.freedesktop.login1.hibernate-ignore-inhibit",
1580 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1581 Manager *m = userdata;
1583 return method_do_shutdown_or_sleep(
1585 SPECIAL_HYBRID_SLEEP_TARGET,
1587 "org.freedesktop.login1.hibernate",
1588 "org.freedesktop.login1.hibernate-multiple-sessions",
1589 "org.freedesktop.login1.hibernate-ignore-inhibit",
1591 method_hybrid_sleep,
1595 static int method_can_shutdown_or_sleep(
1597 sd_bus_message *message,
1600 const char *action_multiple_sessions,
1601 const char *action_ignore_inhibit,
1602 const char *sleep_verb,
1603 sd_bus_error *error) {
1605 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1606 bool multiple_sessions, challenge, blocked;
1607 const char *result = NULL;
1614 assert(w <= _INHIBIT_WHAT_MAX);
1616 assert(action_multiple_sessions);
1617 assert(action_ignore_inhibit);
1620 r = can_sleep(sleep_verb);
1624 return sd_bus_reply_method_return(message, "s", "na");
1627 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1631 r = sd_bus_creds_get_uid(creds, &uid);
1635 r = have_multiple_sessions(m, uid);
1639 multiple_sessions = r > 0;
1640 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1642 if (multiple_sessions) {
1643 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1650 result = "challenge";
1656 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1660 if (r > 0 && !result)
1662 else if (challenge && (!result || streq(result, "yes")))
1663 result = "challenge";
1668 if (!multiple_sessions && !blocked) {
1669 /* If neither inhibit nor multiple sessions
1670 * apply then just check the normal policy */
1672 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1679 result = "challenge";
1684 return sd_bus_reply_method_return(message, "s", result);
1687 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1688 Manager *m = userdata;
1690 return method_can_shutdown_or_sleep(
1693 "org.freedesktop.login1.power-off",
1694 "org.freedesktop.login1.power-off-multiple-sessions",
1695 "org.freedesktop.login1.power-off-ignore-inhibit",
1700 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1701 Manager *m = userdata;
1703 return method_can_shutdown_or_sleep(
1706 "org.freedesktop.login1.reboot",
1707 "org.freedesktop.login1.reboot-multiple-sessions",
1708 "org.freedesktop.login1.reboot-ignore-inhibit",
1713 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1714 Manager *m = userdata;
1716 return method_can_shutdown_or_sleep(
1719 "org.freedesktop.login1.suspend",
1720 "org.freedesktop.login1.suspend-multiple-sessions",
1721 "org.freedesktop.login1.suspend-ignore-inhibit",
1726 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727 Manager *m = userdata;
1729 return method_can_shutdown_or_sleep(
1732 "org.freedesktop.login1.hibernate",
1733 "org.freedesktop.login1.hibernate-multiple-sessions",
1734 "org.freedesktop.login1.hibernate-ignore-inhibit",
1739 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1740 Manager *m = userdata;
1742 return method_can_shutdown_or_sleep(
1745 "org.freedesktop.login1.hibernate",
1746 "org.freedesktop.login1.hibernate-multiple-sessions",
1747 "org.freedesktop.login1.hibernate-ignore-inhibit",
1752 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1753 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1754 const char *who, *why, *what, *mode;
1755 _cleanup_free_ char *id = NULL;
1756 _cleanup_close_ int fifo_fd = -1;
1757 Manager *m = userdata;
1758 Inhibitor *i = NULL;
1769 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1773 w = inhibit_what_from_string(what);
1775 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1777 mm = inhibit_mode_from_string(mode);
1779 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1781 /* Delay is only supported for shutdown/sleep */
1782 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1783 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1785 /* Don't allow taking delay locks while we are already
1786 * executing the operation. We shouldn't create the impression
1787 * that the lock was successful if the machine is about to go
1788 * down/suspend any moment. */
1789 if (m->action_what & w)
1790 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1792 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1793 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1794 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1795 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1796 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1797 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1798 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1799 "org.freedesktop.login1.inhibit-handle-lid-switch",
1800 false, error, method_inhibit, m);
1804 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1806 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1810 r = sd_bus_creds_get_uid(creds, &uid);
1814 r = sd_bus_creds_get_pid(creds, &pid);
1822 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1825 } while (hashmap_get(m->inhibitors, id));
1827 r = manager_add_inhibitor(m, id, &i);
1835 i->why = strdup(why);
1836 i->who = strdup(who);
1838 if (!i->why || !i->who) {
1843 fifo_fd = inhibitor_create_fifo(i);
1851 return sd_bus_reply_method_return(message, "h", fifo_fd);
1860 const sd_bus_vtable manager_vtable[] = {
1861 SD_BUS_VTABLE_START(0),
1863 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1864 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1865 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1866 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1867 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1868 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1869 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1870 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1871 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1872 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1873 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1874 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1875 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1876 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1877 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1878 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1879 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1880 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1882 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1883 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1884 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1885 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1886 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1887 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1888 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1889 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1890 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1891 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
1892 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1893 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1894 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1895 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1896 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1897 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1898 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1899 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1900 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1901 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1902 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1903 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1904 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1905 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1906 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1907 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1908 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1909 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1910 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1911 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1912 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1913 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1914 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1915 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1916 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1917 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1919 SD_BUS_SIGNAL("SessionNew", "so", 0),
1920 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1921 SD_BUS_SIGNAL("UserNew", "uo", 0),
1922 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1923 SD_BUS_SIGNAL("SeatNew", "so", 0),
1924 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1925 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1926 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1931 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1932 const char *path, *result, *unit;
1933 Manager *m = userdata;
1943 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1945 bus_log_parse_error(r);
1949 if (m->action_job && streq(m->action_job, path)) {
1950 log_info("Operation finished.");
1952 /* Tell people that they now may take a lock again */
1953 send_prepare_for(m, m->action_what, false);
1955 free(m->action_job);
1956 m->action_job = NULL;
1957 m->action_unit = NULL;
1962 session = hashmap_get(m->session_units, unit);
1965 if (streq_ptr(path, session->scope_job)) {
1966 free(session->scope_job);
1967 session->scope_job = NULL;
1970 if (session->started) {
1971 if (streq(result, "done"))
1972 session_send_create_reply(session, NULL);
1974 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1976 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1977 session_send_create_reply(session, &e);
1980 session_save(session);
1982 session_add_to_gc_queue(session);
1985 user = hashmap_get(m->user_units, unit);
1988 if (streq_ptr(path, user->service_job)) {
1989 free(user->service_job);
1990 user->service_job = NULL;
1993 if (streq_ptr(path, user->slice_job)) {
1994 free(user->slice_job);
1995 user->slice_job = NULL;
1999 user_add_to_gc_queue(user);
2005 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2006 const char *path, *unit;
2007 Manager *m = userdata;
2016 r = sd_bus_message_read(message, "so", &unit, &path);
2018 bus_log_parse_error(r);
2022 session = hashmap_get(m->session_units, unit);
2024 session_add_to_gc_queue(session);
2026 user = hashmap_get(m->user_units, unit);
2028 user_add_to_gc_queue(user);
2033 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2034 _cleanup_free_ char *unit = NULL;
2035 Manager *m = userdata;
2045 path = sd_bus_message_get_path(message);
2049 r = unit_name_from_dbus_path(path, &unit);
2053 session = hashmap_get(m->session_units, unit);
2055 session_add_to_gc_queue(session);
2057 user = hashmap_get(m->user_units, unit);
2059 user_add_to_gc_queue(user);
2064 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2065 Manager *m = userdata;
2072 r = sd_bus_message_read(message, "b", &b);
2074 bus_log_parse_error(r);
2081 /* systemd finished reloading, let's recheck all our sessions */
2082 log_debug("System manager has been reloaded, rechecking sessions...");
2084 HASHMAP_FOREACH(session, m->sessions, i)
2085 session_add_to_gc_queue(session);
2090 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2091 const char *name, *old, *new;
2092 Manager *m = userdata;
2100 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2102 bus_log_parse_error(r);
2106 if (isempty(old) || !isempty(new))
2109 key = set_remove(m->busnames, (char*) old);
2113 /* Drop all controllers owned by this name */
2117 HASHMAP_FOREACH(session, m->sessions, i)
2118 if (session_is_controller(session, old))
2119 session_drop_controller(session);
2124 int manager_send_changed(Manager *manager, const char *property, ...) {
2129 l = strv_from_stdarg_alloca(property);
2131 return sd_bus_emit_properties_changed_strv(
2133 "/org/freedesktop/login1",
2134 "org.freedesktop.login1.Manager",
2138 int manager_dispatch_delayed(Manager *manager) {
2139 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2140 Inhibitor *offending = NULL;
2145 if (manager->action_what == 0 || manager->action_job)
2148 /* Continue delay? */
2149 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2150 _cleanup_free_ char *comm = NULL, *u = NULL;
2152 get_process_comm(offending->pid, &comm);
2153 u = uid_to_name(offending->uid);
2155 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2158 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2159 (unsigned long) offending->uid, strna(u),
2160 (unsigned long) offending->pid, strna(comm));
2163 /* Actually do the operation */
2164 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2166 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2168 manager->action_unit = NULL;
2169 manager->action_what = 0;
2176 int manager_start_scope(
2181 const char *description,
2183 const char *kill_mode,
2184 sd_bus_error *error,
2187 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2194 r = sd_bus_message_new_method_call(
2196 "org.freedesktop.systemd1",
2197 "/org/freedesktop/systemd1",
2198 "org.freedesktop.systemd1.Manager",
2199 "StartTransientUnit",
2204 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2208 r = sd_bus_message_open_container(m, 'a', "(sv)");
2212 if (!isempty(slice)) {
2213 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2218 if (!isempty(description)) {
2219 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2224 if (!isempty(description)) {
2225 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2230 if (!isempty(kill_mode)) {
2231 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2236 /* cgroup empty notification is not available in containers
2237 * currently. To make this less problematic, let's shorten the
2238 * stop timeout for sessions, so that we don't wait
2241 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2245 /* Make sure that the session shells are terminated with
2246 * SIGHUP since bash and friends tend to ignore SIGTERM */
2247 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2251 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2255 r = sd_bus_message_close_container(m);
2259 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2263 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2271 r = sd_bus_message_read(reply, "o", &j);
2285 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2286 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2292 r = sd_bus_call_method(
2294 "org.freedesktop.systemd1",
2295 "/org/freedesktop/systemd1",
2296 "org.freedesktop.systemd1.Manager",
2300 "ss", unit, "fail");
2308 r = sd_bus_message_read(reply, "o", &j);
2322 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2323 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2329 r = sd_bus_call_method(
2331 "org.freedesktop.systemd1",
2332 "/org/freedesktop/systemd1",
2333 "org.freedesktop.systemd1.Manager",
2337 "ss", unit, "fail");
2339 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2340 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2345 sd_bus_error_free(error);
2356 r = sd_bus_message_read(reply, "o", &j);
2370 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2374 return sd_bus_call_method(
2376 "org.freedesktop.systemd1",
2377 "/org/freedesktop/systemd1",
2378 "org.freedesktop.systemd1.Manager",
2382 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2385 int manager_unit_is_active(Manager *manager, const char *unit) {
2386 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2387 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2388 _cleanup_free_ char *path = NULL;
2395 path = unit_dbus_path_from_name(unit);
2399 r = sd_bus_get_property(
2401 "org.freedesktop.systemd1",
2403 "org.freedesktop.systemd1.Unit",
2409 /* systemd might have droppped off momentarily, let's
2410 * not make this an error */
2411 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2412 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2415 /* If the unit is already unloaded then it's not
2417 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2418 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2424 r = sd_bus_message_read(reply, "s", &state);
2428 return !streq(state, "inactive") && !streq(state, "failed");
2431 int manager_job_is_active(Manager *manager, const char *path) {
2432 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2433 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2439 r = sd_bus_get_property(
2441 "org.freedesktop.systemd1",
2443 "org.freedesktop.systemd1.Job",
2449 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2450 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2453 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2459 /* We don't actually care about the state really. The fact
2460 * that we could read the job state is enough for us */