1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/capability.h>
29 #include "sd-messages.h"
32 #include "path-util.h"
34 #include "sleep-config.h"
35 #include "fileio-label.h"
38 #include "unit-name.h"
42 #include "bus-error.h"
44 #include "bus-errors.h"
45 #include "udev-util.h"
47 static int property_get_idle_hint(
50 const char *interface,
52 sd_bus_message *reply,
54 sd_bus_error *error) {
56 Manager *m = userdata;
62 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
65 static int property_get_idle_since_hint(
68 const char *interface,
70 sd_bus_message *reply,
72 sd_bus_error *error) {
74 Manager *m = userdata;
81 manager_get_idle_hint(m, &t);
83 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
86 static int property_get_inhibited(
89 const char *interface,
91 sd_bus_message *reply,
93 sd_bus_error *error) {
95 Manager *m = userdata;
102 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
104 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
107 static int property_get_preparing(
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
114 sd_bus_error *error) {
116 Manager *m = userdata;
123 if (streq(property, "PreparingForShutdown"))
124 b = !!(m->action_what & INHIBIT_SHUTDOWN);
126 b = !!(m->action_what & INHIBIT_SLEEP);
128 return sd_bus_message_append(reply, "b", b);
131 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
133 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
134 _cleanup_free_ char *p = NULL;
135 Manager *m = userdata;
144 r = sd_bus_message_read(message, "s", &name);
148 session = hashmap_get(m->sessions, name);
150 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
152 p = session_bus_path(session);
156 return sd_bus_reply_method_return(message, "o", p);
159 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
160 _cleanup_free_ char *p = NULL;
161 Session *session = NULL;
162 Manager *m = userdata;
170 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
172 r = sd_bus_message_read(message, "u", &pid);
177 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
179 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
183 r = sd_bus_creds_get_pid(creds, &pid);
188 r = manager_get_session_by_pid(m, pid, &session);
192 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
194 p = session_bus_path(session);
198 return sd_bus_reply_method_return(message, "o", p);
201 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
202 _cleanup_free_ char *p = NULL;
203 Manager *m = userdata;
212 r = sd_bus_message_read(message, "u", &uid);
216 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
218 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
220 p = user_bus_path(user);
224 return sd_bus_reply_method_return(message, "o", p);
227 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
228 _cleanup_free_ char *p = NULL;
229 Manager *m = userdata;
238 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
240 r = sd_bus_message_read(message, "u", &pid);
245 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
247 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
251 r = sd_bus_creds_get_pid(creds, &pid);
256 r = manager_get_user_by_pid(m, pid, &user);
260 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
262 p = user_bus_path(user);
266 return sd_bus_reply_method_return(message, "o", p);
269 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
270 _cleanup_free_ char *p = NULL;
271 Manager *m = userdata;
280 r = sd_bus_message_read(message, "s", &name);
284 seat = hashmap_get(m->seats, name);
286 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
288 p = seat_bus_path(seat);
292 return sd_bus_reply_method_return(message, "o", p);
295 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
297 Manager *m = userdata;
306 r = sd_bus_message_new_method_return(message, &reply);
310 r = sd_bus_message_open_container(reply, 'a', "(susso)");
314 HASHMAP_FOREACH(session, m->sessions, i) {
315 _cleanup_free_ char *p = NULL;
317 p = session_bus_path(session);
321 r = sd_bus_message_append(reply, "(susso)",
323 (uint32_t) session->user->uid,
325 session->seat ? session->seat->id : "",
331 r = sd_bus_message_close_container(reply);
335 return sd_bus_send(bus, reply, NULL);
338 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
339 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
340 Manager *m = userdata;
349 r = sd_bus_message_new_method_return(message, &reply);
353 r = sd_bus_message_open_container(reply, 'a', "(uso)");
357 HASHMAP_FOREACH(user, m->users, i) {
358 _cleanup_free_ char *p = NULL;
360 p = user_bus_path(user);
364 r = sd_bus_message_append(reply, "(uso)",
365 (uint32_t) user->uid,
372 r = sd_bus_message_close_container(reply);
376 return sd_bus_send(bus, reply, NULL);
379 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
380 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
381 Manager *m = userdata;
390 r = sd_bus_message_new_method_return(message, &reply);
394 r = sd_bus_message_open_container(reply, 'a', "(so)");
398 HASHMAP_FOREACH(seat, m->seats, i) {
399 _cleanup_free_ char *p = NULL;
401 p = seat_bus_path(seat);
405 r = sd_bus_message_append(reply, "(so)", seat->id, p);
410 r = sd_bus_message_close_container(reply);
414 return sd_bus_send(bus, reply, NULL);
417 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
418 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
419 Manager *m = userdata;
420 Inhibitor *inhibitor;
424 r = sd_bus_message_new_method_return(message, &reply);
428 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
432 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
434 r = sd_bus_message_append(reply, "(ssssuu)",
435 strempty(inhibit_what_to_string(inhibitor->what)),
436 strempty(inhibitor->who),
437 strempty(inhibitor->why),
438 strempty(inhibit_mode_to_string(inhibitor->mode)),
439 (uint32_t) inhibitor->uid,
440 (uint32_t) inhibitor->pid);
445 r = sd_bus_message_close_container(reply);
449 return sd_bus_send(bus, reply, NULL);
452 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
454 uint32_t uid, leader, audit_id = 0;
455 _cleanup_free_ char *id = NULL;
456 Session *session = NULL;
457 Manager *m = userdata;
470 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
475 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
478 t = _SESSION_TYPE_INVALID;
480 t = session_type_from_string(type);
482 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
486 c = _SESSION_CLASS_INVALID;
488 c = session_class_from_string(class);
490 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
493 if (isempty(desktop))
496 if (!string_is_safe(desktop))
497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
503 seat = hashmap_get(m->seats, cseat);
505 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
508 if (tty_is_vc(tty)) {
513 else if (seat != m->seat0)
514 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
516 v = vtnr_from_tty(tty);
518 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
522 else if (vtnr != (uint32_t) v)
523 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
525 } else if (tty_is_console(tty)) {
529 else if (seat != m->seat0)
530 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
533 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
537 if (seat_has_vts(seat)) {
538 if (!vtnr || vtnr > 63)
539 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
542 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
546 r = sd_bus_message_enter_container(message, 'a', "(sv)");
550 if (t == _SESSION_TYPE_INVALID) {
551 if (!isempty(display))
553 else if (!isempty(tty))
556 t = SESSION_UNSPECIFIED;
559 if (c == _SESSION_CLASS_INVALID) {
560 if (t == SESSION_UNSPECIFIED)
561 c = SESSION_BACKGROUND;
567 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
569 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
573 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
575 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
580 manager_get_session_by_pid(m, leader, &session);
582 _cleanup_free_ char *path = NULL;
583 _cleanup_close_ int fifo_fd = -1;
585 /* Session already exists, client is probably
586 * something like "su" which changes uid but is still
587 * the same session */
589 fifo_fd = session_create_fifo(session);
593 path = session_bus_path(session);
597 log_debug("Sending reply about an existing session: "
598 "id=%s object_path=%s uid=%u runtime_path=%s "
599 "session_fd=%d seat=%s vtnr=%u",
602 (uint32_t) session->user->uid,
603 session->user->runtime_path,
605 session->seat ? session->seat->id : "",
606 (uint32_t) session->vtnr);
608 return sd_bus_reply_method_return(
612 session->user->runtime_path,
614 (uint32_t) session->user->uid,
615 session->seat ? session->seat->id : "",
616 (uint32_t) session->vtnr,
620 audit_session_from_pid(leader, &audit_id);
622 /* Keep our session IDs and the audit session IDs in sync */
624 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
627 /* Wut? There's already a session by this name and we
628 * didn't find it above? Weird, then let's not trust
629 * the audit data and let's better register a new
631 if (hashmap_get(m->sessions, id)) {
632 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
645 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
648 } while (hashmap_get(m->sessions, id));
651 r = manager_add_user_by_uid(m, uid, &user);
655 r = manager_add_session(m, id, &session);
659 session_set_user(session, user);
661 session->leader = leader;
662 session->audit_id = audit_id;
665 session->remote = remote;
666 session->vtnr = vtnr;
669 session->tty = strdup(tty);
676 if (!isempty(display)) {
677 session->display = strdup(display);
678 if (!session->display) {
684 if (!isempty(remote_user)) {
685 session->remote_user = strdup(remote_user);
686 if (!session->remote_user) {
692 if (!isempty(remote_host)) {
693 session->remote_host = strdup(remote_host);
694 if (!session->remote_host) {
700 if (!isempty(service)) {
701 session->service = strdup(service);
702 if (!session->service) {
708 if (!isempty(desktop)) {
709 session->desktop = strdup(desktop);
710 if (!session->desktop) {
717 r = seat_attach_session(seat, session);
722 r = session_start(session);
726 session->create_message = sd_bus_message_ref(message);
728 /* Now, let's wait until the slice unit and stuff got
729 * created. We send the reply back from
730 * session_send_create_reply().*/
736 session_add_to_gc_queue(session);
739 user_add_to_gc_queue(user);
744 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
745 Manager *m = userdata;
754 r = sd_bus_message_read(message, "s", &name);
758 session = hashmap_get(m->sessions, name);
760 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
762 session_release(session);
764 return sd_bus_reply_method_return(message, NULL);
767 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
768 Manager *m = userdata;
777 r = sd_bus_message_read(message, "s", &name);
781 session = hashmap_get(m->sessions, name);
783 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
785 r = session_activate(session);
789 return sd_bus_reply_method_return(message, NULL);
792 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
793 const char *session_name, *seat_name;
794 Manager *m = userdata;
803 /* Same as ActivateSession() but refuses to work if
804 * the seat doesn't match */
806 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
810 session = hashmap_get(m->sessions, session_name);
812 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
814 seat = hashmap_get(m->seats, seat_name);
816 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
818 if (session->seat != seat)
819 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
821 r = session_activate(session);
825 return sd_bus_reply_method_return(message, NULL);
828 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
829 Manager *m = userdata;
838 r = sd_bus_message_read(message, "s", &name);
842 session = hashmap_get(m->sessions, name);
844 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
846 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
850 return sd_bus_reply_method_return(message, NULL);
853 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
854 Manager *m = userdata;
861 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
865 return sd_bus_reply_method_return(message, NULL);
868 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
869 const char *name, *swho;
870 Manager *m = userdata;
880 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
887 who = kill_who_from_string(swho);
889 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
892 if (signo <= 0 || signo >= _NSIG)
893 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
895 session = hashmap_get(m->sessions, name);
897 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
899 r = session_kill(session, who, signo);
903 return sd_bus_reply_method_return(message, NULL);
906 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
907 Manager *m = userdata;
917 r = sd_bus_message_read(message, "ui", &uid, &signo);
921 if (signo <= 0 || signo >= _NSIG)
922 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
924 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
926 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
928 r = user_kill(user, signo);
932 return sd_bus_reply_method_return(message, NULL);
935 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
936 Manager *m = userdata;
945 r = sd_bus_message_read(message, "s", &name);
949 session = hashmap_get(m->sessions, name);
951 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
953 r = session_stop(session, true);
957 return sd_bus_reply_method_return(message, NULL);
960 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
961 Manager *m = userdata;
970 r = sd_bus_message_read(message, "u", &uid);
974 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
976 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
978 r = user_stop(user, true);
982 return sd_bus_reply_method_return(message, NULL);
985 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
986 Manager *m = userdata;
995 r = sd_bus_message_read(message, "s", &name);
999 seat = hashmap_get(m->seats, name);
1001 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
1003 r = seat_stop_sessions(seat, true);
1007 return sd_bus_reply_method_return(message, NULL);
1010 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1011 _cleanup_free_ char *cc = NULL;
1012 Manager *m = userdata;
1023 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1030 return errno ? -errno : -ENOENT;
1032 r = bus_verify_polkit_async(bus,
1033 &m->polkit_registry,
1035 "org.freedesktop.login1.set-user-linger",
1038 method_set_user_linger, m);
1042 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1044 mkdir_p_label("/var/lib/systemd", 0755);
1046 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1050 cc = cescape(pw->pw_name);
1054 path = strappenda("/var/lib/systemd/linger/", cc);
1062 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1069 if (r < 0 && errno != ENOENT)
1072 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1074 user_add_to_gc_queue(u);
1077 return sd_bus_reply_method_return(message, NULL);
1080 static int trigger_device(Manager *m, struct udev_device *d) {
1081 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1082 struct udev_list_entry *first, *item;
1087 e = udev_enumerate_new(m->udev);
1092 r = udev_enumerate_add_match_parent(e, d);
1097 r = udev_enumerate_scan_devices(e);
1101 first = udev_enumerate_get_list_entry(e);
1102 udev_list_entry_foreach(item, first) {
1103 _cleanup_free_ char *t = NULL;
1106 p = udev_list_entry_get_name(item);
1108 t = strappend(p, "/uevent");
1112 write_string_file(t, "change");
1118 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1119 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1120 _cleanup_free_ char *rule = NULL, *file = NULL;
1121 const char *id_for_seat;
1128 d = udev_device_new_from_syspath(m->udev, sysfs);
1132 if (!udev_device_has_tag(d, "seat"))
1135 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1139 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1142 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 return trigger_device(m, d);
1154 static int flush_devices(Manager *m) {
1155 _cleanup_closedir_ DIR *d;
1159 d = opendir("/etc/udev/rules.d");
1161 if (errno != ENOENT)
1162 log_warning("Failed to open /etc/udev/rules.d: %m");
1166 while ((de = readdir(d))) {
1168 if (!dirent_is_file(de))
1171 if (!startswith(de->d_name, "72-seat-"))
1174 if (!endswith(de->d_name, ".rules"))
1177 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1178 log_warning("Failed to unlink %s: %m", de->d_name);
1182 return trigger_device(m, NULL);
1185 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1186 const char *sysfs, *seat;
1187 Manager *m = userdata;
1194 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1198 if (!path_startswith(sysfs, "/sys"))
1199 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1201 if (!seat_name_is_valid(seat))
1202 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1204 r = bus_verify_polkit_async(bus,
1205 &m->polkit_registry,
1207 "org.freedesktop.login1.attach-device",
1210 method_attach_device, m);
1214 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1216 r = attach_device(m, seat, sysfs);
1220 return sd_bus_reply_method_return(message, NULL);
1223 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1224 Manager *m = userdata;
1231 r = sd_bus_message_read(message, "b", &interactive);
1235 r = bus_verify_polkit_async(bus,
1236 &m->polkit_registry,
1238 "org.freedesktop.login1.flush-devices",
1241 method_flush_devices, m);
1245 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1247 r = flush_devices(m);
1251 return sd_bus_reply_method_return(message, NULL);
1254 static int have_multiple_sessions(
1263 /* Check for other users' sessions. Greeter sessions do not
1264 * count, and non-login sessions do not count either. */
1265 HASHMAP_FOREACH(session, m->sessions, i)
1266 if (session->class == SESSION_USER &&
1267 session->user->uid != uid)
1273 static int bus_manager_log_shutdown(
1276 const char *unit_name) {
1283 if (w != INHIBIT_SHUTDOWN)
1286 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1287 p = "MESSAGE=System is powering down.";
1288 q = "SHUTDOWN=power-off";
1289 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1290 p = "MESSAGE=System is halting.";
1291 q = "SHUTDOWN=halt";
1292 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1293 p = "MESSAGE=System is rebooting.";
1294 q = "SHUTDOWN=reboot";
1295 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1296 p = "MESSAGE=System is rebooting with kexec.";
1297 q = "SHUTDOWN=kexec";
1299 p = "MESSAGE=System is shutting down.";
1303 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1308 static int execute_shutdown_or_sleep(
1311 const char *unit_name,
1312 sd_bus_error *error) {
1314 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1321 assert(w < _INHIBIT_WHAT_MAX);
1324 bus_manager_log_shutdown(m, w, unit_name);
1326 r = sd_bus_call_method(
1328 "org.freedesktop.systemd1",
1329 "/org/freedesktop/systemd1",
1330 "org.freedesktop.systemd1.Manager",
1334 "ss", unit_name, "replace-irreversibly");
1338 r = sd_bus_message_read(reply, "o", &p);
1346 m->action_unit = unit_name;
1347 free(m->action_job);
1351 /* Make sure the lid switch is ignored for a while */
1352 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
1357 static int delay_shutdown_or_sleep(
1360 const char *unit_name) {
1364 assert(w < _INHIBIT_WHAT_MAX);
1367 m->action_timestamp = now(CLOCK_MONOTONIC);
1368 m->action_unit = unit_name;
1374 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1376 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1377 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1378 [INHIBIT_SLEEP] = "PrepareForSleep"
1381 int active = _active;
1385 assert(w < _INHIBIT_WHAT_MAX);
1386 assert(signal_name[w]);
1388 return sd_bus_emit_signal(m->bus,
1389 "/org/freedesktop/login1",
1390 "org.freedesktop.login1.Manager",
1396 int bus_manager_shutdown_or_sleep_now_or_later(
1398 const char *unit_name,
1400 sd_bus_error *error) {
1408 assert(w <= _INHIBIT_WHAT_MAX);
1409 assert(!m->action_job);
1411 /* Tell everybody to prepare for shutdown/sleep */
1412 send_prepare_for(m, w, true);
1415 m->inhibit_delay_max > 0 &&
1416 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1419 /* Shutdown is delayed, keep in mind what we
1420 * want to do, and start a timeout */
1421 r = delay_shutdown_or_sleep(m, w, unit_name);
1423 /* Shutdown is not delayed, execute it
1425 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1430 static int method_do_shutdown_or_sleep(
1432 sd_bus_message *message,
1433 const char *unit_name,
1436 const char *action_multiple_sessions,
1437 const char *action_ignore_inhibit,
1438 const char *sleep_verb,
1439 sd_bus_message_handler_t method,
1440 sd_bus_error *error) {
1442 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1443 bool multiple_sessions, blocked;
1451 assert(w <= _INHIBIT_WHAT_MAX);
1453 assert(action_multiple_sessions);
1454 assert(action_ignore_inhibit);
1457 r = sd_bus_message_read(message, "b", &interactive);
1461 /* Don't allow multiple jobs being executed at the same time */
1463 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1466 r = can_sleep(sleep_verb);
1471 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1474 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1478 r = sd_bus_creds_get_uid(creds, &uid);
1482 r = have_multiple_sessions(m, uid);
1486 multiple_sessions = r > 0;
1487 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1489 if (multiple_sessions) {
1490 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1491 action_multiple_sessions, interactive, error, method, m);
1495 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1499 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1500 action_ignore_inhibit, interactive, error, method, m);
1504 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1507 if (!multiple_sessions && !blocked) {
1508 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1509 action, interactive, error, method, m);
1513 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1516 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1520 return sd_bus_reply_method_return(message, NULL);
1523 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1524 Manager *m = userdata;
1526 return method_do_shutdown_or_sleep(
1528 SPECIAL_POWEROFF_TARGET,
1530 "org.freedesktop.login1.power-off",
1531 "org.freedesktop.login1.power-off-multiple-sessions",
1532 "org.freedesktop.login1.power-off-ignore-inhibit",
1538 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1539 Manager *m = userdata;
1541 return method_do_shutdown_or_sleep(
1543 SPECIAL_REBOOT_TARGET,
1545 "org.freedesktop.login1.reboot",
1546 "org.freedesktop.login1.reboot-multiple-sessions",
1547 "org.freedesktop.login1.reboot-ignore-inhibit",
1553 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1554 Manager *m = userdata;
1556 return method_do_shutdown_or_sleep(
1558 SPECIAL_SUSPEND_TARGET,
1560 "org.freedesktop.login1.suspend",
1561 "org.freedesktop.login1.suspend-multiple-sessions",
1562 "org.freedesktop.login1.suspend-ignore-inhibit",
1568 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1569 Manager *m = userdata;
1571 return method_do_shutdown_or_sleep(
1573 SPECIAL_HIBERNATE_TARGET,
1575 "org.freedesktop.login1.hibernate",
1576 "org.freedesktop.login1.hibernate-multiple-sessions",
1577 "org.freedesktop.login1.hibernate-ignore-inhibit",
1583 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1584 Manager *m = userdata;
1586 return method_do_shutdown_or_sleep(
1588 SPECIAL_HYBRID_SLEEP_TARGET,
1590 "org.freedesktop.login1.hibernate",
1591 "org.freedesktop.login1.hibernate-multiple-sessions",
1592 "org.freedesktop.login1.hibernate-ignore-inhibit",
1594 method_hybrid_sleep,
1598 static int method_can_shutdown_or_sleep(
1600 sd_bus_message *message,
1603 const char *action_multiple_sessions,
1604 const char *action_ignore_inhibit,
1605 const char *sleep_verb,
1606 sd_bus_error *error) {
1608 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1609 bool multiple_sessions, challenge, blocked;
1610 const char *result = NULL;
1617 assert(w <= _INHIBIT_WHAT_MAX);
1619 assert(action_multiple_sessions);
1620 assert(action_ignore_inhibit);
1623 r = can_sleep(sleep_verb);
1627 return sd_bus_reply_method_return(message, "s", "na");
1630 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1634 r = sd_bus_creds_get_uid(creds, &uid);
1638 r = have_multiple_sessions(m, uid);
1642 multiple_sessions = r > 0;
1643 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1645 if (multiple_sessions) {
1646 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1653 result = "challenge";
1659 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1663 if (r > 0 && !result)
1665 else if (challenge && (!result || streq(result, "yes")))
1666 result = "challenge";
1671 if (!multiple_sessions && !blocked) {
1672 /* If neither inhibit nor multiple sessions
1673 * apply then just check the normal policy */
1675 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1682 result = "challenge";
1687 return sd_bus_reply_method_return(message, "s", result);
1690 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1691 Manager *m = userdata;
1693 return method_can_shutdown_or_sleep(
1696 "org.freedesktop.login1.power-off",
1697 "org.freedesktop.login1.power-off-multiple-sessions",
1698 "org.freedesktop.login1.power-off-ignore-inhibit",
1703 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1704 Manager *m = userdata;
1706 return method_can_shutdown_or_sleep(
1709 "org.freedesktop.login1.reboot",
1710 "org.freedesktop.login1.reboot-multiple-sessions",
1711 "org.freedesktop.login1.reboot-ignore-inhibit",
1716 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1717 Manager *m = userdata;
1719 return method_can_shutdown_or_sleep(
1722 "org.freedesktop.login1.suspend",
1723 "org.freedesktop.login1.suspend-multiple-sessions",
1724 "org.freedesktop.login1.suspend-ignore-inhibit",
1729 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1730 Manager *m = userdata;
1732 return method_can_shutdown_or_sleep(
1735 "org.freedesktop.login1.hibernate",
1736 "org.freedesktop.login1.hibernate-multiple-sessions",
1737 "org.freedesktop.login1.hibernate-ignore-inhibit",
1742 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1743 Manager *m = userdata;
1745 return method_can_shutdown_or_sleep(
1748 "org.freedesktop.login1.hibernate",
1749 "org.freedesktop.login1.hibernate-multiple-sessions",
1750 "org.freedesktop.login1.hibernate-ignore-inhibit",
1755 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1756 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1757 const char *who, *why, *what, *mode;
1758 _cleanup_free_ char *id = NULL;
1759 _cleanup_close_ int fifo_fd = -1;
1760 Manager *m = userdata;
1761 Inhibitor *i = NULL;
1772 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1776 w = inhibit_what_from_string(what);
1778 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1780 mm = inhibit_mode_from_string(mode);
1782 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1784 /* Delay is only supported for shutdown/sleep */
1785 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1786 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1788 /* Don't allow taking delay locks while we are already
1789 * executing the operation. We shouldn't create the impression
1790 * that the lock was successful if the machine is about to go
1791 * down/suspend any moment. */
1792 if (m->action_what & w)
1793 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1795 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1796 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1797 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1798 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1799 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1800 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1801 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1802 "org.freedesktop.login1.inhibit-handle-lid-switch",
1803 false, error, method_inhibit, m);
1807 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1809 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1813 r = sd_bus_creds_get_uid(creds, &uid);
1817 r = sd_bus_creds_get_pid(creds, &pid);
1825 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1828 } while (hashmap_get(m->inhibitors, id));
1830 r = manager_add_inhibitor(m, id, &i);
1838 i->why = strdup(why);
1839 i->who = strdup(who);
1841 if (!i->why || !i->who) {
1846 fifo_fd = inhibitor_create_fifo(i);
1854 return sd_bus_reply_method_return(message, "h", fifo_fd);
1863 const sd_bus_vtable manager_vtable[] = {
1864 SD_BUS_VTABLE_START(0),
1866 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1867 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1868 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1869 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1870 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1871 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1872 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1873 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1874 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1875 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1876 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1877 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1878 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1879 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1880 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1881 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1882 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1883 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1885 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1887 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1888 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1889 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1890 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1893 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1894 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1895 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1896 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1897 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1899 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1900 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1901 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1902 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1903 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1904 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1905 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1906 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1907 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1908 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1909 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1910 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1911 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1912 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1913 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1914 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1915 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1916 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1917 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1918 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1919 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1920 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1922 SD_BUS_SIGNAL("SessionNew", "so", 0),
1923 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1924 SD_BUS_SIGNAL("UserNew", "uo", 0),
1925 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1926 SD_BUS_SIGNAL("SeatNew", "so", 0),
1927 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1928 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1929 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1934 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1943 if (streq(result, "done"))
1944 r = session_send_create_reply(s, NULL);
1946 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1948 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1949 r = session_send_create_reply(s, &e);
1955 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1956 const char *path, *result, *unit;
1957 Manager *m = userdata;
1967 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1969 bus_log_parse_error(r);
1973 if (m->action_job && streq(m->action_job, path)) {
1974 log_info("Operation finished.");
1976 /* Tell people that they now may take a lock again */
1977 send_prepare_for(m, m->action_what, false);
1979 free(m->action_job);
1980 m->action_job = NULL;
1981 m->action_unit = NULL;
1986 session = hashmap_get(m->session_units, unit);
1989 if (streq_ptr(path, session->scope_job)) {
1990 free(session->scope_job);
1991 session->scope_job = NULL;
1994 session_jobs_reply(session, unit, result);
1996 session_save(session);
1997 session_add_to_gc_queue(session);
2000 user = hashmap_get(m->user_units, unit);
2003 if (streq_ptr(path, user->service_job)) {
2004 free(user->service_job);
2005 user->service_job = NULL;
2008 if (streq_ptr(path, user->slice_job)) {
2009 free(user->slice_job);
2010 user->slice_job = NULL;
2013 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2014 session_jobs_reply(session, unit, result);
2018 user_add_to_gc_queue(user);
2024 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2025 const char *path, *unit;
2026 Manager *m = userdata;
2035 r = sd_bus_message_read(message, "so", &unit, &path);
2037 bus_log_parse_error(r);
2041 session = hashmap_get(m->session_units, unit);
2043 session_add_to_gc_queue(session);
2045 user = hashmap_get(m->user_units, unit);
2047 user_add_to_gc_queue(user);
2052 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2053 _cleanup_free_ char *unit = NULL;
2054 Manager *m = userdata;
2064 path = sd_bus_message_get_path(message);
2068 r = unit_name_from_dbus_path(path, &unit);
2070 /* quietly ignore non-units paths */
2071 return r == -EINVAL ? 0 : r;
2073 session = hashmap_get(m->session_units, unit);
2075 session_add_to_gc_queue(session);
2077 user = hashmap_get(m->user_units, unit);
2079 user_add_to_gc_queue(user);
2084 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2085 Manager *m = userdata;
2092 r = sd_bus_message_read(message, "b", &b);
2094 bus_log_parse_error(r);
2101 /* systemd finished reloading, let's recheck all our sessions */
2102 log_debug("System manager has been reloaded, rechecking sessions...");
2104 HASHMAP_FOREACH(session, m->sessions, i)
2105 session_add_to_gc_queue(session);
2110 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2111 const char *name, *old, *new;
2112 Manager *m = userdata;
2120 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2122 bus_log_parse_error(r);
2126 if (isempty(old) || !isempty(new))
2129 key = set_remove(m->busnames, (char*) old);
2133 /* Drop all controllers owned by this name */
2137 HASHMAP_FOREACH(session, m->sessions, i)
2138 if (session_is_controller(session, old))
2139 session_drop_controller(session);
2144 int manager_send_changed(Manager *manager, const char *property, ...) {
2149 l = strv_from_stdarg_alloca(property);
2151 return sd_bus_emit_properties_changed_strv(
2153 "/org/freedesktop/login1",
2154 "org.freedesktop.login1.Manager",
2158 int manager_dispatch_delayed(Manager *manager) {
2159 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2160 Inhibitor *offending = NULL;
2165 if (manager->action_what == 0 || manager->action_job)
2168 /* Continue delay? */
2169 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2170 _cleanup_free_ char *comm = NULL, *u = NULL;
2172 get_process_comm(offending->pid, &comm);
2173 u = uid_to_name(offending->uid);
2175 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2178 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2179 (unsigned long) offending->uid, strna(u),
2180 (unsigned long) offending->pid, strna(comm));
2183 /* Actually do the operation */
2184 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2186 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2188 manager->action_unit = NULL;
2189 manager->action_what = 0;
2196 int manager_start_scope(
2201 const char *description,
2202 const char *after, const char *after2,
2203 sd_bus_error *error,
2206 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2213 r = sd_bus_message_new_method_call(
2216 "org.freedesktop.systemd1",
2217 "/org/freedesktop/systemd1",
2218 "org.freedesktop.systemd1.Manager",
2219 "StartTransientUnit");
2223 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2227 r = sd_bus_message_open_container(m, 'a', "(sv)");
2231 if (!isempty(slice)) {
2232 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2237 if (!isempty(description)) {
2238 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2243 if (!isempty(after)) {
2244 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2249 if (!isempty(after2)) {
2250 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2255 /* cgroup empty notification is not available in containers
2256 * currently. To make this less problematic, let's shorten the
2257 * stop timeout for sessions, so that we don't wait
2260 /* Make sure that the session shells are terminated with
2261 * SIGHUP since bash and friends tend to ignore SIGTERM */
2262 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2266 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2270 r = sd_bus_message_close_container(m);
2274 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2278 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2286 r = sd_bus_message_read(reply, "o", &j);
2300 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2301 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2307 r = sd_bus_call_method(
2309 "org.freedesktop.systemd1",
2310 "/org/freedesktop/systemd1",
2311 "org.freedesktop.systemd1.Manager",
2315 "ss", unit, "fail");
2323 r = sd_bus_message_read(reply, "o", &j);
2337 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2338 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2344 r = sd_bus_call_method(
2346 "org.freedesktop.systemd1",
2347 "/org/freedesktop/systemd1",
2348 "org.freedesktop.systemd1.Manager",
2352 "ss", unit, "fail");
2354 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2355 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2360 sd_bus_error_free(error);
2371 r = sd_bus_message_read(reply, "o", &j);
2385 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2386 _cleanup_free_ char *path = NULL;
2392 path = unit_dbus_path_from_name(scope);
2396 r = sd_bus_call_method(
2398 "org.freedesktop.systemd1",
2400 "org.freedesktop.systemd1.Scope",
2406 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2407 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2408 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2409 sd_bus_error_free(error);
2419 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2423 return sd_bus_call_method(
2425 "org.freedesktop.systemd1",
2426 "/org/freedesktop/systemd1",
2427 "org.freedesktop.systemd1.Manager",
2431 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2434 int manager_unit_is_active(Manager *manager, const char *unit) {
2435 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2436 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2437 _cleanup_free_ char *path = NULL;
2444 path = unit_dbus_path_from_name(unit);
2448 r = sd_bus_get_property(
2450 "org.freedesktop.systemd1",
2452 "org.freedesktop.systemd1.Unit",
2458 /* systemd might have droppped off momentarily, let's
2459 * not make this an error */
2460 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2461 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2464 /* If the unit is already unloaded then it's not
2466 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2467 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2473 r = sd_bus_message_read(reply, "s", &state);
2477 return !streq(state, "inactive") && !streq(state, "failed");
2480 int manager_job_is_active(Manager *manager, const char *path) {
2481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2482 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2488 r = sd_bus_get_property(
2490 "org.freedesktop.systemd1",
2492 "org.freedesktop.systemd1.Job",
2498 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2499 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2502 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2508 /* We don't actually care about the state really. The fact
2509 * that we could read the job state is enough for us */