1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "sd-messages.h"
31 #include "path-util.h"
33 #include "sleep-config.h"
34 #include "fileio-label.h"
37 #include "unit-name.h"
41 #include "bus-error.h"
43 #include "bus-errors.h"
45 static int property_get_idle_hint(
48 const char *interface
,
50 sd_bus_message
*reply
,
52 sd_bus_error
*error
) {
54 Manager
*m
= userdata
;
60 return sd_bus_message_append(reply
, "b", manager_get_idle_hint(m
, NULL
) > 0);
63 static int property_get_idle_since_hint(
66 const char *interface
,
68 sd_bus_message
*reply
,
70 sd_bus_error
*error
) {
72 Manager
*m
= userdata
;
79 manager_get_idle_hint(m
, &t
);
81 return sd_bus_message_append(reply
, "t", streq(property
, "IdleSinceHint") ? t
.realtime
: t
.monotonic
);
84 static int property_get_inhibited(
87 const char *interface
,
89 sd_bus_message
*reply
,
91 sd_bus_error
*error
) {
93 Manager
*m
= userdata
;
100 w
= manager_inhibit_what(m
, streq(property
, "BlockInhibited") ? INHIBIT_BLOCK
: INHIBIT_DELAY
);
102 return sd_bus_message_append(reply
, "s", inhibit_what_to_string(w
));
105 static int property_get_preparing(
108 const char *interface
,
109 const char *property
,
110 sd_bus_message
*reply
,
112 sd_bus_error
*error
) {
114 Manager
*m
= userdata
;
121 if (streq(property
, "PreparingForShutdown"))
122 b
= !!(m
->action_what
& INHIBIT_SHUTDOWN
);
124 b
= !!(m
->action_what
& INHIBIT_SLEEP
);
126 return sd_bus_message_append(reply
, "b", b
);
129 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action
, handle_action
, HandleAction
);
131 static int method_get_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
132 _cleanup_free_
char *p
= NULL
;
133 Manager
*m
= userdata
;
142 r
= sd_bus_message_read(message
, "s", &name
);
146 session
= hashmap_get(m
->sessions
, name
);
148 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
150 p
= session_bus_path(session
);
154 return sd_bus_reply_method_return(message
, "o", p
);
157 static int method_get_session_by_pid(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
158 _cleanup_free_
char *p
= NULL
;
159 Session
*session
= NULL
;
160 Manager
*m
= userdata
;
168 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
170 r
= sd_bus_message_read(message
, "u", &pid
);
175 r
= sd_bus_get_owner_pid(bus
, sd_bus_message_get_sender(message
), &pid
);
180 r
= manager_get_session_by_pid(m
, pid
, &session
);
184 return sd_bus_error_setf(error
, BUS_ERROR_NO_SESSION_FOR_PID
, "PID %lu does not belong to any known session", (unsigned long) pid
);
186 p
= session_bus_path(session
);
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
, sd_bus_error
*error
) {
194 _cleanup_free_
char *p
= NULL
;
195 Manager
*m
= userdata
;
204 r
= sd_bus_message_read(message
, "u", &uid
);
208 user
= hashmap_get(m
->users
, ULONG_TO_PTR((unsigned long) uid
));
210 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_USER
, "No user '%lu' known or logged in", (unsigned long) uid
);
212 p
= user_bus_path(user
);
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
, sd_bus_error
*error
) {
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
);
237 r
= sd_bus_get_owner_pid(bus
, sd_bus_message_get_sender(message
), &pid
);
242 r
= manager_get_user_by_pid(m
, pid
, &user
);
246 return sd_bus_error_setf(error
, BUS_ERROR_NO_USER_FOR_PID
, "PID %lu does not belong to any known or logged in user", (unsigned long) pid
);
248 p
= user_bus_path(user
);
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
, sd_bus_error
*error
) {
256 _cleanup_free_
char *p
= NULL
;
257 Manager
*m
= userdata
;
266 r
= sd_bus_message_read(message
, "s", &name
);
270 seat
= hashmap_get(m
->seats
, name
);
272 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "No seat '%s' known", name
);
274 p
= seat_bus_path(seat
);
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
, sd_bus_error
*error
) {
282 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
283 Manager
*m
= userdata
;
292 r
= sd_bus_message_new_method_return(message
, &reply
);
296 r
= sd_bus_message_open_container(reply
, 'a', "(susso)");
300 HASHMAP_FOREACH(session
, m
->sessions
, i
) {
301 _cleanup_free_
char *p
= NULL
;
303 p
= session_bus_path(session
);
307 r
= sd_bus_message_append(reply
, "(susso)",
309 (uint32_t) session
->user
->uid
,
311 session
->seat
? session
->seat
->id
: "",
317 r
= sd_bus_message_close_container(reply
);
321 return sd_bus_send(bus
, reply
, NULL
);
324 static int method_list_users(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
325 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
326 Manager
*m
= userdata
;
335 r
= sd_bus_message_new_method_return(message
, &reply
);
339 r
= sd_bus_message_open_container(reply
, 'a', "(uso)");
343 HASHMAP_FOREACH(user
, m
->users
, i
) {
344 _cleanup_free_
char *p
= NULL
;
346 p
= user_bus_path(user
);
350 r
= sd_bus_message_append(reply
, "(uso)",
351 (uint32_t) user
->uid
,
358 r
= sd_bus_message_close_container(reply
);
362 return sd_bus_send(bus
, reply
, NULL
);
365 static int method_list_seats(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
366 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
367 Manager
*m
= userdata
;
376 r
= sd_bus_message_new_method_return(message
, &reply
);
380 r
= sd_bus_message_open_container(reply
, 'a', "(so)");
384 HASHMAP_FOREACH(seat
, m
->seats
, i
) {
385 _cleanup_free_
char *p
= NULL
;
387 p
= seat_bus_path(seat
);
391 r
= sd_bus_message_append(reply
, "(so)", seat
->id
, p
);
396 r
= sd_bus_message_close_container(reply
);
400 return sd_bus_send(bus
, reply
, NULL
);
403 static int method_list_inhibitors(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
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
);
414 r
= sd_bus_message_open_container(reply
, 'a', "(ssssuu)");
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
);
431 r
= sd_bus_message_close_container(reply
);
435 return sd_bus_send(bus
, reply
, NULL
);
438 static int method_create_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
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
);
461 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid leader PID");
464 t
= _SESSION_TYPE_INVALID
;
466 t
= session_type_from_string(type
);
468 return sd_bus_error_setf(error
, 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_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid session class %s", class);
482 seat
= hashmap_get(m
->seats
, cseat
);
484 return sd_bus_error_setf(error
, 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_error_setf(error
, 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_error_setf(error
, 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_error_setf(error
, 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_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Console TTY specified but seat is not seat0");
512 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Console TTY specified but VT number is not 0");
516 if (seat_has_vts(seat
)) {
518 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "VT number out of range");
521 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Seat has no VTs but VT number not 0");
525 r
= sd_bus_message_enter_container(message
, 'a', "(sv)");
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
);
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
);
566 path
= session_bus_path(session
);
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)
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)
609 } while (hashmap_get(m
->sessions
, id
));
612 r
= manager_add_user_by_uid(m
, uid
, &user
);
616 r
= manager_add_session(m
, id
, &session
);
620 session_set_user(session
, user
);
622 session
->leader
= leader
;
623 session
->audit_id
= audit_id
;
626 session
->remote
= remote
;
627 session
->vtnr
= vtnr
;
630 session
->tty
= strdup(tty
);
637 if (!isempty(display
)) {
638 session
->display
= strdup(display
);
639 if (!session
->display
) {
645 if (!isempty(remote_user
)) {
646 session
->remote_user
= strdup(remote_user
);
647 if (!session
->remote_user
) {
653 if (!isempty(remote_host
)) {
654 session
->remote_host
= strdup(remote_host
);
655 if (!session
->remote_host
) {
661 if (!isempty(service
)) {
662 session
->service
= strdup(service
);
663 if (!session
->service
) {
670 r
= seat_attach_session(seat
, session
);
675 r
= session_start(session
);
679 session
->create_message
= sd_bus_message_ref(message
);
681 /* Now, let's wait until the slice unit and stuff got
682 * created. We send the reply back from
683 * session_send_create_reply().*/
689 session_add_to_gc_queue(session
);
692 user_add_to_gc_queue(user
);
697 static int method_release_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
698 Manager
*m
= userdata
;
707 r
= sd_bus_message_read(message
, "s", &name
);
711 session
= hashmap_get(m
->sessions
, name
);
713 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
715 /* We use the FIFO to detect stray sessions where the process
716 invoking PAM dies abnormally. We need to make sure that
717 that process is not killed if at the clean end of the
718 session it closes the FIFO. Hence, with this call
719 explicitly turn off the FIFO logic, so that the PAM code
720 can finish clean up on its own */
721 session_remove_fifo(session
);
722 session_save(session
);
723 user_save(session
->user
);
725 return sd_bus_reply_method_return(message
, NULL
);
728 static int method_activate_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
729 Manager
*m
= userdata
;
738 r
= sd_bus_message_read(message
, "s", &name
);
742 session
= hashmap_get(m
->sessions
, name
);
744 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
746 r
= session_activate(session
);
750 return sd_bus_reply_method_return(message
, NULL
);
753 static int method_activate_session_on_seat(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
754 const char *session_name
, *seat_name
;
755 Manager
*m
= userdata
;
764 /* Same as ActivateSession() but refuses to work if
765 * the seat doesn't match */
767 r
= sd_bus_message_read(message
, "ss", &session_name
, &seat_name
);
771 session
= hashmap_get(m
->sessions
, session_name
);
773 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", session_name
);
775 seat
= hashmap_get(m
->seats
, seat_name
);
777 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "No seat '%s' known", seat_name
);
779 if (session
->seat
!= seat
)
780 return sd_bus_error_setf(error
, BUS_ERROR_SESSION_NOT_ON_SEAT
, "Session %s not on seat %s", session_name
, seat_name
);
782 r
= session_activate(session
);
786 return sd_bus_reply_method_return(message
, NULL
);
789 static int method_lock_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
790 Manager
*m
= userdata
;
799 r
= sd_bus_message_read(message
, "s", &name
);
803 session
= hashmap_get(m
->sessions
, name
);
805 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
807 r
= session_send_lock(session
, streq(sd_bus_message_get_member(message
), "LockSession"));
811 return sd_bus_reply_method_return(message
, NULL
);
814 static int method_lock_sessions(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
815 Manager
*m
= userdata
;
822 r
= session_send_lock_all(m
, streq(sd_bus_message_get_member(message
), "LockSessions"));
826 return sd_bus_reply_method_return(message
, NULL
);
829 static int method_kill_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
830 const char *name
, *swho
;
831 Manager
*m
= userdata
;
841 r
= sd_bus_message_read(message
, "ssi", &name
, &swho
, &signo
);
848 who
= kill_who_from_string(swho
);
850 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid kill parameter '%s'", swho
);
853 if (signo
<= 0 || signo
>= _NSIG
)
854 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid signal %i", signo
);
856 session
= hashmap_get(m
->sessions
, name
);
858 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
860 r
= session_kill(session
, who
, signo
);
864 return sd_bus_reply_method_return(message
, NULL
);
867 static int method_kill_user(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
868 Manager
*m
= userdata
;
878 r
= sd_bus_message_read(message
, "ui", &uid
, &signo
);
882 if (signo
<= 0 || signo
>= _NSIG
)
883 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid signal %i", signo
);
885 user
= hashmap_get(m
->users
, ULONG_TO_PTR((unsigned long) uid
));
887 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_USER
, "No user '%lu' known or logged in", (unsigned long) uid
);
889 r
= user_kill(user
, signo
);
893 return sd_bus_reply_method_return(message
, NULL
);
896 static int method_terminate_session(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
897 Manager
*m
= userdata
;
906 r
= sd_bus_message_read(message
, "s", &name
);
910 session
= hashmap_get(m
->sessions
, name
);
912 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
914 r
= session_stop(session
);
918 return sd_bus_reply_method_return(message
, NULL
);
921 static int method_terminate_user(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
922 Manager
*m
= userdata
;
931 r
= sd_bus_message_read(message
, "u", &uid
);
935 user
= hashmap_get(m
->users
, ULONG_TO_PTR((unsigned long) uid
));
937 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_USER
, "No user '%lu' known or logged in", (unsigned long) uid
);
943 return sd_bus_reply_method_return(message
, NULL
);
946 static int method_terminate_seat(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
947 Manager
*m
= userdata
;
956 r
= sd_bus_message_read(message
, "s", &name
);
960 seat
= hashmap_get(m
->seats
, name
);
962 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "No seat '%s' known", name
);
964 r
= seat_stop_sessions(seat
);
968 return sd_bus_reply_method_return(message
, NULL
);
971 static int method_set_user_linger(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
972 _cleanup_free_
char *cc
= NULL
;
973 Manager
*m
= userdata
;
984 r
= sd_bus_message_read(message
, "ubb", &uid
, &b
, &interactive
);
991 return errno
? -errno
: -ENOENT
;
993 r
= bus_verify_polkit_async(bus
,
996 "org.freedesktop.login1.set-user-linger",
999 method_set_user_linger
, m
);
1003 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1005 mkdir_p_label("/var/lib/systemd", 0755);
1007 r
= mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1011 cc
= cescape(pw
->pw_name
);
1015 path
= strappenda("/var/lib/systemd/linger/", cc
);
1023 if (manager_add_user_by_uid(m
, uid
, &u
) >= 0)
1030 if (r
< 0 && errno
!= ENOENT
)
1033 u
= hashmap_get(m
->users
, ULONG_TO_PTR((unsigned long) uid
));
1035 user_add_to_gc_queue(u
);
1038 return sd_bus_reply_method_return(message
, NULL
);
1041 static int trigger_device(Manager
*m
, struct udev_device
*d
) {
1042 struct udev_enumerate
*e
;
1043 struct udev_list_entry
*first
, *item
;
1048 e
= udev_enumerate_new(m
->udev
);
1055 if (udev_enumerate_add_match_parent(e
, d
) < 0) {
1061 if (udev_enumerate_scan_devices(e
) < 0) {
1066 first
= udev_enumerate_get_list_entry(e
);
1067 udev_list_entry_foreach(item
, first
) {
1068 _cleanup_free_
char *t
= NULL
;
1071 p
= udev_list_entry_get_name(item
);
1073 t
= strappend(p
, "/uevent");
1079 write_string_file(t
, "change");
1086 udev_enumerate_unref(e
);
1091 static int attach_device(Manager
*m
, const char *seat
, const char *sysfs
) {
1092 _cleanup_free_
char *rule
= NULL
, *file
= NULL
;
1093 const char *id_for_seat
;
1094 struct udev_device
*d
;
1101 d
= udev_device_new_from_syspath(m
->udev
, sysfs
);
1105 if (!udev_device_has_tag(d
, "seat")) {
1110 id_for_seat
= udev_device_get_property_value(d
, "ID_FOR_SEAT");
1116 if (asprintf(&file
, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat
) < 0) {
1121 if (asprintf(&rule
, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat
, seat
) < 0) {
1126 mkdir_p_label("/etc/udev/rules.d", 0755);
1128 r
= write_string_file_atomic_label(file
, rule
);
1132 r
= trigger_device(m
, d
);
1136 udev_device_unref(d
);
1141 static int flush_devices(Manager
*m
) {
1142 _cleanup_closedir_
DIR *d
;
1146 d
= opendir("/etc/udev/rules.d");
1148 if (errno
!= ENOENT
)
1149 log_warning("Failed to open /etc/udev/rules.d: %m");
1153 while ((de
= readdir(d
))) {
1155 if (!dirent_is_file(de
))
1158 if (!startswith(de
->d_name
, "72-seat-"))
1161 if (!endswith(de
->d_name
, ".rules"))
1164 if (unlinkat(dirfd(d
), de
->d_name
, 0) < 0)
1165 log_warning("Failed to unlink %s: %m", de
->d_name
);
1169 return trigger_device(m
, NULL
);
1172 static int method_attach_device(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1173 const char *sysfs
, *seat
;
1174 Manager
*m
= userdata
;
1181 r
= sd_bus_message_read(message
, "ssb", &seat
, &sysfs
, &interactive
);
1185 if (!path_startswith(sysfs
, "/sys"))
1186 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not in /sys", sysfs
);
1188 if (!seat_name_is_valid(seat
))
1189 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Seat %s is not valid", seat
);
1191 r
= bus_verify_polkit_async(bus
,
1192 &m
->polkit_registry
,
1194 "org.freedesktop.login1.attach-device",
1197 method_attach_device
, m
);
1201 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1203 r
= attach_device(m
, seat
, sysfs
);
1207 return sd_bus_reply_method_return(message
, NULL
);
1210 static int method_flush_devices(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1211 Manager
*m
= userdata
;
1218 r
= sd_bus_message_read(message
, "b", &interactive
);
1222 r
= bus_verify_polkit_async(bus
,
1223 &m
->polkit_registry
,
1225 "org.freedesktop.login1.flush-devices",
1228 method_flush_devices
, m
);
1232 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1234 r
= flush_devices(m
);
1238 return sd_bus_reply_method_return(message
, NULL
);
1241 static int have_multiple_sessions(
1250 /* Check for other users' sessions. Greeter sessions do not
1251 * count, and non-login sessions do not count either. */
1252 HASHMAP_FOREACH(session
, m
->sessions
, i
)
1253 if (session
->class == SESSION_USER
&&
1254 !session
->closing
&&
1255 session
->user
->uid
!= uid
)
1261 static int bus_manager_log_shutdown(
1264 const char *unit_name
) {
1271 if (w
!= INHIBIT_SHUTDOWN
)
1274 if (streq(unit_name
, SPECIAL_POWEROFF_TARGET
)) {
1275 p
= "MESSAGE=System is powering down.";
1276 q
= "SHUTDOWN=power-off";
1277 } else if (streq(unit_name
, SPECIAL_HALT_TARGET
)) {
1278 p
= "MESSAGE=System is halting.";
1279 q
= "SHUTDOWN=halt";
1280 } else if (streq(unit_name
, SPECIAL_REBOOT_TARGET
)) {
1281 p
= "MESSAGE=System is rebooting.";
1282 q
= "SHUTDOWN=reboot";
1283 } else if (streq(unit_name
, SPECIAL_KEXEC_TARGET
)) {
1284 p
= "MESSAGE=System is rebooting with kexec.";
1285 q
= "SHUTDOWN=kexec";
1287 p
= "MESSAGE=System is shutting down.";
1291 return log_struct(LOG_NOTICE
, MESSAGE_ID(SD_MESSAGE_SHUTDOWN
),
1296 static int execute_shutdown_or_sleep(
1299 const char *unit_name
,
1300 sd_bus_error
*error
) {
1302 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1309 assert(w
< _INHIBIT_WHAT_MAX
);
1312 bus_manager_log_shutdown(m
, w
, unit_name
);
1314 r
= sd_bus_call_method(
1316 "org.freedesktop.systemd1",
1317 "/org/freedesktop/systemd1",
1318 "org.freedesktop.systemd1.Manager",
1322 "ss", unit_name
, "replace-irreversibly");
1326 r
= sd_bus_message_read(reply
, "o", &p
);
1334 m
->action_unit
= unit_name
;
1335 free(m
->action_job
);
1342 static int delay_shutdown_or_sleep(
1345 const char *unit_name
) {
1349 assert(w
< _INHIBIT_WHAT_MAX
);
1352 m
->action_timestamp
= now(CLOCK_MONOTONIC
);
1353 m
->action_unit
= unit_name
;
1359 static int send_prepare_for(Manager
*m
, InhibitWhat w
, bool _active
) {
1361 static const char * const signal_name
[_INHIBIT_WHAT_MAX
] = {
1362 [INHIBIT_SHUTDOWN
] = "PrepareForShutdown",
1363 [INHIBIT_SLEEP
] = "PrepareForSleep"
1366 int active
= _active
;
1370 assert(w
< _INHIBIT_WHAT_MAX
);
1371 assert(signal_name
[w
]);
1373 return sd_bus_emit_signal(m
->bus
,
1374 "/org/freedesktop/login1",
1375 "org.freedesktop.login1.Manager",
1381 int bus_manager_shutdown_or_sleep_now_or_later(
1383 const char *unit_name
,
1385 sd_bus_error
*error
) {
1393 assert(w
<= _INHIBIT_WHAT_MAX
);
1394 assert(!m
->action_job
);
1396 /* Tell everybody to prepare for shutdown/sleep */
1397 send_prepare_for(m
, w
, true);
1400 m
->inhibit_delay_max
> 0 &&
1401 manager_is_inhibited(m
, w
, INHIBIT_DELAY
, NULL
, false, false, 0);
1404 /* Shutdown is delayed, keep in mind what we
1405 * want to do, and start a timeout */
1406 r
= delay_shutdown_or_sleep(m
, w
, unit_name
);
1408 /* Shutdown is not delayed, execute it
1410 r
= execute_shutdown_or_sleep(m
, w
, unit_name
, error
);
1415 static int method_do_shutdown_or_sleep(
1417 sd_bus_message
*message
,
1418 const char *unit_name
,
1421 const char *action_multiple_sessions
,
1422 const char *action_ignore_inhibit
,
1423 const char *sleep_verb
,
1424 sd_bus_message_handler_t method
,
1425 sd_bus_error
*error
) {
1427 bool multiple_sessions
, blocked
;
1435 assert(w
<= _INHIBIT_WHAT_MAX
);
1437 assert(action_multiple_sessions
);
1438 assert(action_ignore_inhibit
);
1441 r
= sd_bus_message_read(message
, "b", &interactive
);
1445 /* Don't allow multiple jobs being executed at the same time */
1447 return sd_bus_error_setf(error
, BUS_ERROR_OPERATION_IN_PROGRESS
, "There's already a shutdown or sleep operation in progress");
1450 r
= can_sleep(sleep_verb
);
1455 return sd_bus_error_setf(error
, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED
, "Sleep verb not supported");
1458 r
= sd_bus_get_owner_uid(m
->bus
, sd_bus_message_get_sender(message
), &uid
);
1462 r
= have_multiple_sessions(m
, uid
);
1466 multiple_sessions
= r
> 0;
1467 blocked
= manager_is_inhibited(m
, w
, INHIBIT_BLOCK
, NULL
, false, true, uid
);
1469 if (multiple_sessions
) {
1470 r
= bus_verify_polkit_async(m
->bus
, &m
->polkit_registry
, message
,
1471 action_multiple_sessions
, interactive
, error
, method
, m
);
1477 r
= bus_verify_polkit_async(m
->bus
, &m
->polkit_registry
, message
,
1478 action_ignore_inhibit
, interactive
, error
, method
, m
);
1483 if (!multiple_sessions
&& !blocked
) {
1484 r
= bus_verify_polkit_async(m
->bus
, &m
->polkit_registry
, message
,
1485 action
, interactive
, error
, method
, m
);
1490 r
= bus_manager_shutdown_or_sleep_now_or_later(m
, unit_name
, w
, error
);
1494 return sd_bus_reply_method_return(message
, NULL
);
1497 static int method_poweroff(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1498 Manager
*m
= userdata
;
1500 return method_do_shutdown_or_sleep(
1502 SPECIAL_POWEROFF_TARGET
,
1504 "org.freedesktop.login1.power-off",
1505 "org.freedesktop.login1.power-off-multiple-sessions",
1506 "org.freedesktop.login1.power-off-ignore-inhibit",
1512 static int method_reboot(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1513 Manager
*m
= userdata
;
1515 return method_do_shutdown_or_sleep(
1517 SPECIAL_REBOOT_TARGET
,
1519 "org.freedesktop.login1.reboot",
1520 "org.freedesktop.login1.reboot-multiple-sessions",
1521 "org.freedesktop.login1.reboot-ignore-inhibit",
1527 static int method_suspend(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1528 Manager
*m
= userdata
;
1530 return method_do_shutdown_or_sleep(
1532 SPECIAL_SUSPEND_TARGET
,
1534 "org.freedesktop.login1.suspend",
1535 "org.freedesktop.login1.suspend-multiple-sessions",
1536 "org.freedesktop.login1.suspend-ignore-inhibit",
1542 static int method_hibernate(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1543 Manager
*m
= userdata
;
1545 return method_do_shutdown_or_sleep(
1547 SPECIAL_HIBERNATE_TARGET
,
1549 "org.freedesktop.login1.hibernate",
1550 "org.freedesktop.login1.hibernate-multiple-sessions",
1551 "org.freedesktop.login1.hibernate-ignore-inhibit",
1557 static int method_hybrid_sleep(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1558 Manager
*m
= userdata
;
1560 return method_do_shutdown_or_sleep(
1562 SPECIAL_HYBRID_SLEEP_TARGET
,
1564 "org.freedesktop.login1.hibernate",
1565 "org.freedesktop.login1.hibernate-multiple-sessions",
1566 "org.freedesktop.login1.hibernate-ignore-inhibit",
1568 method_hybrid_sleep
,
1572 static int method_can_shutdown_or_sleep(
1574 sd_bus_message
*message
,
1577 const char *action_multiple_sessions
,
1578 const char *action_ignore_inhibit
,
1579 const char *sleep_verb
,
1580 sd_bus_error
*error
) {
1582 bool multiple_sessions
, challenge
, blocked
;
1583 const char *result
= NULL
;
1590 assert(w
<= _INHIBIT_WHAT_MAX
);
1592 assert(action_multiple_sessions
);
1593 assert(action_ignore_inhibit
);
1596 r
= can_sleep(sleep_verb
);
1600 return sd_bus_reply_method_return(message
, "s", "na");
1603 r
= sd_bus_get_owner_uid(m
->bus
, sd_bus_message_get_sender(message
), &uid
);
1607 r
= have_multiple_sessions(m
, uid
);
1611 multiple_sessions
= r
> 0;
1612 blocked
= manager_is_inhibited(m
, w
, INHIBIT_BLOCK
, NULL
, false, true, uid
);
1614 if (multiple_sessions
) {
1615 r
= bus_verify_polkit(m
->bus
, message
, action_multiple_sessions
, false, &challenge
, error
);
1622 result
= "challenge";
1628 r
= bus_verify_polkit(m
->bus
, message
, action_ignore_inhibit
, false, &challenge
, error
);
1632 if (r
> 0 && !result
)
1634 else if (challenge
&& (!result
|| streq(result
, "yes")))
1635 result
= "challenge";
1640 if (!multiple_sessions
&& !blocked
) {
1641 /* If neither inhibit nor multiple sessions
1642 * apply then just check the normal policy */
1644 r
= bus_verify_polkit(m
->bus
, message
, action
, false, &challenge
, error
);
1651 result
= "challenge";
1656 return sd_bus_reply_method_return(message
, "s", result
);
1659 static int method_can_poweroff(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1660 Manager
*m
= userdata
;
1662 return method_can_shutdown_or_sleep(
1665 "org.freedesktop.login1.power-off",
1666 "org.freedesktop.login1.power-off-multiple-sessions",
1667 "org.freedesktop.login1.power-off-ignore-inhibit",
1672 static int method_can_reboot(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1673 Manager
*m
= userdata
;
1675 return method_can_shutdown_or_sleep(
1678 "org.freedesktop.login1.reboot",
1679 "org.freedesktop.login1.reboot-multiple-sessions",
1680 "org.freedesktop.login1.reboot-ignore-inhibit",
1685 static int method_can_suspend(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1686 Manager
*m
= userdata
;
1688 return method_can_shutdown_or_sleep(
1691 "org.freedesktop.login1.suspend",
1692 "org.freedesktop.login1.suspend-multiple-sessions",
1693 "org.freedesktop.login1.suspend-ignore-inhibit",
1698 static int method_can_hibernate(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1699 Manager
*m
= userdata
;
1701 return method_can_shutdown_or_sleep(
1704 "org.freedesktop.login1.hibernate",
1705 "org.freedesktop.login1.hibernate-multiple-sessions",
1706 "org.freedesktop.login1.hibernate-ignore-inhibit",
1711 static int method_can_hybrid_sleep(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1712 Manager
*m
= userdata
;
1714 return method_can_shutdown_or_sleep(
1717 "org.freedesktop.login1.hibernate",
1718 "org.freedesktop.login1.hibernate-multiple-sessions",
1719 "org.freedesktop.login1.hibernate-ignore-inhibit",
1724 static int method_inhibit(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1725 const char *who
, *why
, *what
, *mode
;
1726 _cleanup_free_
char *id
= NULL
;
1727 _cleanup_close_
int fifo_fd
= -1;
1728 Manager
*m
= userdata
;
1729 Inhibitor
*i
= NULL
;
1740 r
= sd_bus_message_read(message
, "ssss", &what
, &who
, &why
, &mode
);
1744 w
= inhibit_what_from_string(what
);
1746 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid what specification %s", what
);
1748 mm
= inhibit_mode_from_string(mode
);
1750 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid mode specification %s", mode
);
1752 /* Delay is only supported for shutdown/sleep */
1753 if (mm
== INHIBIT_DELAY
&& (w
& ~(INHIBIT_SHUTDOWN
|INHIBIT_SLEEP
)))
1754 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delay inhibitors only supported for shutdown and sleep");
1756 /* Don't allow taking delay locks while we are already
1757 * executing the operation. We shouldn't create the impression
1758 * that the lock was successful if the machine is about to go
1759 * down/suspend any moment. */
1760 if (m
->action_what
& w
)
1761 return sd_bus_error_setf(error
, BUS_ERROR_OPERATION_IN_PROGRESS
, "The operation inhibition has been requested for is already running");
1763 r
= bus_verify_polkit_async(bus
, &m
->polkit_registry
, message
,
1764 w
== INHIBIT_SHUTDOWN
? (mm
== INHIBIT_BLOCK
? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1765 w
== INHIBIT_SLEEP
? (mm
== INHIBIT_BLOCK
? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1766 w
== INHIBIT_IDLE
? "org.freedesktop.login1.inhibit-block-idle" :
1767 w
== INHIBIT_HANDLE_POWER_KEY
? "org.freedesktop.login1.inhibit-handle-power-key" :
1768 w
== INHIBIT_HANDLE_SUSPEND_KEY
? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1769 w
== INHIBIT_HANDLE_HIBERNATE_KEY
? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1770 "org.freedesktop.login1.inhibit-handle-lid-switch",
1771 false, error
, method_inhibit
, m
);
1775 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1777 r
= sd_bus_get_owner_uid(m
->bus
, sd_bus_message_get_sender(message
), &uid
);
1781 r
= sd_bus_get_owner_pid(m
->bus
, sd_bus_message_get_sender(message
), &pid
);
1789 if (asprintf(&id
, "%lu", ++m
->inhibit_counter
) < 0)
1792 } while (hashmap_get(m
->inhibitors
, id
));
1794 r
= manager_add_inhibitor(m
, id
, &i
);
1802 i
->why
= strdup(why
);
1803 i
->who
= strdup(who
);
1805 if (!i
->why
|| !i
->who
) {
1810 fifo_fd
= inhibitor_create_fifo(i
);
1818 return sd_bus_reply_method_return(message
, "h", fifo_fd
);
1827 const sd_bus_vtable manager_vtable
[] = {
1828 SD_BUS_VTABLE_START(0),
1830 SD_BUS_PROPERTY("NAutoVTs", "u", NULL
, offsetof(Manager
, n_autovts
), 0),
1831 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL
, offsetof(Manager
, kill_only_users
), 0),
1832 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL
, offsetof(Manager
, kill_exclude_users
), 0),
1833 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL
, offsetof(Manager
, kill_user_processes
), 0),
1834 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1835 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1836 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1837 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1838 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1839 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL
, offsetof(Manager
, inhibit_delay_max
), 0),
1840 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action
, offsetof(Manager
, handle_power_key
), 0),
1841 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action
, offsetof(Manager
, handle_suspend_key
), 0),
1842 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action
, offsetof(Manager
, handle_hibernate_key
), 0),
1843 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action
, offsetof(Manager
, handle_lid_switch
), 0),
1844 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action
, offsetof(Manager
, idle_action
), 0),
1845 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL
, offsetof(Manager
, idle_action_usec
), 0),
1846 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing
, 0, 0),
1847 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing
, 0, 0),
1849 SD_BUS_METHOD("GetSession", "s", "o", method_get_session
, 0),
1850 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid
, 0),
1851 SD_BUS_METHOD("GetUser", "u", "o", method_get_user
, 0),
1852 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid
, 0),
1853 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat
, 0),
1854 SD_BUS_METHOD("ListSessions", NULL
, "a(susso)", method_list_sessions
, 0),
1855 SD_BUS_METHOD("ListUsers", NULL
, "a(uso)", method_list_users
, 0),
1856 SD_BUS_METHOD("ListSeats", NULL
, "a(so)", method_list_seats
, 0),
1857 SD_BUS_METHOD("ListInhibitors", NULL
, "a(ssssuu)", method_list_inhibitors
, 0),
1858 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshsub", method_create_session
, 0),
1859 SD_BUS_METHOD("ReleaseSession", "s", NULL
, method_release_session
, 0),
1860 SD_BUS_METHOD("ActivateSession", "s", NULL
, method_activate_session
, 0),
1861 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL
, method_activate_session_on_seat
, 0),
1862 SD_BUS_METHOD("LockSession", "s", NULL
, method_lock_session
, 0),
1863 SD_BUS_METHOD("UnlockSession", "s", NULL
, method_lock_session
, 0),
1864 SD_BUS_METHOD("LockSessions", NULL
, NULL
, method_lock_sessions
, 0),
1865 SD_BUS_METHOD("UnlockSessions", NULL
, NULL
, method_lock_sessions
, 0),
1866 SD_BUS_METHOD("KillSession", "ssi", NULL
, method_kill_session
, 0),
1867 SD_BUS_METHOD("KillUser", "ui", NULL
, method_kill_user
, 0),
1868 SD_BUS_METHOD("TerminateSession", "s", NULL
, method_terminate_session
, 0),
1869 SD_BUS_METHOD("TerminateUser", "u", NULL
, method_terminate_user
, 0),
1870 SD_BUS_METHOD("TerminateSeat", "s", NULL
, method_terminate_seat
, 0),
1871 SD_BUS_METHOD("SetUserLinger", "ubb", NULL
, method_set_user_linger
, 0),
1872 SD_BUS_METHOD("AttachDevice", "ssb", NULL
, method_attach_device
, 0),
1873 SD_BUS_METHOD("FlushDevices", "b", NULL
, method_flush_devices
, 0),
1874 SD_BUS_METHOD("PowerOff", "b", NULL
, method_poweroff
, 0),
1875 SD_BUS_METHOD("Reboot", "b", NULL
, method_reboot
, 0),
1876 SD_BUS_METHOD("Suspend", "b", NULL
, method_suspend
, 0),
1877 SD_BUS_METHOD("Hibernate", "b", NULL
, method_hibernate
, 0),
1878 SD_BUS_METHOD("HybridSleep", "b", NULL
, method_hybrid_sleep
, 0),
1879 SD_BUS_METHOD("CanPowerOff", NULL
, "s", method_can_poweroff
, 0),
1880 SD_BUS_METHOD("CanReboot", NULL
, "s", method_can_reboot
, 0),
1881 SD_BUS_METHOD("CanSuspend", NULL
, "s", method_can_suspend
, 0),
1882 SD_BUS_METHOD("CanHibernate", NULL
, "s", method_can_hibernate
, 0),
1883 SD_BUS_METHOD("CanHybridSleep", NULL
, "s", method_can_hybrid_sleep
, 0),
1884 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit
, 0),
1886 SD_BUS_SIGNAL("SessionNew", "so", 0),
1887 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1888 SD_BUS_SIGNAL("UserNew", "uo", 0),
1889 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1890 SD_BUS_SIGNAL("SeatNew", "so", 0),
1891 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1892 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1893 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1898 int match_job_removed(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1899 const char *path
, *result
, *unit
;
1900 Manager
*m
= userdata
;
1910 r
= sd_bus_message_read(message
, "uoss", &id
, &path
, &unit
, &result
);
1912 bus_log_parse_error(r
);
1916 if (m
->action_job
&& streq(m
->action_job
, path
)) {
1917 log_info("Operation finished.");
1919 /* Tell people that they now may take a lock again */
1920 send_prepare_for(m
, m
->action_what
, false);
1922 free(m
->action_job
);
1923 m
->action_job
= NULL
;
1924 m
->action_unit
= NULL
;
1929 session
= hashmap_get(m
->session_units
, unit
);
1932 if (streq_ptr(path
, session
->scope_job
)) {
1933 free(session
->scope_job
);
1934 session
->scope_job
= NULL
;
1937 if (session
->started
) {
1938 if (streq(result
, "done"))
1939 session_send_create_reply(session
, NULL
);
1941 _cleanup_bus_error_free_ sd_bus_error e
= SD_BUS_ERROR_NULL
;
1943 sd_bus_error_setf(&e
, BUS_ERROR_JOB_FAILED
, "Start job for unit %s failed with '%s'", unit
, result
);
1944 session_send_create_reply(session
, &e
);
1947 session_save(session
);
1949 session_add_to_gc_queue(session
);
1952 user
= hashmap_get(m
->user_units
, unit
);
1955 if (streq_ptr(path
, user
->service_job
)) {
1956 free(user
->service_job
);
1957 user
->service_job
= NULL
;
1960 if (streq_ptr(path
, user
->slice_job
)) {
1961 free(user
->slice_job
);
1962 user
->slice_job
= NULL
;
1966 user_add_to_gc_queue(user
);
1972 int match_unit_removed(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1973 const char *path
, *unit
;
1974 Manager
*m
= userdata
;
1983 r
= sd_bus_message_read(message
, "so", &unit
, &path
);
1985 bus_log_parse_error(r
);
1989 session
= hashmap_get(m
->session_units
, unit
);
1991 session_add_to_gc_queue(session
);
1993 user
= hashmap_get(m
->user_units
, unit
);
1995 user_add_to_gc_queue(user
);
2000 int match_properties_changed(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2001 _cleanup_free_
char *unit
= NULL
;
2002 Manager
*m
= userdata
;
2012 path
= sd_bus_message_get_path(message
);
2016 r
= unit_name_from_dbus_path(path
, &unit
);
2020 session
= hashmap_get(m
->session_units
, unit
);
2022 session_add_to_gc_queue(session
);
2024 user
= hashmap_get(m
->user_units
, unit
);
2026 user_add_to_gc_queue(user
);
2031 int match_reloading(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2032 Manager
*m
= userdata
;
2039 r
= sd_bus_message_read(message
, "b", &b
);
2041 bus_log_parse_error(r
);
2048 /* systemd finished reloading, let's recheck all our sessions */
2049 log_debug("System manager has been reloaded, rechecking sessions...");
2051 HASHMAP_FOREACH(session
, m
->sessions
, i
)
2052 session_add_to_gc_queue(session
);
2057 int match_name_owner_changed(sd_bus
*bus
, sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2058 const char *name
, *old
, *new;
2059 Manager
*m
= userdata
;
2067 r
= sd_bus_message_read(message
, "sss", &name
, &old
, &new);
2069 bus_log_parse_error(r
);
2073 if (isempty(old
) || !isempty(new))
2076 key
= set_remove(m
->busnames
, (char*) old
);
2080 /* Drop all controllers owned by this name */
2084 HASHMAP_FOREACH(session
, m
->sessions
, i
)
2085 if (session_is_controller(session
, old
))
2086 session_drop_controller(session
);
2091 int manager_send_changed(Manager
*manager
, const char *property
, ...) {
2096 l
= strv_from_stdarg_alloca(property
);
2098 return sd_bus_emit_properties_changed_strv(
2100 "/org/freedesktop/login1",
2101 "org.freedesktop.login1.Manager",
2105 int manager_dispatch_delayed(Manager
*manager
) {
2106 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2111 if (manager
->action_what
== 0 || manager
->action_job
)
2114 /* Continue delay? */
2115 if (manager_is_inhibited(manager
, manager
->action_what
, INHIBIT_DELAY
, NULL
, false, false, 0)) {
2117 if (manager
->action_timestamp
+ manager
->inhibit_delay_max
> now(CLOCK_MONOTONIC
))
2120 log_info("Delay lock is active but inhibitor timeout is reached.");
2123 /* Actually do the operation */
2124 r
= execute_shutdown_or_sleep(manager
, manager
->action_what
, manager
->action_unit
, &error
);
2126 log_warning("Failed to send delayed message: %s", bus_error_message(&error
, r
));
2128 manager
->action_unit
= NULL
;
2129 manager
->action_what
= 0;
2136 int manager_start_scope(
2141 const char *description
,
2143 const char *kill_mode
,
2144 sd_bus_error
*error
,
2147 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
, *reply
= NULL
;
2154 r
= sd_bus_message_new_method_call(
2156 "org.freedesktop.systemd1",
2157 "/org/freedesktop/systemd1",
2158 "org.freedesktop.systemd1.Manager",
2159 "StartTransientUnit",
2164 r
= sd_bus_message_append(m
, "ss", strempty(scope
), "fail");
2168 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
2172 if (!isempty(slice
)) {
2173 r
= sd_bus_message_append(m
, "(sv)", "Slice", "s", slice
);
2178 if (!isempty(description
)) {
2179 r
= sd_bus_message_append(m
, "(sv)", "Description", "s", description
);
2184 if (!isempty(description
)) {
2185 r
= sd_bus_message_append(m
, "(sv)", "After", "as", 1, after
);
2190 if (!isempty(kill_mode
)) {
2191 r
= sd_bus_message_append(m
, "(sv)", "KillMode", "s", kill_mode
);
2196 /* cgroup empty notification is not available in containers
2197 * currently. To make this less problematic, let's shorten the
2198 * stop timeout for sessions, so that we don't wait
2201 r
= sd_bus_message_append(m
, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC
);
2205 /* Make sure that the session shells are terminated with
2206 * SIGHUP since bash and friends tend to ignore SIGTERM */
2207 r
= sd_bus_message_append(m
, "(sv)", "SendSIGHUP", "b", true);
2211 r
= sd_bus_message_append(m
, "(sv)", "PIDs", "au", 1, pid
);
2215 r
= sd_bus_message_close_container(m
);
2219 r
= sd_bus_call(manager
->bus
, m
, 0, error
, &reply
);
2227 r
= sd_bus_message_read(reply
, "o", &j
);
2241 int manager_start_unit(Manager
*manager
, const char *unit
, sd_bus_error
*error
, char **job
) {
2242 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2248 r
= sd_bus_call_method(
2250 "org.freedesktop.systemd1",
2251 "/org/freedesktop/systemd1",
2252 "org.freedesktop.systemd1.Manager",
2256 "ss", unit
, "fail");
2264 r
= sd_bus_message_read(reply
, "o", &j
);
2278 int manager_stop_unit(Manager
*manager
, const char *unit
, sd_bus_error
*error
, char **job
) {
2279 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2285 r
= sd_bus_call_method(
2287 "org.freedesktop.systemd1",
2288 "/org/freedesktop/systemd1",
2289 "org.freedesktop.systemd1.Manager",
2293 "ss", unit
, "fail");
2295 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) ||
2296 sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
)) {
2301 sd_bus_error_free(error
);
2312 r
= sd_bus_message_read(reply
, "o", &j
);
2326 int manager_kill_unit(Manager
*manager
, const char *unit
, KillWho who
, int signo
, sd_bus_error
*error
) {
2330 return sd_bus_call_method(
2332 "org.freedesktop.systemd1",
2333 "/org/freedesktop/systemd1",
2334 "org.freedesktop.systemd1.Manager",
2338 "ssi", unit
, who
== KILL_LEADER
? "main" : "all", signo
);
2341 int manager_unit_is_active(Manager
*manager
, const char *unit
) {
2342 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2343 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2344 _cleanup_free_
char *path
= NULL
;
2351 path
= unit_dbus_path_from_name(unit
);
2355 r
= sd_bus_get_property(
2357 "org.freedesktop.systemd1",
2359 "org.freedesktop.systemd1.Unit",
2365 /* systemd might have droppped off momentarily, let's
2366 * not make this an error */
2367 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_NO_REPLY
) ||
2368 sd_bus_error_has_name(&error
, SD_BUS_ERROR_DISCONNECTED
))
2371 /* If the unit is already unloaded then it's not
2373 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
) ||
2374 sd_bus_error_has_name(&error
, BUS_ERROR_LOAD_FAILED
))
2380 r
= sd_bus_message_read(reply
, "s", &state
);
2384 return !streq(state
, "inactive") && !streq(state
, "failed");
2387 int manager_job_is_active(Manager
*manager
, const char *path
) {
2388 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2389 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2395 r
= sd_bus_get_property(
2397 "org.freedesktop.systemd1",
2399 "org.freedesktop.systemd1.Job",
2405 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_NO_REPLY
) ||
2406 sd_bus_error_has_name(&error
, SD_BUS_ERROR_DISCONNECTED
))
2409 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_OBJECT
))
2415 /* We don't actually care about the state really. The fact
2416 * that we could read the job state is enough for us */