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_free_ char *p = NULL;
220 Manager *m = userdata;
229 r = sd_bus_message_read(message, "s", &name);
233 r = manager_get_session_from_creds(m, message, name, error, &session);
237 p = session_bus_path(session);
241 return sd_bus_reply_method_return(message, "o", p);
244 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
245 _cleanup_free_ char *p = NULL;
246 Session *session = NULL;
247 Manager *m = userdata;
255 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
257 r = sd_bus_message_read(message, "u", &pid);
262 r = manager_get_session_from_creds(m, message, NULL, error, &session);
266 r = manager_get_session_by_pid(m, pid, &session);
271 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
274 p = session_bus_path(session);
278 return sd_bus_reply_method_return(message, "o", p);
281 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
282 _cleanup_free_ char *p = NULL;
283 Manager *m = userdata;
292 r = sd_bus_message_read(message, "u", &uid);
296 r = manager_get_user_from_creds(m, message, uid, error, &user);
300 p = user_bus_path(user);
304 return sd_bus_reply_method_return(message, "o", p);
307 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
308 _cleanup_free_ char *p = NULL;
309 Manager *m = userdata;
318 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
320 r = sd_bus_message_read(message, "u", &pid);
325 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
329 r = manager_get_user_by_pid(m, pid, &user);
333 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);
336 p = user_bus_path(user);
340 return sd_bus_reply_method_return(message, "o", p);
343 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
344 _cleanup_free_ char *p = NULL;
345 Manager *m = userdata;
354 r = sd_bus_message_read(message, "s", &name);
358 r = manager_get_seat_from_creds(m, message, name, error, &seat);
362 p = seat_bus_path(seat);
366 return sd_bus_reply_method_return(message, "o", p);
369 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
371 Manager *m = userdata;
380 r = sd_bus_message_new_method_return(message, &reply);
384 r = sd_bus_message_open_container(reply, 'a', "(susso)");
388 HASHMAP_FOREACH(session, m->sessions, i) {
389 _cleanup_free_ char *p = NULL;
391 p = session_bus_path(session);
395 r = sd_bus_message_append(reply, "(susso)",
397 (uint32_t) session->user->uid,
399 session->seat ? session->seat->id : "",
405 r = sd_bus_message_close_container(reply);
409 return sd_bus_send(bus, reply, NULL);
412 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
413 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
414 Manager *m = userdata;
423 r = sd_bus_message_new_method_return(message, &reply);
427 r = sd_bus_message_open_container(reply, 'a', "(uso)");
431 HASHMAP_FOREACH(user, m->users, i) {
432 _cleanup_free_ char *p = NULL;
434 p = user_bus_path(user);
438 r = sd_bus_message_append(reply, "(uso)",
439 (uint32_t) user->uid,
446 r = sd_bus_message_close_container(reply);
450 return sd_bus_send(bus, reply, NULL);
453 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
454 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
455 Manager *m = userdata;
464 r = sd_bus_message_new_method_return(message, &reply);
468 r = sd_bus_message_open_container(reply, 'a', "(so)");
472 HASHMAP_FOREACH(seat, m->seats, i) {
473 _cleanup_free_ char *p = NULL;
475 p = seat_bus_path(seat);
479 r = sd_bus_message_append(reply, "(so)", seat->id, p);
484 r = sd_bus_message_close_container(reply);
488 return sd_bus_send(bus, reply, NULL);
491 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
492 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
493 Manager *m = userdata;
494 Inhibitor *inhibitor;
498 r = sd_bus_message_new_method_return(message, &reply);
502 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
506 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
508 r = sd_bus_message_append(reply, "(ssssuu)",
509 strempty(inhibit_what_to_string(inhibitor->what)),
510 strempty(inhibitor->who),
511 strempty(inhibitor->why),
512 strempty(inhibit_mode_to_string(inhibitor->mode)),
513 (uint32_t) inhibitor->uid,
514 (uint32_t) inhibitor->pid);
519 r = sd_bus_message_close_container(reply);
523 return sd_bus_send(bus, reply, NULL);
526 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
527 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
528 uint32_t uid, leader, audit_id = 0;
529 _cleanup_free_ char *id = NULL;
530 Session *session = NULL;
531 Manager *m = userdata;
544 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
549 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
552 t = _SESSION_TYPE_INVALID;
554 t = session_type_from_string(type);
556 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
560 c = _SESSION_CLASS_INVALID;
562 c = session_class_from_string(class);
564 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
567 if (isempty(desktop))
570 if (!string_is_safe(desktop))
571 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
577 seat = hashmap_get(m->seats, cseat);
579 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
582 if (tty_is_vc(tty)) {
587 else if (seat != m->seat0)
588 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);
590 v = vtnr_from_tty(tty);
592 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
596 else if (vtnr != (uint32_t) v)
597 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
599 } else if (tty_is_console(tty)) {
603 else if (seat != m->seat0)
604 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
607 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
611 if (seat_has_vts(seat)) {
612 if (!vtnr || vtnr > 63)
613 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
616 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
620 r = sd_bus_message_enter_container(message, 'a', "(sv)");
624 if (t == _SESSION_TYPE_INVALID) {
625 if (!isempty(display))
627 else if (!isempty(tty))
630 t = SESSION_UNSPECIFIED;
633 if (c == _SESSION_CLASS_INVALID) {
634 if (t == SESSION_UNSPECIFIED)
635 c = SESSION_BACKGROUND;
641 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
643 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
647 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
652 manager_get_session_by_pid(m, leader, &session);
654 _cleanup_free_ char *path = NULL;
655 _cleanup_close_ int fifo_fd = -1;
657 /* Session already exists, client is probably
658 * something like "su" which changes uid but is still
659 * the same session */
661 fifo_fd = session_create_fifo(session);
665 path = session_bus_path(session);
669 log_debug("Sending reply about an existing session: "
670 "id=%s object_path=%s uid=%u runtime_path=%s "
671 "session_fd=%d seat=%s vtnr=%u",
674 (uint32_t) session->user->uid,
675 session->user->runtime_path,
677 session->seat ? session->seat->id : "",
678 (uint32_t) session->vtnr);
680 return sd_bus_reply_method_return(
684 session->user->runtime_path,
686 (uint32_t) session->user->uid,
687 session->seat ? session->seat->id : "",
688 (uint32_t) session->vtnr,
692 audit_session_from_pid(leader, &audit_id);
694 /* Keep our session IDs and the audit session IDs in sync */
696 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
699 /* Wut? There's already a session by this name and we
700 * didn't find it above? Weird, then let's not trust
701 * the audit data and let's better register a new
703 if (hashmap_get(m->sessions, id)) {
704 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
717 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
720 } while (hashmap_get(m->sessions, id));
723 r = manager_add_user_by_uid(m, uid, &user);
727 r = manager_add_session(m, id, &session);
731 session_set_user(session, user);
733 session->leader = leader;
734 session->audit_id = audit_id;
737 session->remote = remote;
738 session->vtnr = vtnr;
741 session->tty = strdup(tty);
748 if (!isempty(display)) {
749 session->display = strdup(display);
750 if (!session->display) {
756 if (!isempty(remote_user)) {
757 session->remote_user = strdup(remote_user);
758 if (!session->remote_user) {
764 if (!isempty(remote_host)) {
765 session->remote_host = strdup(remote_host);
766 if (!session->remote_host) {
772 if (!isempty(service)) {
773 session->service = strdup(service);
774 if (!session->service) {
780 if (!isempty(desktop)) {
781 session->desktop = strdup(desktop);
782 if (!session->desktop) {
789 r = seat_attach_session(seat, session);
794 r = session_start(session);
798 session->create_message = sd_bus_message_ref(message);
800 /* Now, let's wait until the slice unit and stuff got
801 * created. We send the reply back from
802 * session_send_create_reply(). */
808 session_add_to_gc_queue(session);
811 user_add_to_gc_queue(user);
816 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
817 Manager *m = userdata;
826 r = sd_bus_message_read(message, "s", &name);
830 r = manager_get_session_from_creds(m, message, name, error, &session);
834 session_release(session);
836 return sd_bus_reply_method_return(message, NULL);
839 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
840 Manager *m = userdata;
849 r = sd_bus_message_read(message, "s", &name);
853 r = manager_get_session_from_creds(m, message, name, error, &session);
857 r = session_activate(session);
861 return sd_bus_reply_method_return(message, NULL);
864 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
865 const char *session_name, *seat_name;
866 Manager *m = userdata;
875 /* Same as ActivateSession() but refuses to work if
876 * the seat doesn't match */
878 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
882 r = manager_get_session_from_creds(m, message, session_name, error, &session);
886 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
890 if (session->seat != seat)
891 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
893 r = session_activate(session);
897 return sd_bus_reply_method_return(message, NULL);
900 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
901 Manager *m = userdata;
910 r = sd_bus_message_read(message, "s", &name);
914 r = manager_get_session_from_creds(m, message, name, error, &session);
918 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
922 return sd_bus_reply_method_return(message, NULL);
925 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
926 Manager *m = userdata;
933 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
937 return sd_bus_reply_method_return(message, NULL);
940 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
941 const char *name, *swho;
942 Manager *m = userdata;
952 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
959 who = kill_who_from_string(swho);
961 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
964 if (signo <= 0 || signo >= _NSIG)
965 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
967 r = manager_get_session_from_creds(m, message, name, error, &session);
971 r = session_kill(session, who, signo);
975 return sd_bus_reply_method_return(message, NULL);
978 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
979 Manager *m = userdata;
989 r = sd_bus_message_read(message, "ui", &uid, &signo);
993 if (signo <= 0 || signo >= _NSIG)
994 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
996 r = manager_get_user_from_creds(m, message, uid, error, &user);
1000 r = user_kill(user, signo);
1004 return sd_bus_reply_method_return(message, NULL);
1007 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1008 Manager *m = userdata;
1017 r = sd_bus_message_read(message, "s", &name);
1021 r = manager_get_session_from_creds(m, message, name, error, &session);
1025 r = session_stop(session, true);
1029 return sd_bus_reply_method_return(message, NULL);
1032 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1033 Manager *m = userdata;
1042 r = sd_bus_message_read(message, "u", &uid);
1046 r = manager_get_user_from_creds(m, message, uid, error, &user);
1050 r = user_stop(user, true);
1054 return sd_bus_reply_method_return(message, NULL);
1057 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1058 Manager *m = userdata;
1067 r = sd_bus_message_read(message, "s", &name);
1071 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1075 r = seat_stop_sessions(seat, true);
1079 return sd_bus_reply_method_return(message, NULL);
1082 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1083 _cleanup_free_ char *cc = NULL;
1084 Manager *m = userdata;
1095 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1099 if (uid == UID_INVALID) {
1100 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1102 /* Note that we get the owner UID of the session, not the actual client UID here! */
1103 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1107 r = sd_bus_creds_get_owner_uid(creds, &uid);
1115 return errno ? -errno : -ENOENT;
1117 r = bus_verify_polkit_async(
1120 "org.freedesktop.login1.set-user-linger",
1122 &m->polkit_registry,
1127 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1129 mkdir_p_label("/var/lib/systemd", 0755);
1131 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1135 cc = cescape(pw->pw_name);
1139 path = strjoina("/var/lib/systemd/linger/", cc);
1147 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1154 if (r < 0 && errno != ENOENT)
1157 u = hashmap_get(m->users, UID_TO_PTR(uid));
1159 user_add_to_gc_queue(u);
1162 return sd_bus_reply_method_return(message, NULL);
1165 static int trigger_device(Manager *m, struct udev_device *d) {
1166 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1167 struct udev_list_entry *first, *item;
1172 e = udev_enumerate_new(m->udev);
1177 r = udev_enumerate_add_match_parent(e, d);
1182 r = udev_enumerate_scan_devices(e);
1186 first = udev_enumerate_get_list_entry(e);
1187 udev_list_entry_foreach(item, first) {
1188 _cleanup_free_ char *t = NULL;
1191 p = udev_list_entry_get_name(item);
1193 t = strappend(p, "/uevent");
1197 write_string_file(t, "change");
1203 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1204 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1205 _cleanup_free_ char *rule = NULL, *file = NULL;
1206 const char *id_for_seat;
1213 d = udev_device_new_from_syspath(m->udev, sysfs);
1217 if (!udev_device_has_tag(d, "seat"))
1220 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1224 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1227 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1230 mkdir_p_label("/etc/udev/rules.d", 0755);
1231 mac_selinux_init("/etc");
1232 r = write_string_file_atomic_label(file, rule);
1236 return trigger_device(m, d);
1239 static int flush_devices(Manager *m) {
1240 _cleanup_closedir_ DIR *d;
1244 d = opendir("/etc/udev/rules.d");
1246 if (errno != ENOENT)
1247 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1251 while ((de = readdir(d))) {
1253 if (!dirent_is_file(de))
1256 if (!startswith(de->d_name, "72-seat-"))
1259 if (!endswith(de->d_name, ".rules"))
1262 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1263 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1267 return trigger_device(m, NULL);
1270 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1271 const char *sysfs, *seat;
1272 Manager *m = userdata;
1279 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1283 if (!path_startswith(sysfs, "/sys"))
1284 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1286 if (!seat_name_is_valid(seat))
1287 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1289 r = bus_verify_polkit_async(
1292 "org.freedesktop.login1.attach-device",
1294 &m->polkit_registry,
1299 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1301 r = attach_device(m, seat, sysfs);
1305 return sd_bus_reply_method_return(message, NULL);
1308 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1309 Manager *m = userdata;
1316 r = sd_bus_message_read(message, "b", &interactive);
1320 r = bus_verify_polkit_async(
1323 "org.freedesktop.login1.flush-devices",
1325 &m->polkit_registry,
1330 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1332 r = flush_devices(m);
1336 return sd_bus_reply_method_return(message, NULL);
1339 static int have_multiple_sessions(
1348 /* Check for other users' sessions. Greeter sessions do not
1349 * count, and non-login sessions do not count either. */
1350 HASHMAP_FOREACH(session, m->sessions, i)
1351 if (session->class == SESSION_USER &&
1352 session->user->uid != uid)
1358 static int bus_manager_log_shutdown(
1361 const char *unit_name) {
1368 if (w != INHIBIT_SHUTDOWN)
1371 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1372 p = "MESSAGE=System is powering down.";
1373 q = "SHUTDOWN=power-off";
1374 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1375 p = "MESSAGE=System is halting.";
1376 q = "SHUTDOWN=halt";
1377 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1378 p = "MESSAGE=System is rebooting.";
1379 q = "SHUTDOWN=reboot";
1380 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1381 p = "MESSAGE=System is rebooting with kexec.";
1382 q = "SHUTDOWN=kexec";
1384 p = "MESSAGE=System is shutting down.";
1388 return log_struct(LOG_NOTICE,
1389 LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1395 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1396 Manager *m = userdata;
1401 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1405 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1410 if (until <= now(CLOCK_MONOTONIC))
1413 /* We want to ignore the lid switch for a while after each
1414 * suspend, and after boot-up. Hence let's install a timer for
1415 * this. As long as the event source exists we ignore the lid
1418 if (m->lid_switch_ignore_event_source) {
1421 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1428 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1430 r = sd_event_add_time(
1432 &m->lid_switch_ignore_event_source,
1435 lid_switch_ignore_handler, m);
1440 static int execute_shutdown_or_sleep(
1443 const char *unit_name,
1444 sd_bus_error *error) {
1446 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1453 assert(w < _INHIBIT_WHAT_MAX);
1456 bus_manager_log_shutdown(m, w, unit_name);
1458 r = sd_bus_call_method(
1460 "org.freedesktop.systemd1",
1461 "/org/freedesktop/systemd1",
1462 "org.freedesktop.systemd1.Manager",
1466 "ss", unit_name, "replace-irreversibly");
1470 r = sd_bus_message_read(reply, "o", &p);
1478 m->action_unit = unit_name;
1479 free(m->action_job);
1483 /* Make sure the lid switch is ignored for a while */
1484 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
1489 static int delay_shutdown_or_sleep(
1492 const char *unit_name) {
1496 assert(w < _INHIBIT_WHAT_MAX);
1499 m->action_timestamp = now(CLOCK_MONOTONIC);
1500 m->action_unit = unit_name;
1506 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1508 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1509 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1510 [INHIBIT_SLEEP] = "PrepareForSleep"
1513 int active = _active;
1517 assert(w < _INHIBIT_WHAT_MAX);
1518 assert(signal_name[w]);
1520 return sd_bus_emit_signal(m->bus,
1521 "/org/freedesktop/login1",
1522 "org.freedesktop.login1.Manager",
1528 int bus_manager_shutdown_or_sleep_now_or_later(
1530 const char *unit_name,
1532 sd_bus_error *error) {
1540 assert(w <= _INHIBIT_WHAT_MAX);
1541 assert(!m->action_job);
1543 /* Tell everybody to prepare for shutdown/sleep */
1544 send_prepare_for(m, w, true);
1547 m->inhibit_delay_max > 0 &&
1548 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1551 /* Shutdown is delayed, keep in mind what we
1552 * want to do, and start a timeout */
1553 r = delay_shutdown_or_sleep(m, w, unit_name);
1555 /* Shutdown is not delayed, execute it
1557 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1562 static int method_do_shutdown_or_sleep(
1564 sd_bus_message *message,
1565 const char *unit_name,
1568 const char *action_multiple_sessions,
1569 const char *action_ignore_inhibit,
1570 const char *sleep_verb,
1571 sd_bus_message_handler_t method,
1572 sd_bus_error *error) {
1574 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1575 bool multiple_sessions, blocked;
1583 assert(w <= _INHIBIT_WHAT_MAX);
1585 assert(action_multiple_sessions);
1586 assert(action_ignore_inhibit);
1589 r = sd_bus_message_read(message, "b", &interactive);
1593 /* Don't allow multiple jobs being executed at the same time */
1595 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1598 r = can_sleep(sleep_verb);
1603 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1606 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1610 r = sd_bus_creds_get_euid(creds, &uid);
1614 r = have_multiple_sessions(m, uid);
1618 multiple_sessions = r > 0;
1619 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1621 if (multiple_sessions) {
1622 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
1626 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1630 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
1634 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1637 if (!multiple_sessions && !blocked) {
1638 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
1642 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1645 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1649 return sd_bus_reply_method_return(message, NULL);
1652 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1653 Manager *m = userdata;
1655 return method_do_shutdown_or_sleep(
1657 SPECIAL_POWEROFF_TARGET,
1659 "org.freedesktop.login1.power-off",
1660 "org.freedesktop.login1.power-off-multiple-sessions",
1661 "org.freedesktop.login1.power-off-ignore-inhibit",
1667 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1668 Manager *m = userdata;
1670 return method_do_shutdown_or_sleep(
1672 SPECIAL_REBOOT_TARGET,
1674 "org.freedesktop.login1.reboot",
1675 "org.freedesktop.login1.reboot-multiple-sessions",
1676 "org.freedesktop.login1.reboot-ignore-inhibit",
1682 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1683 Manager *m = userdata;
1685 return method_do_shutdown_or_sleep(
1687 SPECIAL_SUSPEND_TARGET,
1689 "org.freedesktop.login1.suspend",
1690 "org.freedesktop.login1.suspend-multiple-sessions",
1691 "org.freedesktop.login1.suspend-ignore-inhibit",
1697 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1698 Manager *m = userdata;
1700 return method_do_shutdown_or_sleep(
1702 SPECIAL_HIBERNATE_TARGET,
1704 "org.freedesktop.login1.hibernate",
1705 "org.freedesktop.login1.hibernate-multiple-sessions",
1706 "org.freedesktop.login1.hibernate-ignore-inhibit",
1712 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1713 Manager *m = userdata;
1715 return method_do_shutdown_or_sleep(
1717 SPECIAL_HYBRID_SLEEP_TARGET,
1719 "org.freedesktop.login1.hibernate",
1720 "org.freedesktop.login1.hibernate-multiple-sessions",
1721 "org.freedesktop.login1.hibernate-ignore-inhibit",
1723 method_hybrid_sleep,
1727 static int method_can_shutdown_or_sleep(
1729 sd_bus_message *message,
1732 const char *action_multiple_sessions,
1733 const char *action_ignore_inhibit,
1734 const char *sleep_verb,
1735 sd_bus_error *error) {
1737 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1738 bool multiple_sessions, challenge, blocked;
1739 const char *result = NULL;
1746 assert(w <= _INHIBIT_WHAT_MAX);
1748 assert(action_multiple_sessions);
1749 assert(action_ignore_inhibit);
1752 r = can_sleep(sleep_verb);
1756 return sd_bus_reply_method_return(message, "s", "na");
1759 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1763 r = sd_bus_creds_get_euid(creds, &uid);
1767 r = have_multiple_sessions(m, uid);
1771 multiple_sessions = r > 0;
1772 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1774 if (multiple_sessions) {
1775 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
1782 result = "challenge";
1788 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
1792 if (r > 0 && !result)
1794 else if (challenge && (!result || streq(result, "yes")))
1795 result = "challenge";
1800 if (!multiple_sessions && !blocked) {
1801 /* If neither inhibit nor multiple sessions
1802 * apply then just check the normal policy */
1804 r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error);
1811 result = "challenge";
1816 return sd_bus_reply_method_return(message, "s", result);
1819 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1820 Manager *m = userdata;
1822 return method_can_shutdown_or_sleep(
1825 "org.freedesktop.login1.power-off",
1826 "org.freedesktop.login1.power-off-multiple-sessions",
1827 "org.freedesktop.login1.power-off-ignore-inhibit",
1832 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1833 Manager *m = userdata;
1835 return method_can_shutdown_or_sleep(
1838 "org.freedesktop.login1.reboot",
1839 "org.freedesktop.login1.reboot-multiple-sessions",
1840 "org.freedesktop.login1.reboot-ignore-inhibit",
1845 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1846 Manager *m = userdata;
1848 return method_can_shutdown_or_sleep(
1851 "org.freedesktop.login1.suspend",
1852 "org.freedesktop.login1.suspend-multiple-sessions",
1853 "org.freedesktop.login1.suspend-ignore-inhibit",
1858 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1859 Manager *m = userdata;
1861 return method_can_shutdown_or_sleep(
1864 "org.freedesktop.login1.hibernate",
1865 "org.freedesktop.login1.hibernate-multiple-sessions",
1866 "org.freedesktop.login1.hibernate-ignore-inhibit",
1871 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1872 Manager *m = userdata;
1874 return method_can_shutdown_or_sleep(
1877 "org.freedesktop.login1.hibernate",
1878 "org.freedesktop.login1.hibernate-multiple-sessions",
1879 "org.freedesktop.login1.hibernate-ignore-inhibit",
1884 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1885 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1886 const char *who, *why, *what, *mode;
1887 _cleanup_free_ char *id = NULL;
1888 _cleanup_close_ int fifo_fd = -1;
1889 Manager *m = userdata;
1890 Inhibitor *i = NULL;
1901 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1905 w = inhibit_what_from_string(what);
1907 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1909 mm = inhibit_mode_from_string(mode);
1911 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1913 /* Delay is only supported for shutdown/sleep */
1914 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1915 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1917 /* Don't allow taking delay locks while we are already
1918 * executing the operation. We shouldn't create the impression
1919 * that the lock was successful if the machine is about to go
1920 * down/suspend any moment. */
1921 if (m->action_what & w)
1922 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1924 r = bus_verify_polkit_async(message, CAP_SYS_BOOT,
1925 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1926 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1927 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1928 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1929 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1930 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1931 "org.freedesktop.login1.inhibit-handle-lid-switch",
1932 false, &m->polkit_registry, error);
1936 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1938 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
1942 r = sd_bus_creds_get_euid(creds, &uid);
1946 r = sd_bus_creds_get_pid(creds, &pid);
1954 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1957 } while (hashmap_get(m->inhibitors, id));
1959 r = manager_add_inhibitor(m, id, &i);
1967 i->why = strdup(why);
1968 i->who = strdup(who);
1970 if (!i->why || !i->who) {
1975 fifo_fd = inhibitor_create_fifo(i);
1983 return sd_bus_reply_method_return(message, "h", fifo_fd);
1992 const sd_bus_vtable manager_vtable[] = {
1993 SD_BUS_VTABLE_START(0),
1995 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1996 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1997 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1998 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1999 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2000 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2001 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2002 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2003 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2004 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2005 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2006 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2007 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2008 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2009 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2010 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2011 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2012 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2013 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2015 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2016 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2017 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2020 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2022 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2023 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2024 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2025 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2026 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2027 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2028 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
2029 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
2030 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
2031 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
2032 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2033 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2034 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2035 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2036 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
2037 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2038 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2039 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2040 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2041 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2042 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2043 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2044 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2045 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2046 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2047 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2048 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2049 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2050 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2052 SD_BUS_SIGNAL("SessionNew", "so", 0),
2053 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2054 SD_BUS_SIGNAL("UserNew", "uo", 0),
2055 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2056 SD_BUS_SIGNAL("SeatNew", "so", 0),
2057 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2058 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2059 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2064 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2073 if (streq(result, "done"))
2074 r = session_send_create_reply(s, NULL);
2076 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2078 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2079 r = session_send_create_reply(s, &e);
2085 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2086 const char *path, *result, *unit;
2087 Manager *m = userdata;
2097 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2099 bus_log_parse_error(r);
2103 if (m->action_job && streq(m->action_job, path)) {
2104 log_info("Operation finished.");
2106 /* Tell people that they now may take a lock again */
2107 send_prepare_for(m, m->action_what, false);
2109 free(m->action_job);
2110 m->action_job = NULL;
2111 m->action_unit = NULL;
2116 session = hashmap_get(m->session_units, unit);
2119 if (streq_ptr(path, session->scope_job)) {
2120 free(session->scope_job);
2121 session->scope_job = NULL;
2124 session_jobs_reply(session, unit, result);
2126 session_save(session);
2127 session_add_to_gc_queue(session);
2130 user = hashmap_get(m->user_units, unit);
2133 if (streq_ptr(path, user->service_job)) {
2134 free(user->service_job);
2135 user->service_job = NULL;
2138 if (streq_ptr(path, user->slice_job)) {
2139 free(user->slice_job);
2140 user->slice_job = NULL;
2143 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2144 session_jobs_reply(session, unit, result);
2148 user_add_to_gc_queue(user);
2154 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2155 const char *path, *unit;
2156 Manager *m = userdata;
2165 r = sd_bus_message_read(message, "so", &unit, &path);
2167 bus_log_parse_error(r);
2171 session = hashmap_get(m->session_units, unit);
2173 session_add_to_gc_queue(session);
2175 user = hashmap_get(m->user_units, unit);
2177 user_add_to_gc_queue(user);
2182 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2183 _cleanup_free_ char *unit = NULL;
2184 Manager *m = userdata;
2194 path = sd_bus_message_get_path(message);
2198 r = unit_name_from_dbus_path(path, &unit);
2199 if (r == -EINVAL) /* not a unit */
2204 session = hashmap_get(m->session_units, unit);
2206 session_add_to_gc_queue(session);
2208 user = hashmap_get(m->user_units, unit);
2210 user_add_to_gc_queue(user);
2215 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2216 Manager *m = userdata;
2223 r = sd_bus_message_read(message, "b", &b);
2225 bus_log_parse_error(r);
2232 /* systemd finished reloading, let's recheck all our sessions */
2233 log_debug("System manager has been reloaded, rechecking sessions...");
2235 HASHMAP_FOREACH(session, m->sessions, i)
2236 session_add_to_gc_queue(session);
2241 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2242 const char *name, *old, *new;
2243 Manager *m = userdata;
2251 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2253 bus_log_parse_error(r);
2257 if (isempty(old) || !isempty(new))
2260 key = set_remove(m->busnames, (char*) old);
2264 /* Drop all controllers owned by this name */
2268 HASHMAP_FOREACH(session, m->sessions, i)
2269 if (session_is_controller(session, old))
2270 session_drop_controller(session);
2275 int manager_send_changed(Manager *manager, const char *property, ...) {
2280 l = strv_from_stdarg_alloca(property);
2282 return sd_bus_emit_properties_changed_strv(
2284 "/org/freedesktop/login1",
2285 "org.freedesktop.login1.Manager",
2289 int manager_dispatch_delayed(Manager *manager) {
2290 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2291 Inhibitor *offending = NULL;
2296 if (manager->action_what == 0 || manager->action_job)
2299 /* Continue delay? */
2300 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2301 _cleanup_free_ char *comm = NULL, *u = NULL;
2303 get_process_comm(offending->pid, &comm);
2304 u = uid_to_name(offending->uid);
2306 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2309 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2310 offending->uid, strna(u),
2311 offending->pid, strna(comm));
2314 /* Actually do the operation */
2315 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2317 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2319 manager->action_unit = NULL;
2320 manager->action_what = 0;
2327 int manager_start_scope(
2332 const char *description,
2333 const char *after, const char *after2,
2334 sd_bus_error *error,
2337 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2344 r = sd_bus_message_new_method_call(
2347 "org.freedesktop.systemd1",
2348 "/org/freedesktop/systemd1",
2349 "org.freedesktop.systemd1.Manager",
2350 "StartTransientUnit");
2354 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2358 r = sd_bus_message_open_container(m, 'a', "(sv)");
2362 if (!isempty(slice)) {
2363 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2368 if (!isempty(description)) {
2369 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2374 if (!isempty(after)) {
2375 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2380 if (!isempty(after2)) {
2381 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2386 /* cgroup empty notification is not available in containers
2387 * currently. To make this less problematic, let's shorten the
2388 * stop timeout for sessions, so that we don't wait
2391 /* Make sure that the session shells are terminated with
2392 * SIGHUP since bash and friends tend to ignore SIGTERM */
2393 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2397 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2401 r = sd_bus_message_close_container(m);
2405 r = sd_bus_message_append(m, "a(sa(sv))", 0);
2409 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2417 r = sd_bus_message_read(reply, "o", &j);
2431 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2432 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2438 r = sd_bus_call_method(
2440 "org.freedesktop.systemd1",
2441 "/org/freedesktop/systemd1",
2442 "org.freedesktop.systemd1.Manager",
2446 "ss", unit, "fail");
2454 r = sd_bus_message_read(reply, "o", &j);
2468 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2469 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2475 r = sd_bus_call_method(
2477 "org.freedesktop.systemd1",
2478 "/org/freedesktop/systemd1",
2479 "org.freedesktop.systemd1.Manager",
2483 "ss", unit, "fail");
2485 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2486 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2491 sd_bus_error_free(error);
2502 r = sd_bus_message_read(reply, "o", &j);
2516 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2517 _cleanup_free_ char *path = NULL;
2523 path = unit_dbus_path_from_name(scope);
2527 r = sd_bus_call_method(
2529 "org.freedesktop.systemd1",
2531 "org.freedesktop.systemd1.Scope",
2537 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2538 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2539 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2540 sd_bus_error_free(error);
2550 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2554 return sd_bus_call_method(
2556 "org.freedesktop.systemd1",
2557 "/org/freedesktop/systemd1",
2558 "org.freedesktop.systemd1.Manager",
2562 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2565 int manager_unit_is_active(Manager *manager, const char *unit) {
2566 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2567 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2568 _cleanup_free_ char *path = NULL;
2575 path = unit_dbus_path_from_name(unit);
2579 r = sd_bus_get_property(
2581 "org.freedesktop.systemd1",
2583 "org.freedesktop.systemd1.Unit",
2589 /* systemd might have droppped off momentarily, let's
2590 * not make this an error */
2591 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2592 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2595 /* If the unit is already unloaded then it's not
2597 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2598 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2604 r = sd_bus_message_read(reply, "s", &state);
2608 return !streq(state, "inactive") && !streq(state, "failed");
2611 int manager_job_is_active(Manager *manager, const char *path) {
2612 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2613 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2619 r = sd_bus_get_property(
2621 "org.freedesktop.systemd1",
2623 "org.freedesktop.systemd1.Job",
2629 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2630 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2633 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2639 /* We don't actually care about the state really. The fact
2640 * that we could read the job state is enough for us */