1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "sd-messages.h"
31 #include "path-util.h"
33 #include "sleep-config.h"
34 #include "fileio-label.h"
37 #include "unit-name.h"
41 #include "bus-error.h"
43 #include "bus-errors.h"
45 static int property_get_idle_hint(
48 const char *interface,
50 sd_bus_message *reply,
54 Manager *m = userdata;
60 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
63 static int property_get_idle_since_hint(
66 const char *interface,
68 sd_bus_message *reply,
72 Manager *m = userdata;
79 manager_get_idle_hint(m, &t);
81 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
84 static int property_get_inhibited(
87 const char *interface,
89 sd_bus_message *reply,
93 Manager *m = userdata;
100 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
102 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
105 static int property_get_preparing(
108 const char *interface,
109 const char *property,
110 sd_bus_message *reply,
114 Manager *m = userdata;
121 if (streq(property, "PreparingForShutdown"))
122 b = !!(m->action_what & INHIBIT_SHUTDOWN);
124 b = !!(m->action_what & INHIBIT_SLEEP);
126 return sd_bus_message_append(reply, "b", b);
129 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
131 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
132 _cleanup_free_ char *p = NULL;
133 Manager *m = userdata;
142 r = sd_bus_message_read(message, "s", &name);
144 return sd_bus_reply_method_errno(message, r, NULL);
146 session = hashmap_get(m->sessions, name);
148 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
150 p = session_bus_path(session);
152 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
154 return sd_bus_reply_method_return(message, "o", p);
157 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata) {
158 _cleanup_free_ char *p = NULL;
159 Session *session = NULL;
160 Manager *m = userdata;
168 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
170 r = sd_bus_message_read(message, "u", &pid);
172 return sd_bus_reply_method_errno(message, r, NULL);
175 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
177 return sd_bus_reply_method_errno(message, r, NULL);
180 r = manager_get_session_by_pid(m, pid, &session);
182 return sd_bus_reply_method_errno(message, r, NULL);
184 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
186 p = session_bus_path(session);
188 return sd_bus_reply_method_errno(message, ENOMEM, NULL);
190 return sd_bus_reply_method_return(message, "o", p);
193 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
194 _cleanup_free_ char *p = NULL;
195 Manager *m = userdata;
204 r = sd_bus_message_read(message, "u", &uid);
206 return sd_bus_reply_method_errno(message, r, NULL);
208 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
210 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
212 p = user_bus_path(user);
214 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
216 return sd_bus_reply_method_return(message, "o", p);
219 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata) {
220 _cleanup_free_ char *p = NULL;
221 Manager *m = userdata;
230 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
232 r = sd_bus_message_read(message, "u", &pid);
234 return sd_bus_reply_method_errno(message, r, NULL);
237 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
239 return sd_bus_reply_method_errno(message, r, NULL);
242 r = manager_get_user_by_pid(m, pid, &user);
244 return sd_bus_reply_method_errno(message, r, NULL);
246 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
248 p = user_bus_path(user);
250 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
252 return sd_bus_reply_method_return(message, "o", p);
255 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
256 _cleanup_free_ char *p = NULL;
257 Manager *m = userdata;
266 r = sd_bus_message_read(message, "s", &name);
268 return sd_bus_reply_method_errno(message, r, NULL);
270 seat = hashmap_get(m->seats, name);
272 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
274 p = seat_bus_path(seat);
276 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
278 return sd_bus_reply_method_return(message, "o", p);
281 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata) {
282 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
283 Manager *m = userdata;
292 r = sd_bus_message_new_method_return(message, &reply);
294 return sd_bus_reply_method_errno(message, r, NULL);
296 r = sd_bus_message_open_container(reply, 'a', "(susso)");
298 return sd_bus_reply_method_errno(message, r, NULL);
300 HASHMAP_FOREACH(session, m->sessions, i) {
301 _cleanup_free_ char *p = NULL;
303 p = session_bus_path(session);
305 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
307 r = sd_bus_message_append(reply, "(susso)",
309 (uint32_t) session->user->uid,
311 session->seat ? session->seat->id : "",
314 return sd_bus_reply_method_errno(message, r, NULL);
317 r = sd_bus_message_close_container(reply);
319 return sd_bus_reply_method_errno(message, r, NULL);
321 return sd_bus_send(bus, reply, NULL);
324 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata) {
325 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
326 Manager *m = userdata;
335 r = sd_bus_message_new_method_return(message, &reply);
337 return sd_bus_reply_method_errno(message, r, NULL);
339 r = sd_bus_message_open_container(reply, 'a', "(uso)");
341 return sd_bus_reply_method_errno(message, r, NULL);
343 HASHMAP_FOREACH(user, m->users, i) {
344 _cleanup_free_ char *p = NULL;
346 p = user_bus_path(user);
348 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
350 r = sd_bus_message_append(reply, "(uso)",
351 (uint32_t) user->uid,
355 return sd_bus_reply_method_errno(message, r, NULL);
358 r = sd_bus_message_close_container(reply);
360 return sd_bus_reply_method_errno(message, r, NULL);
362 return sd_bus_send(bus, reply, NULL);
365 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata) {
366 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
367 Manager *m = userdata;
376 r = sd_bus_message_new_method_return(message, &reply);
378 return sd_bus_reply_method_errno(message, r, NULL);
380 r = sd_bus_message_open_container(reply, 'a', "(so)");
382 return sd_bus_reply_method_errno(message, r, NULL);
384 HASHMAP_FOREACH(seat, m->seats, i) {
385 _cleanup_free_ char *p = NULL;
387 p = seat_bus_path(seat);
389 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
391 r = sd_bus_message_append(reply, "(so)", seat->id, p);
393 return sd_bus_reply_method_errno(message, r, NULL);
396 r = sd_bus_message_close_container(reply);
398 return sd_bus_reply_method_errno(message, r, NULL);
400 return sd_bus_send(bus, reply, NULL);
403 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata) {
404 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
405 Manager *m = userdata;
406 Inhibitor *inhibitor;
410 r = sd_bus_message_new_method_return(message, &reply);
412 return sd_bus_reply_method_errno(message, r, NULL);
414 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
416 return sd_bus_reply_method_errno(message, r, NULL);
418 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
420 r = sd_bus_message_append(reply, "(ssssuu)",
421 strempty(inhibit_what_to_string(inhibitor->what)),
422 strempty(inhibitor->who),
423 strempty(inhibitor->why),
424 strempty(inhibit_mode_to_string(inhibitor->mode)),
425 (uint32_t) inhibitor->uid,
426 (uint32_t) inhibitor->pid);
428 return sd_bus_reply_method_errno(message, r, NULL);
431 r = sd_bus_message_close_container(reply);
433 return sd_bus_reply_method_errno(message, r, NULL);
435 return sd_bus_send(bus, reply, NULL);
438 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
439 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
440 uint32_t uid, leader, audit_id = 0;
441 _cleanup_free_ char *id = NULL;
442 Session *session = NULL;
443 Manager *m = userdata;
456 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
458 return sd_bus_reply_method_errno(message, r, NULL);
461 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
464 t = _SESSION_TYPE_INVALID;
466 t = session_type_from_string(type);
468 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
472 c = _SESSION_CLASS_INVALID;
474 c = session_class_from_string(class);
476 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
482 seat = hashmap_get(m->seats, cseat);
484 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
487 if (tty_is_vc(tty)) {
492 else if (seat != m->seat0)
493 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
495 v = vtnr_from_tty(tty);
497 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
501 else if (vtnr != (uint32_t) v)
502 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
504 } else if (tty_is_console(tty)) {
508 else if (seat != m->seat0)
509 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
512 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
516 if (seat_has_vts(seat)) {
518 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
521 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
525 r = sd_bus_message_enter_container(message, 'a', "(sv)");
527 return sd_bus_reply_method_errno(message, r, NULL);
529 if (t == _SESSION_TYPE_INVALID) {
530 if (!isempty(display))
532 else if (!isempty(tty))
535 t = SESSION_UNSPECIFIED;
538 if (c == _SESSION_CLASS_INVALID) {
539 if (!isempty(display) || !isempty(tty))
542 c = SESSION_BACKGROUND;
546 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
548 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
550 return sd_bus_reply_method_errno(message, r, NULL);
553 manager_get_session_by_pid(m, leader, &session);
555 _cleanup_free_ char *path = NULL;
556 _cleanup_close_ int fifo_fd = -1;
558 /* Session already exists, client is probably
559 * something like "su" which changes uid but is still
560 * the same session */
562 fifo_fd = session_create_fifo(session);
564 return sd_bus_reply_method_errno(message, fifo_fd, NULL);
566 path = session_bus_path(session);
568 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
570 return sd_bus_reply_method_return(
574 session->user->runtime_path,
576 session->seat ? session->seat->id : "",
577 (uint32_t) session->vtnr,
581 audit_session_from_pid(leader, &audit_id);
583 /* Keep our session IDs and the audit session IDs in sync */
585 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
586 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
588 /* Wut? There's already a session by this name and we
589 * didn't find it above? Weird, then let's not trust
590 * the audit data and let's better register a new
592 if (hashmap_get(m->sessions, id)) {
593 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
606 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
607 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
609 } while (hashmap_get(m->sessions, id));
612 r = manager_add_user_by_uid(m, uid, &user);
614 r = sd_bus_reply_method_errno(message, r, NULL);
618 r = manager_add_session(m, id, &session);
620 r = sd_bus_reply_method_errno(message, r, NULL);
624 session_set_user(session, user);
626 session->leader = leader;
627 session->audit_id = audit_id;
630 session->remote = remote;
631 session->vtnr = vtnr;
634 session->tty = strdup(tty);
636 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
641 if (!isempty(display)) {
642 session->display = strdup(display);
643 if (!session->display) {
644 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
649 if (!isempty(remote_user)) {
650 session->remote_user = strdup(remote_user);
651 if (!session->remote_user) {
652 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
657 if (!isempty(remote_host)) {
658 session->remote_host = strdup(remote_host);
659 if (!session->remote_host) {
660 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
665 if (!isempty(service)) {
666 session->service = strdup(service);
667 if (!session->service) {
668 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
674 r = seat_attach_session(seat, session);
676 r = sd_bus_reply_method_errno(message, r, NULL);
681 r = session_start(session);
683 r = sd_bus_reply_method_errno(message, r, NULL);
687 session->create_message = sd_bus_message_ref(message);
689 /* Now, let's wait until the slice unit and stuff got
690 * created. We send the reply back from
691 * session_send_create_reply().*/
697 session_add_to_gc_queue(session);
700 user_add_to_gc_queue(user);
705 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
706 Manager *m = userdata;
715 r = sd_bus_message_read(message, "s", &name);
717 return sd_bus_reply_method_errno(message, r, NULL);
719 session = hashmap_get(m->sessions, name);
721 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
723 /* We use the FIFO to detect stray sessions where the process
724 invoking PAM dies abnormally. We need to make sure that
725 that process is not killed if at the clean end of the
726 session it closes the FIFO. Hence, with this call
727 explicitly turn off the FIFO logic, so that the PAM code
728 can finish clean up on its own */
729 session_remove_fifo(session);
730 session_save(session);
731 user_save(session->user);
733 return sd_bus_reply_method_return(message, NULL);
736 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
737 Manager *m = userdata;
746 r = sd_bus_message_read(message, "s", &name);
748 return sd_bus_reply_method_errno(message, r, NULL);
750 session = hashmap_get(m->sessions, name);
752 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
754 r = session_activate(session);
756 return sd_bus_reply_method_errno(message, r, NULL);
758 return sd_bus_reply_method_return(message, NULL);
761 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
762 const char *session_name, *seat_name;
763 Manager *m = userdata;
772 /* Same as ActivateSession() but refuses to work if
773 * the seat doesn't match */
775 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
777 return sd_bus_reply_method_errno(message, r, NULL);
779 session = hashmap_get(m->sessions, session_name);
781 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
783 seat = hashmap_get(m->seats, seat_name);
785 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
787 if (session->seat != seat)
788 return sd_bus_reply_method_errorf(message, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
790 r = session_activate(session);
792 return sd_bus_reply_method_errno(message, r, NULL);
794 return sd_bus_reply_method_return(message, NULL);
797 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
798 Manager *m = userdata;
807 r = sd_bus_message_read(message, "s", &name);
809 return sd_bus_reply_method_errno(message, r, NULL);
811 session = hashmap_get(m->sessions, name);
813 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
815 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
817 return sd_bus_reply_method_errno(message, r, NULL);
819 return sd_bus_reply_method_return(message, NULL);
822 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata) {
823 Manager *m = userdata;
830 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
832 return sd_bus_reply_method_errno(message, r, NULL);
834 return sd_bus_reply_method_return(message, NULL);
837 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
838 const char *name, *swho;
839 Manager *m = userdata;
849 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
851 return sd_bus_reply_method_errno(message, r, NULL);
856 who = kill_who_from_string(swho);
858 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
861 if (signo <= 0 || signo >= _NSIG)
862 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
864 session = hashmap_get(m->sessions, name);
866 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
868 r = session_kill(session, who, signo);
870 return sd_bus_reply_method_errno(message, r, NULL);
872 return sd_bus_reply_method_return(message, NULL);
875 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
876 Manager *m = userdata;
886 r = sd_bus_message_read(message, "ui", &uid, &signo);
888 return sd_bus_reply_method_errno(message, r, NULL);
890 if (signo <= 0 || signo >= _NSIG)
891 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
893 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
895 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
897 r = user_kill(user, signo);
899 return sd_bus_reply_method_errno(message, r, NULL);
901 return sd_bus_reply_method_return(message, NULL);
904 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
905 Manager *m = userdata;
914 r = sd_bus_message_read(message, "s", &name);
916 return sd_bus_reply_method_errno(message, r, NULL);
918 session = hashmap_get(m->sessions, name);
920 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
922 r = session_stop(session);
924 return sd_bus_reply_method_errno(message, r, NULL);
926 return sd_bus_reply_method_return(message, NULL);
929 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
930 Manager *m = userdata;
939 r = sd_bus_message_read(message, "u", &uid);
941 return sd_bus_reply_method_errno(message, r, NULL);
943 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
945 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
949 return sd_bus_reply_method_errno(message, r, NULL);
951 return sd_bus_reply_method_return(message, NULL);
954 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
955 Manager *m = userdata;
964 r = sd_bus_message_read(message, "s", &name);
966 return sd_bus_reply_method_errno(message, r, NULL);
968 seat = hashmap_get(m->seats, name);
970 return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
972 r = seat_stop_sessions(seat);
974 return sd_bus_reply_method_errno(message, r, NULL);
976 return sd_bus_reply_method_return(message, NULL);
979 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata) {
980 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
981 _cleanup_free_ char *cc = NULL;
982 Manager *m = userdata;
993 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
995 return sd_bus_reply_method_errno(message, r, NULL);
1000 return sd_bus_reply_method_errno(message, errno ? errno : ENOENT, NULL);
1002 r = bus_verify_polkit_async(bus,
1003 &m->polkit_registry,
1005 "org.freedesktop.login1.set-user-linger",
1008 method_set_user_linger, m);
1010 return sd_bus_reply_method_errno(message, r, &error);
1012 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1014 mkdir_p_label("/var/lib/systemd", 0755);
1016 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1018 return sd_bus_reply_method_errno(message, r, NULL);
1020 cc = cescape(pw->pw_name);
1022 return sd_bus_reply_method_errno(message, ENOMEM, NULL);
1024 path = strappenda("/var/lib/systemd/linger/", cc);
1030 return sd_bus_reply_method_errno(message, r, NULL);
1032 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1039 if (r < 0 && errno != ENOENT)
1040 return sd_bus_reply_method_errno(message, errno, NULL);
1042 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1044 user_add_to_gc_queue(u);
1047 return sd_bus_reply_method_return(message, NULL);
1050 static int trigger_device(Manager *m, struct udev_device *d) {
1051 struct udev_enumerate *e;
1052 struct udev_list_entry *first, *item;
1057 e = udev_enumerate_new(m->udev);
1064 if (udev_enumerate_add_match_parent(e, d) < 0) {
1070 if (udev_enumerate_scan_devices(e) < 0) {
1075 first = udev_enumerate_get_list_entry(e);
1076 udev_list_entry_foreach(item, first) {
1077 _cleanup_free_ char *t = NULL;
1080 p = udev_list_entry_get_name(item);
1082 t = strappend(p, "/uevent");
1088 write_string_file(t, "change");
1095 udev_enumerate_unref(e);
1100 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1101 _cleanup_free_ char *rule = NULL, *file = NULL;
1102 const char *id_for_seat;
1103 struct udev_device *d;
1110 d = udev_device_new_from_syspath(m->udev, sysfs);
1114 if (!udev_device_has_tag(d, "seat")) {
1119 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1125 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
1130 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1135 mkdir_p_label("/etc/udev/rules.d", 0755);
1137 r = write_string_file_atomic_label(file, rule);
1141 r = trigger_device(m, d);
1145 udev_device_unref(d);
1150 static int flush_devices(Manager *m) {
1151 _cleanup_closedir_ DIR *d;
1155 d = opendir("/etc/udev/rules.d");
1157 if (errno != ENOENT)
1158 log_warning("Failed to open /etc/udev/rules.d: %m");
1162 while ((de = readdir(d))) {
1164 if (!dirent_is_file(de))
1167 if (!startswith(de->d_name, "72-seat-"))
1170 if (!endswith(de->d_name, ".rules"))
1173 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1174 log_warning("Failed to unlink %s: %m", de->d_name);
1178 return trigger_device(m, NULL);
1181 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata) {
1182 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1183 const char *sysfs, *seat;
1184 Manager *m = userdata;
1191 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1193 return sd_bus_reply_method_errno(message, r, NULL);
1195 if (!path_startswith(sysfs, "/sys"))
1196 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1198 if (!seat_name_is_valid(seat))
1199 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1201 r = bus_verify_polkit_async(bus,
1202 &m->polkit_registry,
1204 "org.freedesktop.login1.attach-device",
1207 method_attach_device, m);
1209 return sd_bus_reply_method_errno(message, r, &error);
1211 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1213 r = attach_device(m, seat, sysfs);
1215 return sd_bus_reply_method_errno(message, r, NULL);
1217 return sd_bus_reply_method_return(message, NULL);
1220 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata) {
1221 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1222 Manager *m = userdata;
1229 r = sd_bus_message_read(message, "b", &interactive);
1231 return sd_bus_reply_method_errno(message, r, NULL);
1233 r = bus_verify_polkit_async(bus,
1234 &m->polkit_registry,
1236 "org.freedesktop.login1.flush-devices",
1239 method_flush_devices, m);
1241 return sd_bus_reply_method_errno(message, r, &error);
1243 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1245 r = flush_devices(m);
1247 return sd_bus_reply_method_errno(message, r, &error);
1249 return sd_bus_reply_method_return(message, NULL);
1252 static int have_multiple_sessions(
1261 /* Check for other users' sessions. Greeter sessions do not
1262 * count, and non-login sessions do not count either. */
1263 HASHMAP_FOREACH(session, m->sessions, i)
1264 if (session->class == SESSION_USER &&
1265 !session->closing &&
1266 session->user->uid != uid)
1272 static int bus_manager_log_shutdown(
1275 const char *unit_name) {
1282 if (w != INHIBIT_SHUTDOWN)
1285 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1286 p = "MESSAGE=System is powering down.";
1287 q = "SHUTDOWN=power-off";
1288 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1289 p = "MESSAGE=System is halting.";
1290 q = "SHUTDOWN=halt";
1291 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1292 p = "MESSAGE=System is rebooting.";
1293 q = "SHUTDOWN=reboot";
1294 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1295 p = "MESSAGE=System is rebooting with kexec.";
1296 q = "SHUTDOWN=kexec";
1298 p = "MESSAGE=System is shutting down.";
1302 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1307 static int execute_shutdown_or_sleep(
1310 const char *unit_name,
1311 sd_bus_error *error) {
1313 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1320 assert(w < _INHIBIT_WHAT_MAX);
1323 bus_manager_log_shutdown(m, w, unit_name);
1325 r = sd_bus_call_method(
1327 "org.freedesktop.systemd1",
1328 "/org/freedesktop/systemd1",
1329 "org.freedesktop.systemd1.Manager",
1333 "ss", unit_name, "replace-irreversibly");
1337 r = sd_bus_message_read(reply, "o", &p);
1345 m->action_unit = unit_name;
1346 free(m->action_job);
1353 static int delay_shutdown_or_sleep(
1356 const char *unit_name) {
1360 assert(w < _INHIBIT_WHAT_MAX);
1363 m->action_timestamp = now(CLOCK_MONOTONIC);
1364 m->action_unit = unit_name;
1370 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1372 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1373 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1374 [INHIBIT_SLEEP] = "PrepareForSleep"
1377 int active = _active;
1381 assert(w < _INHIBIT_WHAT_MAX);
1382 assert(signal_name[w]);
1384 return sd_bus_emit_signal(m->bus,
1385 "/org/freedesktop/login1",
1386 "org.freedesktop.login1.Manager",
1392 int bus_manager_shutdown_or_sleep_now_or_later(
1394 const char *unit_name,
1396 sd_bus_error *error) {
1404 assert(w <= _INHIBIT_WHAT_MAX);
1405 assert(!m->action_job);
1407 /* Tell everybody to prepare for shutdown/sleep */
1408 send_prepare_for(m, w, true);
1411 m->inhibit_delay_max > 0 &&
1412 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0);
1415 /* Shutdown is delayed, keep in mind what we
1416 * want to do, and start a timeout */
1417 r = delay_shutdown_or_sleep(m, w, unit_name);
1419 /* Shutdown is not delayed, execute it
1421 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1426 static int method_do_shutdown_or_sleep(
1428 sd_bus_message *message,
1429 const char *unit_name,
1432 const char *action_multiple_sessions,
1433 const char *action_ignore_inhibit,
1434 const char *sleep_verb,
1435 sd_bus_message_handler_t method) {
1437 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1438 bool multiple_sessions, blocked;
1446 assert(w <= _INHIBIT_WHAT_MAX);
1448 assert(action_multiple_sessions);
1449 assert(action_ignore_inhibit);
1452 r = sd_bus_message_read(message, "b", &interactive);
1454 return sd_bus_reply_method_errno(message, r, NULL);
1456 /* Don't allow multiple jobs being executed at the same time */
1458 return sd_bus_reply_method_errorf(message, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1461 r = can_sleep(sleep_verb);
1463 return sd_bus_reply_method_errno(message, r, NULL);
1466 return sd_bus_reply_method_errorf(message, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1469 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1471 return sd_bus_reply_method_errno(message, r, NULL);
1473 r = have_multiple_sessions(m, uid);
1475 return sd_bus_reply_method_errno(message, r, NULL);
1477 multiple_sessions = r > 0;
1478 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1480 if (multiple_sessions) {
1481 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1482 action_multiple_sessions, interactive, &error, method, m);
1484 return sd_bus_reply_method_errno(message, r, &error);
1488 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1489 action_ignore_inhibit, interactive, &error, method, m);
1491 return sd_bus_reply_method_errno(message, r, &error);
1494 if (!multiple_sessions && !blocked) {
1495 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1496 action, interactive, &error, method, m);
1498 return sd_bus_reply_method_errno(message, r, &error);
1501 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, &error);
1503 return sd_bus_reply_method_errno(message, r, &error);
1505 return sd_bus_reply_method_return(message, NULL);
1508 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata) {
1509 Manager *m = userdata;
1511 return method_do_shutdown_or_sleep(
1513 SPECIAL_POWEROFF_TARGET,
1515 "org.freedesktop.login1.power-off",
1516 "org.freedesktop.login1.power-off-multiple-sessions",
1517 "org.freedesktop.login1.power-off-ignore-inhibit",
1522 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata) {
1523 Manager *m = userdata;
1525 return method_do_shutdown_or_sleep(
1527 SPECIAL_REBOOT_TARGET,
1529 "org.freedesktop.login1.reboot",
1530 "org.freedesktop.login1.reboot-multiple-sessions",
1531 "org.freedesktop.login1.reboot-ignore-inhibit",
1536 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata) {
1537 Manager *m = userdata;
1539 return method_do_shutdown_or_sleep(
1541 SPECIAL_SUSPEND_TARGET,
1543 "org.freedesktop.login1.suspend",
1544 "org.freedesktop.login1.suspend-multiple-sessions",
1545 "org.freedesktop.login1.suspend-ignore-inhibit",
1550 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata) {
1551 Manager *m = userdata;
1553 return method_do_shutdown_or_sleep(
1555 SPECIAL_HIBERNATE_TARGET,
1557 "org.freedesktop.login1.hibernate",
1558 "org.freedesktop.login1.hibernate-multiple-sessions",
1559 "org.freedesktop.login1.hibernate-ignore-inhibit",
1564 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata) {
1565 Manager *m = userdata;
1567 return method_do_shutdown_or_sleep(
1569 SPECIAL_HYBRID_SLEEP_TARGET,
1571 "org.freedesktop.login1.hibernate",
1572 "org.freedesktop.login1.hibernate-multiple-sessions",
1573 "org.freedesktop.login1.hibernate-ignore-inhibit",
1575 method_hybrid_sleep);
1578 static int method_can_shutdown_or_sleep(
1580 sd_bus_message *message,
1583 const char *action_multiple_sessions,
1584 const char *action_ignore_inhibit,
1585 const char *sleep_verb) {
1587 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1588 bool multiple_sessions, challenge, blocked;
1589 const char *result = NULL;
1596 assert(w <= _INHIBIT_WHAT_MAX);
1598 assert(action_multiple_sessions);
1599 assert(action_ignore_inhibit);
1602 r = can_sleep(sleep_verb);
1604 return sd_bus_reply_method_errno(message, r, NULL);
1606 return sd_bus_reply_method_return(message, "s", "na");
1609 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1611 return sd_bus_reply_method_errno(message, r, NULL);
1613 r = have_multiple_sessions(m, uid);
1615 return sd_bus_reply_method_errno(message, r, NULL);
1617 multiple_sessions = r > 0;
1618 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1620 if (multiple_sessions) {
1621 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, &error);
1623 return sd_bus_reply_method_errno(message, r, &error);
1628 result = "challenge";
1634 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, &error);
1636 return sd_bus_reply_method_errno(message, r, &error);
1638 if (r > 0 && !result)
1640 else if (challenge && (!result || streq(result, "yes")))
1641 result = "challenge";
1646 if (!multiple_sessions && !blocked) {
1647 /* If neither inhibit nor multiple sessions
1648 * apply then just check the normal policy */
1650 r = bus_verify_polkit(m->bus, message, action, false, &challenge, &error);
1652 return sd_bus_reply_method_errno(message, r, &error);
1657 result = "challenge";
1662 return sd_bus_reply_method_return(message, "s", result);
1665 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata) {
1666 Manager *m = userdata;
1668 return method_can_shutdown_or_sleep(
1671 "org.freedesktop.login1.power-off",
1672 "org.freedesktop.login1.power-off-multiple-sessions",
1673 "org.freedesktop.login1.power-off-ignore-inhibit",
1677 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata) {
1678 Manager *m = userdata;
1680 return method_can_shutdown_or_sleep(
1683 "org.freedesktop.login1.reboot",
1684 "org.freedesktop.login1.reboot-multiple-sessions",
1685 "org.freedesktop.login1.reboot-ignore-inhibit",
1689 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata) {
1690 Manager *m = userdata;
1692 return method_can_shutdown_or_sleep(
1695 "org.freedesktop.login1.suspend",
1696 "org.freedesktop.login1.suspend-multiple-sessions",
1697 "org.freedesktop.login1.suspend-ignore-inhibit",
1701 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata) {
1702 Manager *m = userdata;
1704 return method_can_shutdown_or_sleep(
1707 "org.freedesktop.login1.hibernate",
1708 "org.freedesktop.login1.hibernate-multiple-sessions",
1709 "org.freedesktop.login1.hibernate-ignore-inhibit",
1713 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata) {
1714 Manager *m = userdata;
1716 return method_can_shutdown_or_sleep(
1719 "org.freedesktop.login1.hibernate",
1720 "org.freedesktop.login1.hibernate-multiple-sessions",
1721 "org.freedesktop.login1.hibernate-ignore-inhibit",
1725 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata) {
1726 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1727 const char *who, *why, *what, *mode;
1728 _cleanup_free_ char *id = NULL;
1729 _cleanup_close_ int fifo_fd = -1;
1730 Manager *m = userdata;
1731 Inhibitor *i = NULL;
1742 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1744 return sd_bus_reply_method_errno(message, r, NULL);
1746 w = inhibit_what_from_string(what);
1748 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1750 mm = inhibit_mode_from_string(mode);
1752 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1754 /* Delay is only supported for shutdown/sleep */
1755 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1756 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1758 /* Don't allow taking delay locks while we are already
1759 * executing the operation. We shouldn't create the impression
1760 * that the lock was successful if the machine is about to go
1761 * down/suspend any moment. */
1762 if (m->action_what & w)
1763 return sd_bus_reply_method_errorf(message, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1765 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1766 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1767 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1768 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1769 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1770 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1771 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1772 "org.freedesktop.login1.inhibit-handle-lid-switch",
1773 false, &error, method_inhibit, m);
1775 return sd_bus_reply_method_errno(message, r, &error);
1777 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1779 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1781 return sd_bus_reply_method_errno(message, r, NULL);
1783 r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
1785 return sd_bus_reply_method_errno(message, r, NULL);
1791 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1792 return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
1794 } while (hashmap_get(m->inhibitors, id));
1796 r = manager_add_inhibitor(m, id, &i);
1798 return sd_bus_reply_method_errno(message, r, NULL);
1804 i->why = strdup(why);
1805 i->who = strdup(who);
1807 if (!i->why || !i->who) {
1808 r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
1812 fifo_fd = inhibitor_create_fifo(i);
1814 r = sd_bus_reply_method_errno(message, fifo_fd, NULL);
1820 return sd_bus_reply_method_return(message, "h", fifo_fd);
1829 const sd_bus_vtable manager_vtable[] = {
1830 SD_BUS_VTABLE_START(0),
1832 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1833 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1834 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1835 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1836 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1837 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1838 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1839 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1840 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1841 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1842 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1843 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1844 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1845 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1846 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1847 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1848 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1849 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1851 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1852 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1853 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1854 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1855 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1856 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1857 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1858 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1859 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1860 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshsub", method_create_session, 0),
1861 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1862 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1863 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1864 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1865 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1866 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1867 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1868 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1869 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1870 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1871 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1872 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1873 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1874 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1875 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1876 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1877 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1878 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1879 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1880 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1881 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1882 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1883 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1884 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1885 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1886 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1888 SD_BUS_SIGNAL("SessionNew", "so", 0),
1889 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1890 SD_BUS_SIGNAL("UserNew", "uo", 0),
1891 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1892 SD_BUS_SIGNAL("SeatNew", "so", 0),
1893 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1894 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1895 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1900 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
1901 const char *path, *result, *unit;
1902 Manager *m = userdata;
1912 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1914 log_error("Failed to parse JobRemoved message: %s", strerror(-r));
1918 if (m->action_job && streq(m->action_job, path)) {
1919 log_info("Operation finished.");
1921 /* Tell people that they now may take a lock again */
1922 send_prepare_for(m, m->action_what, false);
1924 free(m->action_job);
1925 m->action_job = NULL;
1926 m->action_unit = NULL;
1931 session = hashmap_get(m->session_units, unit);
1934 if (streq_ptr(path, session->scope_job)) {
1935 free(session->scope_job);
1936 session->scope_job = NULL;
1939 if (session->started) {
1940 if (streq(result, "done"))
1941 session_send_create_reply(session, NULL);
1943 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1945 sd_bus_error_setf(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1946 session_send_create_reply(session, &error);
1949 session_save(session);
1951 session_add_to_gc_queue(session);
1954 user = hashmap_get(m->user_units, unit);
1957 if (streq_ptr(path, user->service_job)) {
1958 free(user->service_job);
1959 user->service_job = NULL;
1962 if (streq_ptr(path, user->slice_job)) {
1963 free(user->slice_job);
1964 user->slice_job = NULL;
1968 user_add_to_gc_queue(user);
1974 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
1975 const char *path, *unit;
1976 Manager *m = userdata;
1985 r = sd_bus_message_read(message, "so", &unit, &path);
1987 log_error("Failed to parse UnitRemoved message: %s", strerror(-r));
1991 session = hashmap_get(m->session_units, unit);
1993 session_add_to_gc_queue(session);
1995 user = hashmap_get(m->user_units, unit);
1997 user_add_to_gc_queue(user);
2002 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
2003 _cleanup_free_ char *unit = NULL;
2004 Manager *m = userdata;
2013 path = sd_bus_message_get_path(message);
2017 unit_name_from_dbus_path(path, &unit);
2021 session = hashmap_get(m->session_units, unit);
2023 session_add_to_gc_queue(session);
2025 user = hashmap_get(m->user_units, unit);
2027 user_add_to_gc_queue(user);
2032 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata) {
2033 Manager *m = userdata;
2040 r = sd_bus_message_read(message, "b", &b);
2042 log_error("Failed to parse Reloading message: %s", strerror(-r));
2049 /* systemd finished reloading, let's recheck all our sessions */
2050 log_debug("System manager has been reloaded, rechecking sessions...");
2052 HASHMAP_FOREACH(session, m->sessions, i)
2053 session_add_to_gc_queue(session);
2058 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
2059 const char *name, *old, *new;
2060 Manager *m = userdata;
2068 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2070 log_error("Failed to parse NameOwnerChanged message: %s", strerror(-r));
2074 if (isempty(old) || !isempty(new))
2077 key = set_remove(m->busnames, (char*) old);
2081 /* Drop all controllers owned by this name */
2085 HASHMAP_FOREACH(session, m->sessions, i)
2086 if (session_is_controller(session, old))
2087 session_drop_controller(session);
2092 int manager_send_changed(Manager *manager, const char *property, ...) {
2097 l = strv_from_stdarg_alloca(property);
2099 return sd_bus_emit_properties_changed_strv(
2101 "/org/freedesktop/login1",
2102 "org.freedesktop.login1.Manager",
2106 int manager_dispatch_delayed(Manager *manager) {
2107 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2112 if (manager->action_what == 0 || manager->action_job)
2115 /* Continue delay? */
2116 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0)) {
2118 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2121 log_info("Delay lock is active but inhibitor timeout is reached.");
2124 /* Actually do the operation */
2125 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2127 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2129 manager->action_unit = NULL;
2130 manager->action_what = 0;
2137 int manager_start_scope(
2142 const char *description,
2144 const char *kill_mode,
2145 sd_bus_error *error,
2148 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2155 r = sd_bus_message_new_method_call(
2157 "org.freedesktop.systemd1",
2158 "/org/freedesktop/systemd1",
2159 "org.freedesktop.systemd1.Manager",
2160 "StartTransientUnit",
2165 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2169 r = sd_bus_message_open_container(m, 'a', "(sv)");
2173 if (!isempty(slice)) {
2174 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2179 if (!isempty(description)) {
2180 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2185 if (!isempty(description)) {
2186 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2191 if (!isempty(kill_mode)) {
2192 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2197 /* cgroup empty notification is not available in containers
2198 * currently. To make this less problematic, let's shorten the
2199 * stop timeout for sessions, so that we don't wait
2202 r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2206 /* Make sure that the session shells are terminated with
2207 * SIGHUP since bash and friends tend to ignore SIGTERM */
2208 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2212 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2216 r = sd_bus_message_close_container(m);
2220 r = sd_bus_call(manager->bus, m, 0, error, &reply);
2228 r = sd_bus_message_read(reply, "o", &j);
2242 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2243 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2249 r = sd_bus_call_method(
2251 "org.freedesktop.systemd1",
2252 "/org/freedesktop/systemd1",
2253 "org.freedesktop.systemd1.Manager",
2257 "ss", unit, "fail");
2265 r = sd_bus_message_read(reply, "o", &j);
2279 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2280 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2286 r = sd_bus_call_method(
2288 "org.freedesktop.systemd1",
2289 "/org/freedesktop/systemd1",
2290 "org.freedesktop.systemd1.Manager",
2294 "ss", unit, "fail");
2296 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2297 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2302 sd_bus_error_free(error);
2313 r = sd_bus_message_read(reply, "o", &j);
2327 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2331 return sd_bus_call_method(
2333 "org.freedesktop.systemd1",
2334 "/org/freedesktop/systemd1",
2335 "org.freedesktop.systemd1.Manager",
2339 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2342 int manager_unit_is_active(Manager *manager, const char *unit) {
2343 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2344 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2345 _cleanup_free_ char *path = NULL;
2352 path = unit_dbus_path_from_name(unit);
2356 r = sd_bus_get_property(
2358 "org.freedesktop.systemd1",
2360 "org.freedesktop.systemd1.Unit",
2366 /* systemd might have droppped off momentarily, let's
2367 * not make this an error */
2368 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2369 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2372 /* If the unit is already unloaded then it's not
2374 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2375 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2381 r = sd_bus_message_read(reply, "s", &state);
2385 return !streq(state, "inactive") && !streq(state, "failed");
2388 int manager_job_is_active(Manager *manager, const char *path) {
2389 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2390 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2396 r = sd_bus_get_property(
2398 "org.freedesktop.systemd1",
2400 "org.freedesktop.systemd1.Job",
2406 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2407 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2410 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2416 /* We don't actually care about the state really. The fact
2417 * that we could read the job state is enough for us */