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"
42 #include "bus-common-errors.h"
43 #include "udev-util.h"
44 #include "selinux-util.h"
47 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
48 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
61 r = sd_bus_creds_get_session(creds, &name);
66 session = hashmap_get(m->sessions, name);
68 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
74 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
82 if (uid == UID_INVALID) {
83 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
85 /* Note that we get the owner UID of the session, not the actual client UID here! */
86 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
90 r = sd_bus_creds_get_owner_uid(creds, &uid);
95 user = hashmap_get(m->users, UID_TO_PTR(uid));
97 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
103 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
114 r = manager_get_session_from_creds(m, message, NULL, error, &session);
118 seat = session->seat;
121 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
123 seat = hashmap_get(m->seats, name);
125 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
132 static int property_get_idle_hint(
135 const char *interface,
136 const char *property,
137 sd_bus_message *reply,
139 sd_bus_error *error) {
141 Manager *m = userdata;
147 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
150 static int property_get_idle_since_hint(
153 const char *interface,
154 const char *property,
155 sd_bus_message *reply,
157 sd_bus_error *error) {
159 Manager *m = userdata;
166 manager_get_idle_hint(m, &t);
168 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
171 static int property_get_inhibited(
174 const char *interface,
175 const char *property,
176 sd_bus_message *reply,
178 sd_bus_error *error) {
180 Manager *m = userdata;
187 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
189 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
192 static int property_get_preparing(
195 const char *interface,
196 const char *property,
197 sd_bus_message *reply,
199 sd_bus_error *error) {
201 Manager *m = userdata;
208 if (streq(property, "PreparingForShutdown"))
209 b = !!(m->action_what & INHIBIT_SHUTDOWN);
211 b = !!(m->action_what & INHIBIT_SLEEP);
213 return sd_bus_message_append(reply, "b", b);
216 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
218 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
219 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
220 _cleanup_free_ char *p = NULL;
221 Manager *m = userdata;
230 r = sd_bus_message_read(message, "s", &name);
234 r = manager_get_session_from_creds(m, message, name, error, &session);
238 p = session_bus_path(session);
242 return sd_bus_reply_method_return(message, "o", p);
245 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
246 _cleanup_free_ char *p = NULL;
247 Session *session = NULL;
248 Manager *m = userdata;
256 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
258 r = sd_bus_message_read(message, "u", &pid);
263 r = manager_get_session_from_creds(m, message, NULL, error, &session);
267 r = manager_get_session_by_pid(m, pid, &session);
272 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
275 p = session_bus_path(session);
279 return sd_bus_reply_method_return(message, "o", p);
282 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
283 _cleanup_free_ char *p = NULL;
284 Manager *m = userdata;
293 r = sd_bus_message_read(message, "u", &uid);
297 r = manager_get_user_from_creds(m, message, uid, error, &user);
301 p = user_bus_path(user);
305 return sd_bus_reply_method_return(message, "o", p);
308 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
309 _cleanup_free_ char *p = NULL;
310 Manager *m = userdata;
319 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
321 r = sd_bus_message_read(message, "u", &pid);
326 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
330 r = manager_get_user_by_pid(m, pid, &user);
334 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
337 p = user_bus_path(user);
341 return sd_bus_reply_method_return(message, "o", p);
344 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
345 _cleanup_free_ char *p = NULL;
346 Manager *m = userdata;
355 r = sd_bus_message_read(message, "s", &name);
359 r = manager_get_seat_from_creds(m, message, name, error, &seat);
363 p = seat_bus_path(seat);
367 return sd_bus_reply_method_return(message, "o", p);
370 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
371 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
372 Manager *m = userdata;
381 r = sd_bus_message_new_method_return(message, &reply);
385 r = sd_bus_message_open_container(reply, 'a', "(susso)");
389 HASHMAP_FOREACH(session, m->sessions, i) {
390 _cleanup_free_ char *p = NULL;
392 p = session_bus_path(session);
396 r = sd_bus_message_append(reply, "(susso)",
398 (uint32_t) session->user->uid,
400 session->seat ? session->seat->id : "",
406 r = sd_bus_message_close_container(reply);
410 return sd_bus_send(bus, reply, NULL);
413 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
414 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
415 Manager *m = userdata;
424 r = sd_bus_message_new_method_return(message, &reply);
428 r = sd_bus_message_open_container(reply, 'a', "(uso)");
432 HASHMAP_FOREACH(user, m->users, i) {
433 _cleanup_free_ char *p = NULL;
435 p = user_bus_path(user);
439 r = sd_bus_message_append(reply, "(uso)",
440 (uint32_t) user->uid,
447 r = sd_bus_message_close_container(reply);
451 return sd_bus_send(bus, reply, NULL);
454 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
455 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
456 Manager *m = userdata;
465 r = sd_bus_message_new_method_return(message, &reply);
469 r = sd_bus_message_open_container(reply, 'a', "(so)");
473 HASHMAP_FOREACH(seat, m->seats, i) {
474 _cleanup_free_ char *p = NULL;
476 p = seat_bus_path(seat);
480 r = sd_bus_message_append(reply, "(so)", seat->id, p);
485 r = sd_bus_message_close_container(reply);
489 return sd_bus_send(bus, reply, NULL);
492 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 Manager *m = userdata;
495 Inhibitor *inhibitor;
499 r = sd_bus_message_new_method_return(message, &reply);
503 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
507 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
509 r = sd_bus_message_append(reply, "(ssssuu)",
510 strempty(inhibit_what_to_string(inhibitor->what)),
511 strempty(inhibitor->who),
512 strempty(inhibitor->why),
513 strempty(inhibit_mode_to_string(inhibitor->mode)),
514 (uint32_t) inhibitor->uid,
515 (uint32_t) inhibitor->pid);
520 r = sd_bus_message_close_container(reply);
524 return sd_bus_send(bus, reply, NULL);
527 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
528 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
529 uint32_t uid, leader, audit_id = 0;
530 _cleanup_free_ char *id = NULL;
531 Session *session = NULL;
532 Manager *m = userdata;
545 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
550 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
553 t = _SESSION_TYPE_INVALID;
555 t = session_type_from_string(type);
557 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
561 c = _SESSION_CLASS_INVALID;
563 c = session_class_from_string(class);
565 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
568 if (isempty(desktop))
571 if (!string_is_safe(desktop))
572 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
578 seat = hashmap_get(m->seats, cseat);
580 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
583 if (tty_is_vc(tty)) {
588 else if (seat != m->seat0)
589 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);
591 v = vtnr_from_tty(tty);
593 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
597 else if (vtnr != (uint32_t) v)
598 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
600 } else if (tty_is_console(tty)) {
604 else if (seat != m->seat0)
605 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
608 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
612 if (seat_has_vts(seat)) {
613 if (!vtnr || vtnr > 63)
614 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
617 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
621 r = sd_bus_message_enter_container(message, 'a', "(sv)");
625 if (t == _SESSION_TYPE_INVALID) {
626 if (!isempty(display))
628 else if (!isempty(tty))
631 t = SESSION_UNSPECIFIED;
634 if (c == _SESSION_CLASS_INVALID) {
635 if (t == SESSION_UNSPECIFIED)
636 c = SESSION_BACKGROUND;
642 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
644 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
648 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
653 manager_get_session_by_pid(m, leader, &session);
655 _cleanup_free_ char *path = NULL;
656 _cleanup_close_ int fifo_fd = -1;
658 /* Session already exists, client is probably
659 * something like "su" which changes uid but is still
660 * the same session */
662 fifo_fd = session_create_fifo(session);
666 path = session_bus_path(session);
670 log_debug("Sending reply about an existing session: "
671 "id=%s object_path=%s uid=%u runtime_path=%s "
672 "session_fd=%d seat=%s vtnr=%u",
675 (uint32_t) session->user->uid,
676 session->user->runtime_path,
678 session->seat ? session->seat->id : "",
679 (uint32_t) session->vtnr);
681 return sd_bus_reply_method_return(
685 session->user->runtime_path,
687 (uint32_t) session->user->uid,
688 session->seat ? session->seat->id : "",
689 (uint32_t) session->vtnr,
693 audit_session_from_pid(leader, &audit_id);
695 /* Keep our session IDs and the audit session IDs in sync */
697 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
700 /* Wut? There's already a session by this name and we
701 * didn't find it above? Weird, then let's not trust
702 * the audit data and let's better register a new
704 if (hashmap_get(m->sessions, id)) {
705 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
718 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
721 } while (hashmap_get(m->sessions, id));
724 r = manager_add_user_by_uid(m, uid, &user);
728 r = manager_add_session(m, id, &session);
732 session_set_user(session, user);
734 session->leader = leader;
735 session->audit_id = audit_id;
738 session->remote = remote;
739 session->vtnr = vtnr;
742 session->tty = strdup(tty);
749 if (!isempty(display)) {
750 session->display = strdup(display);
751 if (!session->display) {
757 if (!isempty(remote_user)) {
758 session->remote_user = strdup(remote_user);
759 if (!session->remote_user) {
765 if (!isempty(remote_host)) {
766 session->remote_host = strdup(remote_host);
767 if (!session->remote_host) {
773 if (!isempty(service)) {
774 session->service = strdup(service);
775 if (!session->service) {
781 if (!isempty(desktop)) {
782 session->desktop = strdup(desktop);
783 if (!session->desktop) {
790 r = seat_attach_session(seat, session);
795 r = session_start(session);
799 session->create_message = sd_bus_message_ref(message);
801 /* Now, let's wait until the slice unit and stuff got
802 * created. We send the reply back from
803 * session_send_create_reply(). */
809 session_add_to_gc_queue(session);
812 user_add_to_gc_queue(user);
817 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
818 Manager *m = userdata;
827 r = sd_bus_message_read(message, "s", &name);
831 r = manager_get_session_from_creds(m, message, name, error, &session);
835 session_release(session);
837 return sd_bus_reply_method_return(message, NULL);
840 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
841 Manager *m = userdata;
850 r = sd_bus_message_read(message, "s", &name);
854 r = manager_get_session_from_creds(m, message, name, error, &session);
858 r = session_activate(session);
862 return sd_bus_reply_method_return(message, NULL);
865 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
866 const char *session_name, *seat_name;
867 Manager *m = userdata;
876 /* Same as ActivateSession() but refuses to work if
877 * the seat doesn't match */
879 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
883 r = manager_get_session_from_creds(m, message, session_name, error, &session);
887 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
891 if (session->seat != seat)
892 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
894 r = session_activate(session);
898 return sd_bus_reply_method_return(message, NULL);
901 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
902 Manager *m = userdata;
911 r = sd_bus_message_read(message, "s", &name);
915 r = manager_get_session_from_creds(m, message, name, error, &session);
919 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
923 return sd_bus_reply_method_return(message, NULL);
926 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
927 Manager *m = userdata;
934 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
938 return sd_bus_reply_method_return(message, NULL);
941 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
942 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
943 const char *name, *swho;
944 Manager *m = userdata;
954 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
961 who = kill_who_from_string(swho);
963 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
966 if (signo <= 0 || signo >= _NSIG)
967 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
969 r = manager_get_session_from_creds(m, message, name, error, &session);
973 r = session_kill(session, who, signo);
977 return sd_bus_reply_method_return(message, NULL);
980 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
981 Manager *m = userdata;
991 r = sd_bus_message_read(message, "ui", &uid, &signo);
995 if (signo <= 0 || signo >= _NSIG)
996 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
998 r = manager_get_user_from_creds(m, message, uid, error, &user);
1002 r = user_kill(user, signo);
1006 return sd_bus_reply_method_return(message, NULL);
1009 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1010 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1011 Manager *m = userdata;
1020 r = sd_bus_message_read(message, "s", &name);
1024 r = manager_get_session_from_creds(m, message, name, error, &session);
1028 r = session_stop(session, true);
1032 return sd_bus_reply_method_return(message, NULL);
1035 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1036 Manager *m = userdata;
1045 r = sd_bus_message_read(message, "u", &uid);
1049 r = manager_get_user_from_creds(m, message, uid, error, &user);
1053 r = user_stop(user, true);
1057 return sd_bus_reply_method_return(message, NULL);
1060 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1061 Manager *m = userdata;
1070 r = sd_bus_message_read(message, "s", &name);
1074 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1078 r = seat_stop_sessions(seat, true);
1082 return sd_bus_reply_method_return(message, NULL);
1085 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1086 _cleanup_free_ char *cc = NULL;
1087 Manager *m = userdata;
1098 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1102 if (uid == UID_INVALID) {
1103 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1105 /* Note that we get the owner UID of the session, not the actual client UID here! */
1106 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1110 r = sd_bus_creds_get_owner_uid(creds, &uid);
1118 return errno ? -errno : -ENOENT;
1120 r = bus_verify_polkit_async(
1123 "org.freedesktop.login1.set-user-linger",
1125 &m->polkit_registry,
1130 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1132 mkdir_p_label("/var/lib/systemd", 0755);
1134 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1138 cc = cescape(pw->pw_name);
1142 path = strappenda("/var/lib/systemd/linger/", cc);
1150 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1157 if (r < 0 && errno != ENOENT)
1160 u = hashmap_get(m->users, UID_TO_PTR(uid));
1162 user_add_to_gc_queue(u);
1165 return sd_bus_reply_method_return(message, NULL);
1168 static int trigger_device(Manager *m, struct udev_device *d) {
1169 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1170 struct udev_list_entry *first, *item;
1175 e = udev_enumerate_new(m->udev);
1180 r = udev_enumerate_add_match_parent(e, d);
1185 r = udev_enumerate_scan_devices(e);
1189 first = udev_enumerate_get_list_entry(e);
1190 udev_list_entry_foreach(item, first) {
1191 _cleanup_free_ char *t = NULL;
1194 p = udev_list_entry_get_name(item);
1196 t = strappend(p, "/uevent");
1200 write_string_file(t, "change");
1206 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1207 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1208 _cleanup_free_ char *rule = NULL, *file = NULL;
1209 const char *id_for_seat;
1216 d = udev_device_new_from_syspath(m->udev, sysfs);
1220 if (!udev_device_has_tag(d, "seat"))
1223 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1227 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1230 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1233 mkdir_p_label("/etc/udev/rules.d", 0755);
1234 mac_selinux_init("/etc");
1235 r = write_string_file_atomic_label(file, rule);
1239 return trigger_device(m, d);
1242 static int flush_devices(Manager *m) {
1243 _cleanup_closedir_ DIR *d;
1247 d = opendir("/etc/udev/rules.d");
1249 if (errno != ENOENT)
1250 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1254 while ((de = readdir(d))) {
1256 if (!dirent_is_file(de))
1259 if (!startswith(de->d_name, "72-seat-"))
1262 if (!endswith(de->d_name, ".rules"))
1265 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1266 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1270 return trigger_device(m, NULL);
1273 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1274 const char *sysfs, *seat;
1275 Manager *m = userdata;
1282 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1286 if (!path_startswith(sysfs, "/sys"))
1287 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1289 if (!seat_name_is_valid(seat))
1290 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1292 r = bus_verify_polkit_async(
1295 "org.freedesktop.login1.attach-device",
1297 &m->polkit_registry,
1302 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1304 r = attach_device(m, seat, sysfs);
1308 return sd_bus_reply_method_return(message, NULL);
1311 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1312 Manager *m = userdata;
1319 r = sd_bus_message_read(message, "b", &interactive);
1323 r = bus_verify_polkit_async(
1326 "org.freedesktop.login1.flush-devices",
1328 &m->polkit_registry,
1333 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1335 r = flush_devices(m);
1339 return sd_bus_reply_method_return(message, NULL);
1342 static int have_multiple_sessions(
1351 /* Check for other users' sessions. Greeter sessions do not
1352 * count, and non-login sessions do not count either. */
1353 HASHMAP_FOREACH(session, m->sessions, i)
1354 if (session->class == SESSION_USER &&
1355 session->user->uid != uid)
1361 static int bus_manager_log_shutdown(
1364 const char *unit_name) {
1371 if (w != INHIBIT_SHUTDOWN)
1374 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1375 p = "MESSAGE=System is powering down.";
1376 q = "SHUTDOWN=power-off";
1377 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1378 p = "MESSAGE=System is halting.";
1379 q = "SHUTDOWN=halt";
1380 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1381 p = "MESSAGE=System is rebooting.";
1382 q = "SHUTDOWN=reboot";
1383 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1384 p = "MESSAGE=System is rebooting with kexec.";
1385 q = "SHUTDOWN=kexec";
1387 p = "MESSAGE=System is shutting down.";
1391 return log_struct(LOG_NOTICE,
1392 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1398 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1399 Manager *m = userdata;
1404 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1408 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1413 if (until <= now(CLOCK_MONOTONIC))
1416 /* We want to ignore the lid switch for a while after each
1417 * suspend, and after boot-up. Hence let's install a timer for
1418 * this. As long as the event source exists we ignore the lid
1421 if (m->lid_switch_ignore_event_source) {
1424 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1431 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1433 r = sd_event_add_time(
1435 &m->lid_switch_ignore_event_source,
1438 lid_switch_ignore_handler, m);
1443 static int execute_shutdown_or_sleep(
1446 const char *unit_name,
1447 sd_bus_error *error) {
1449 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1456 assert(w < _INHIBIT_WHAT_MAX);
1459 bus_manager_log_shutdown(m, w, unit_name);
1461 r = sd_bus_call_method(
1463 "org.freedesktop.systemd1",
1464 "/org/freedesktop/systemd1",
1465 "org.freedesktop.systemd1.Manager",
1469 "ss", unit_name, "replace-irreversibly");
1473 r = sd_bus_message_read(reply, "o", &p);
1481 m->action_unit = unit_name;
1482 free(m->action_job);
1486 /* Make sure the lid switch is ignored for a while */
1487 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
1492 static int delay_shutdown_or_sleep(
1495 const char *unit_name) {
1499 assert(w < _INHIBIT_WHAT_MAX);
1502 m->action_timestamp = now(CLOCK_MONOTONIC);
1503 m->action_unit = unit_name;
1509 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1511 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1512 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1513 [INHIBIT_SLEEP] = "PrepareForSleep"
1516 int active = _active;
1520 assert(w < _INHIBIT_WHAT_MAX);
1521 assert(signal_name[w]);
1523 return sd_bus_emit_signal(m->bus,
1524 "/org/freedesktop/login1",
1525 "org.freedesktop.login1.Manager",
1531 int bus_manager_shutdown_or_sleep_now_or_later(
1533 const char *unit_name,
1535 sd_bus_error *error) {
1543 assert(w <= _INHIBIT_WHAT_MAX);
1544 assert(!m->action_job);
1546 /* Tell everybody to prepare for shutdown/sleep */
1547 send_prepare_for(m, w, true);
1550 m->inhibit_delay_max > 0 &&
1551 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1554 /* Shutdown is delayed, keep in mind what we
1555 * want to do, and start a timeout */
1556 r = delay_shutdown_or_sleep(m, w, unit_name);
1558 /* Shutdown is not delayed, execute it
1560 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1565 static int method_do_shutdown_or_sleep(
1567 sd_bus_message *message,
1568 const char *unit_name,
1571 const char *action_multiple_sessions,
1572 const char *action_ignore_inhibit,
1573 const char *sleep_verb,
1574 sd_bus_message_handler_t method,
1575 sd_bus_error *error) {
1577 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1578 bool multiple_sessions, blocked;
1586 assert(w <= _INHIBIT_WHAT_MAX);
1588 assert(action_multiple_sessions);
1589 assert(action_ignore_inhibit);
1592 r = sd_bus_message_read(message, "b", &interactive);
1596 /* Don't allow multiple jobs being executed at the same time */
1598 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1601 r = can_sleep(sleep_verb);
1606 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1609 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1613 r = sd_bus_creds_get_euid(creds, &uid);
1617 r = have_multiple_sessions(m, uid);
1621 multiple_sessions = r > 0;
1622 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1624 if (multiple_sessions) {
1625 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
1629 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1633 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
1637 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1640 if (!multiple_sessions && !blocked) {
1641 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
1645 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1648 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1652 return sd_bus_reply_method_return(message, NULL);
1655 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1656 Manager *m = userdata;
1658 return method_do_shutdown_or_sleep(
1660 SPECIAL_POWEROFF_TARGET,
1662 "org.freedesktop.login1.power-off",
1663 "org.freedesktop.login1.power-off-multiple-sessions",
1664 "org.freedesktop.login1.power-off-ignore-inhibit",
1670 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1671 Manager *m = userdata;
1673 return method_do_shutdown_or_sleep(
1675 SPECIAL_REBOOT_TARGET,
1677 "org.freedesktop.login1.reboot",
1678 "org.freedesktop.login1.reboot-multiple-sessions",
1679 "org.freedesktop.login1.reboot-ignore-inhibit",
1685 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1686 Manager *m = userdata;
1688 return method_do_shutdown_or_sleep(
1690 SPECIAL_SUSPEND_TARGET,
1692 "org.freedesktop.login1.suspend",
1693 "org.freedesktop.login1.suspend-multiple-sessions",
1694 "org.freedesktop.login1.suspend-ignore-inhibit",
1700 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1701 Manager *m = userdata;
1703 return method_do_shutdown_or_sleep(
1705 SPECIAL_HIBERNATE_TARGET,
1707 "org.freedesktop.login1.hibernate",
1708 "org.freedesktop.login1.hibernate-multiple-sessions",
1709 "org.freedesktop.login1.hibernate-ignore-inhibit",
1715 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1716 Manager *m = userdata;
1718 return method_do_shutdown_or_sleep(
1720 SPECIAL_HYBRID_SLEEP_TARGET,
1722 "org.freedesktop.login1.hibernate",
1723 "org.freedesktop.login1.hibernate-multiple-sessions",
1724 "org.freedesktop.login1.hibernate-ignore-inhibit",
1726 method_hybrid_sleep,
1730 static int method_can_shutdown_or_sleep(
1732 sd_bus_message *message,
1735 const char *action_multiple_sessions,
1736 const char *action_ignore_inhibit,
1737 const char *sleep_verb,
1738 sd_bus_error *error) {
1740 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1741 bool multiple_sessions, challenge, blocked;
1742 const char *result = NULL;
1749 assert(w <= _INHIBIT_WHAT_MAX);
1751 assert(action_multiple_sessions);
1752 assert(action_ignore_inhibit);
1755 r = can_sleep(sleep_verb);
1759 return sd_bus_reply_method_return(message, "s", "na");
1762 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1766 r = sd_bus_creds_get_euid(creds, &uid);
1770 r = have_multiple_sessions(m, uid);
1774 multiple_sessions = r > 0;
1775 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1777 if (multiple_sessions) {
1778 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
1785 result = "challenge";
1791 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
1795 if (r > 0 && !result)
1797 else if (challenge && (!result || streq(result, "yes")))
1798 result = "challenge";
1803 if (!multiple_sessions && !blocked) {
1804 /* If neither inhibit nor multiple sessions
1805 * apply then just check the normal policy */
1807 r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error);
1814 result = "challenge";
1819 return sd_bus_reply_method_return(message, "s", result);
1822 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1823 Manager *m = userdata;
1825 return method_can_shutdown_or_sleep(
1828 "org.freedesktop.login1.power-off",
1829 "org.freedesktop.login1.power-off-multiple-sessions",
1830 "org.freedesktop.login1.power-off-ignore-inhibit",
1835 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1836 Manager *m = userdata;
1838 return method_can_shutdown_or_sleep(
1841 "org.freedesktop.login1.reboot",
1842 "org.freedesktop.login1.reboot-multiple-sessions",
1843 "org.freedesktop.login1.reboot-ignore-inhibit",
1848 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1849 Manager *m = userdata;
1851 return method_can_shutdown_or_sleep(
1854 "org.freedesktop.login1.suspend",
1855 "org.freedesktop.login1.suspend-multiple-sessions",
1856 "org.freedesktop.login1.suspend-ignore-inhibit",
1861 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1862 Manager *m = userdata;
1864 return method_can_shutdown_or_sleep(
1867 "org.freedesktop.login1.hibernate",
1868 "org.freedesktop.login1.hibernate-multiple-sessions",
1869 "org.freedesktop.login1.hibernate-ignore-inhibit",
1874 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1875 Manager *m = userdata;
1877 return method_can_shutdown_or_sleep(
1880 "org.freedesktop.login1.hibernate",
1881 "org.freedesktop.login1.hibernate-multiple-sessions",
1882 "org.freedesktop.login1.hibernate-ignore-inhibit",
1887 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1888 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1889 const char *who, *why, *what, *mode;
1890 _cleanup_free_ char *id = NULL;
1891 _cleanup_close_ int fifo_fd = -1;
1892 Manager *m = userdata;
1893 Inhibitor *i = NULL;
1904 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1908 w = inhibit_what_from_string(what);
1910 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1912 mm = inhibit_mode_from_string(mode);
1914 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1916 /* Delay is only supported for shutdown/sleep */
1917 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1918 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1920 /* Don't allow taking delay locks while we are already
1921 * executing the operation. We shouldn't create the impression
1922 * that the lock was successful if the machine is about to go
1923 * down/suspend any moment. */
1924 if (m->action_what & w)
1925 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1927 r = bus_verify_polkit_async(message, CAP_SYS_BOOT,
1928 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1929 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1930 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1931 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1932 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1933 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1934 "org.freedesktop.login1.inhibit-handle-lid-switch",
1935 false, &m->polkit_registry, error);
1939 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1941 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
1945 r = sd_bus_creds_get_euid(creds, &uid);
1949 r = sd_bus_creds_get_pid(creds, &pid);
1957 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1960 } while (hashmap_get(m->inhibitors, id));
1962 r = manager_add_inhibitor(m, id, &i);
1970 i->why = strdup(why);
1971 i->who = strdup(who);
1973 if (!i->why || !i->who) {
1978 fifo_fd = inhibitor_create_fifo(i);
1986 return sd_bus_reply_method_return(message, "h", fifo_fd);
1995 const sd_bus_vtable manager_vtable[] = {
1996 SD_BUS_VTABLE_START(0),
1998 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1999 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2000 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2001 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2002 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2003 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2004 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2005 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2006 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2007 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2008 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2009 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2010 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2011 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2012 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2013 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2014 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2015 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2016 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2018 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2020 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2022 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2023 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2024 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2025 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2026 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2027 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2028 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2029 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2030 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2031 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
2032 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
2033 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
2034 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
2035 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2036 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2037 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2038 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2039 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2040 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2041 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2042 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2043 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2044 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2045 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2046 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2047 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2048 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2049 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2050 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2051 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2052 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2053 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2055 SD_BUS_SIGNAL("SessionNew", "so", 0),
2056 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2057 SD_BUS_SIGNAL("UserNew", "uo", 0),
2058 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2059 SD_BUS_SIGNAL("SeatNew", "so", 0),
2060 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2061 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2062 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2067 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2076 if (streq(result, "done"))
2077 r = session_send_create_reply(s, NULL);
2079 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2081 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2082 r = session_send_create_reply(s, &e);
2088 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2089 const char *path, *result, *unit;
2090 Manager *m = userdata;
2100 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2102 bus_log_parse_error(r);
2106 if (m->action_job && streq(m->action_job, path)) {
2107 log_info("Operation finished.");
2109 /* Tell people that they now may take a lock again */
2110 send_prepare_for(m, m->action_what, false);
2112 free(m->action_job);
2113 m->action_job = NULL;
2114 m->action_unit = NULL;
2119 session = hashmap_get(m->session_units, unit);
2122 if (streq_ptr(path, session->scope_job)) {
2123 free(session->scope_job);
2124 session->scope_job = NULL;
2127 session_jobs_reply(session, unit, result);
2129 session_save(session);
2130 session_add_to_gc_queue(session);
2133 user = hashmap_get(m->user_units, unit);
2136 if (streq_ptr(path, user->service_job)) {
2137 free(user->service_job);
2138 user->service_job = NULL;
2141 if (streq_ptr(path, user->slice_job)) {
2142 free(user->slice_job);
2143 user->slice_job = NULL;
2146 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2147 session_jobs_reply(session, unit, result);
2151 user_add_to_gc_queue(user);
2157 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2158 const char *path, *unit;
2159 Manager *m = userdata;
2168 r = sd_bus_message_read(message, "so", &unit, &path);
2170 bus_log_parse_error(r);
2174 session = hashmap_get(m->session_units, unit);
2176 session_add_to_gc_queue(session);
2178 user = hashmap_get(m->user_units, unit);
2180 user_add_to_gc_queue(user);
2185 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2186 _cleanup_free_ char *unit = NULL;
2187 Manager *m = userdata;
2197 path = sd_bus_message_get_path(message);
2201 r = unit_name_from_dbus_path(path, &unit);
2202 if (r == -EINVAL) /* not a unit */
2207 session = hashmap_get(m->session_units, unit);
2209 session_add_to_gc_queue(session);
2211 user = hashmap_get(m->user_units, unit);
2213 user_add_to_gc_queue(user);
2218 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2219 Manager *m = userdata;
2226 r = sd_bus_message_read(message, "b", &b);
2228 bus_log_parse_error(r);
2235 /* systemd finished reloading, let's recheck all our sessions */
2236 log_debug("System manager has been reloaded, rechecking sessions...");
2238 HASHMAP_FOREACH(session, m->sessions, i)
2239 session_add_to_gc_queue(session);
2244 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2245 const char *name, *old, *new;
2246 Manager *m = userdata;
2254 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2256 bus_log_parse_error(r);
2260 if (isempty(old) || !isempty(new))
2263 key = set_remove(m->busnames, (char*) old);
2267 /* Drop all controllers owned by this name */
2271 HASHMAP_FOREACH(session, m->sessions, i)
2272 if (session_is_controller(session, old))
2273 session_drop_controller(session);
2278 int manager_send_changed(Manager *manager, const char *property, ...) {
2283 l = strv_from_stdarg_alloca(property);
2285 return sd_bus_emit_properties_changed_strv(
2287 "/org/freedesktop/login1",
2288 "org.freedesktop.login1.Manager",
2292 int manager_dispatch_delayed(Manager *manager) {
2293 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2294 Inhibitor *offending = NULL;
2299 if (manager->action_what == 0 || manager->action_job)
2302 /* Continue delay? */
2303 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2304 _cleanup_free_ char *comm = NULL, *u = NULL;
2306 get_process_comm(offending->pid, &comm);
2307 u = uid_to_name(offending->uid);
2309 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2312 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2313 offending->uid, strna(u),
2314 offending->pid, strna(comm));
2317 /* Actually do the operation */
2318 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2320 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2322 manager->action_unit = NULL;
2323 manager->action_what = 0;
2330 int manager_start_scope(
2335 const char *description,
2336 const char *after, const char *after2,
2337 sd_bus_error *error,
2340 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2347 r = sd_bus_message_new_method_call(
2350 "org.freedesktop.systemd1",
2351 "/org/freedesktop/systemd1",
2352 "org.freedesktop.systemd1.Manager",
2353 "StartTransientUnit");
2357 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2361 r = sd_bus_message_open_container(m, 'a', "(sv)");
2365 if (!isempty(slice)) {
2366 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2371 if (!isempty(description)) {
2372 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2377 if (!isempty(after)) {
2378 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2383 if (!isempty(after2)) {
2384 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2389 /* cgroup empty notification is not available in containers
2390 * currently. To make this less problematic, let's shorten the
2391 * stop timeout for sessions, so that we don't wait
2394 /* Make sure that the session shells are terminated with
2395 * SIGHUP since bash and friends tend to ignore SIGTERM */
2396 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2400 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2404 r = sd_bus_message_close_container(m);
2408 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2412 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2420 r = sd_bus_message_read(reply, "o", &j);
2434 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2435 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2441 r = sd_bus_call_method(
2443 "org.freedesktop.systemd1",
2444 "/org/freedesktop/systemd1",
2445 "org.freedesktop.systemd1.Manager",
2449 "ss", unit, "fail");
2457 r = sd_bus_message_read(reply, "o", &j);
2471 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2472 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2478 r = sd_bus_call_method(
2480 "org.freedesktop.systemd1",
2481 "/org/freedesktop/systemd1",
2482 "org.freedesktop.systemd1.Manager",
2486 "ss", unit, "fail");
2488 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2489 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2494 sd_bus_error_free(error);
2505 r = sd_bus_message_read(reply, "o", &j);
2519 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2520 _cleanup_free_ char *path = NULL;
2526 path = unit_dbus_path_from_name(scope);
2530 r = sd_bus_call_method(
2532 "org.freedesktop.systemd1",
2534 "org.freedesktop.systemd1.Scope",
2540 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2541 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2542 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2543 sd_bus_error_free(error);
2553 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2557 return sd_bus_call_method(
2559 "org.freedesktop.systemd1",
2560 "/org/freedesktop/systemd1",
2561 "org.freedesktop.systemd1.Manager",
2565 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2568 int manager_unit_is_active(Manager *manager, const char *unit) {
2569 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2570 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2571 _cleanup_free_ char *path = NULL;
2578 path = unit_dbus_path_from_name(unit);
2582 r = sd_bus_get_property(
2584 "org.freedesktop.systemd1",
2586 "org.freedesktop.systemd1.Unit",
2592 /* systemd might have droppped off momentarily, let's
2593 * not make this an error */
2594 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2595 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2598 /* If the unit is already unloaded then it's not
2600 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2601 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2607 r = sd_bus_message_read(reply, "s", &state);
2611 return !streq(state, "inactive") && !streq(state, "failed");
2614 int manager_job_is_active(Manager *manager, const char *path) {
2615 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2616 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2622 r = sd_bus_get_property(
2624 "org.freedesktop.systemd1",
2626 "org.freedesktop.systemd1.Job",
2632 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2633 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2636 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2642 /* We don't actually care about the state really. The fact
2643 * that we could read the job state is enough for us */