1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2011 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include "sd-messages.h"
28 #include "alloc-util.h"
29 #include "audit-util.h"
30 #include "bus-common-errors.h"
31 #include "bus-error.h"
33 #include "dirent-util.h"
37 #include "fileio-label.h"
38 #include "format-util.h"
42 #include "path-util.h"
43 #include "process-util.h"
44 #include "cgroup-util.h"
45 #include "selinux-util.h"
46 #include "sleep-config.h"
49 #include "terminal-util.h"
50 #include "udev-util.h"
51 #include "unit-name.h"
52 #include "user-util.h"
53 #include "utmp-wtmp.h"
55 static int get_sender_session(Manager
*m
, sd_bus_message
*message
, sd_bus_error
*error
, Session
**ret
) {
57 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
62 /* Get client login session. This is not what you are looking for these days,
63 * as apps may instead belong to a user service unit. This includes terminal
64 * emulators and hence command-line apps. */
65 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_AUGMENT
, &creds
);
69 r
= sd_bus_creds_get_session(creds
, &name
);
75 session
= hashmap_get(m
->sessions
, name
);
83 return sd_bus_error_setf(error
, BUS_ERROR_NO_SESSION_FOR_PID
,
84 "Caller does not belong to any known session");
87 int manager_get_session_from_creds(Manager
*m
, sd_bus_message
*message
, const char *name
, sd_bus_error
*error
, Session
**ret
) {
95 return get_sender_session(m
, message
, error
, ret
);
97 session
= hashmap_get(m
->sessions
, name
);
99 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SESSION
, "No session '%s' known", name
);
105 static int get_sender_user(Manager
*m
, sd_bus_message
*message
, sd_bus_error
*error
, User
**ret
) {
107 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
112 /* Note that we get the owner UID of the session, not the actual client UID here! */
113 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_OWNER_UID
|SD_BUS_CREDS_AUGMENT
, &creds
);
117 r
= sd_bus_creds_get_owner_uid(creds
, &uid
);
123 user
= hashmap_get(m
->users
, UID_TO_PTR(uid
));
131 return sd_bus_error_setf(error
, BUS_ERROR_NO_USER_FOR_PID
, "Caller does not belong to any logged in user or lingering user");
134 int manager_get_user_from_creds(Manager
*m
, sd_bus_message
*message
, uid_t uid
, sd_bus_error
*error
, User
**ret
) {
141 if (!uid_is_valid(uid
))
142 return get_sender_user(m
, message
, error
, ret
);
144 user
= hashmap_get(m
->users
, UID_TO_PTR(uid
));
146 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_USER
, "User ID "UID_FMT
" is not logged in or lingering", uid
);
152 int manager_get_seat_from_creds(Manager
*m
, sd_bus_message
*message
, const char *name
, sd_bus_error
*error
, Seat
**ret
) {
163 r
= manager_get_session_from_creds(m
, message
, NULL
, error
, &session
);
167 seat
= session
->seat
;
169 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "Session has no seat.");
171 seat
= hashmap_get(m
->seats
, name
);
173 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "No seat '%s' known", name
);
180 static int property_get_idle_hint(
183 const char *interface
,
184 const char *property
,
185 sd_bus_message
*reply
,
187 sd_bus_error
*error
) {
189 Manager
*m
= userdata
;
195 return sd_bus_message_append(reply
, "b", manager_get_idle_hint(m
, NULL
) > 0);
198 static int property_get_idle_since_hint(
201 const char *interface
,
202 const char *property
,
203 sd_bus_message
*reply
,
205 sd_bus_error
*error
) {
207 Manager
*m
= userdata
;
208 dual_timestamp t
= DUAL_TIMESTAMP_NULL
;
214 manager_get_idle_hint(m
, &t
);
216 return sd_bus_message_append(reply
, "t", streq(property
, "IdleSinceHint") ? t
.realtime
: t
.monotonic
);
219 static int property_get_inhibited(
222 const char *interface
,
223 const char *property
,
224 sd_bus_message
*reply
,
226 sd_bus_error
*error
) {
228 Manager
*m
= userdata
;
235 w
= manager_inhibit_what(m
, streq(property
, "BlockInhibited") ? INHIBIT_BLOCK
: INHIBIT_DELAY
);
237 return sd_bus_message_append(reply
, "s", inhibit_what_to_string(w
));
240 static int property_get_preparing(
243 const char *interface
,
244 const char *property
,
245 sd_bus_message
*reply
,
247 sd_bus_error
*error
) {
249 Manager
*m
= userdata
;
256 if (streq(property
, "PreparingForShutdown"))
257 b
= !!(m
->action_what
& INHIBIT_SHUTDOWN
);
259 b
= !!(m
->action_what
& INHIBIT_SLEEP
);
261 return sd_bus_message_append(reply
, "b", b
);
264 static int property_get_scheduled_shutdown(
267 const char *interface
,
268 const char *property
,
269 sd_bus_message
*reply
,
271 sd_bus_error
*error
) {
273 Manager
*m
= userdata
;
280 r
= sd_bus_message_open_container(reply
, 'r', "st");
284 r
= sd_bus_message_append(reply
, "st", m
->scheduled_shutdown_type
, m
->scheduled_shutdown_timeout
);
288 return sd_bus_message_close_container(reply
);
291 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action
, handle_action
, HandleAction
);
293 static int property_get_docked(
296 const char *interface
,
297 const char *property
,
298 sd_bus_message
*reply
,
300 sd_bus_error
*error
) {
302 Manager
*m
= userdata
;
308 return sd_bus_message_append(reply
, "b", manager_is_docked_or_external_displays(m
));
311 static int property_get_current_sessions(
314 const char *interface
,
315 const char *property
,
316 sd_bus_message
*reply
,
318 sd_bus_error
*error
) {
320 Manager
*m
= userdata
;
326 return sd_bus_message_append(reply
, "t", (uint64_t) hashmap_size(m
->sessions
));
329 static int property_get_current_inhibitors(
332 const char *interface
,
333 const char *property
,
334 sd_bus_message
*reply
,
336 sd_bus_error
*error
) {
338 Manager
*m
= userdata
;
344 return sd_bus_message_append(reply
, "t", (uint64_t) hashmap_size(m
->inhibitors
));
347 static int method_get_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
348 _cleanup_free_
char *p
= NULL
;
349 Manager
*m
= userdata
;
357 r
= sd_bus_message_read(message
, "s", &name
);
361 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
365 p
= session_bus_path(session
);
369 return sd_bus_reply_method_return(message
, "o", p
);
372 /* Get login session of a process. This is not what you are looking for these days,
373 * as apps may instead belong to a user service unit. This includes terminal
374 * emulators and hence command-line apps. */
375 static int method_get_session_by_pid(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
376 _cleanup_free_
char *p
= NULL
;
377 Session
*session
= NULL
;
378 Manager
*m
= userdata
;
385 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
387 r
= sd_bus_message_read(message
, "u", &pid
);
394 r
= manager_get_session_from_creds(m
, message
, NULL
, error
, &session
);
398 r
= manager_get_session_by_pid(m
, pid
, &session
);
403 return sd_bus_error_setf(error
, BUS_ERROR_NO_SESSION_FOR_PID
, "PID "PID_FMT
" does not belong to any known session", pid
);
406 p
= session_bus_path(session
);
410 return sd_bus_reply_method_return(message
, "o", p
);
413 static int method_get_user(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
414 _cleanup_free_
char *p
= NULL
;
415 Manager
*m
= userdata
;
423 r
= sd_bus_message_read(message
, "u", &uid
);
427 r
= manager_get_user_from_creds(m
, message
, uid
, error
, &user
);
431 p
= user_bus_path(user
);
435 return sd_bus_reply_method_return(message
, "o", p
);
438 static int method_get_user_by_pid(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
439 _cleanup_free_
char *p
= NULL
;
440 Manager
*m
= userdata
;
448 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
450 r
= sd_bus_message_read(message
, "u", &pid
);
457 r
= manager_get_user_from_creds(m
, message
, UID_INVALID
, error
, &user
);
461 r
= manager_get_user_by_pid(m
, pid
, &user
);
465 return sd_bus_error_setf(error
, BUS_ERROR_NO_USER_FOR_PID
,
466 "PID "PID_FMT
" does not belong to any logged in user or lingering user",
470 p
= user_bus_path(user
);
474 return sd_bus_reply_method_return(message
, "o", p
);
477 static int method_get_seat(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
478 _cleanup_free_
char *p
= NULL
;
479 Manager
*m
= userdata
;
487 r
= sd_bus_message_read(message
, "s", &name
);
491 r
= manager_get_seat_from_creds(m
, message
, name
, error
, &seat
);
495 p
= seat_bus_path(seat
);
499 return sd_bus_reply_method_return(message
, "o", p
);
502 static int method_list_sessions(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
503 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
504 Manager
*m
= userdata
;
512 r
= sd_bus_message_new_method_return(message
, &reply
);
516 r
= sd_bus_message_open_container(reply
, 'a', "(susso)");
520 HASHMAP_FOREACH(session
, m
->sessions
, i
) {
521 _cleanup_free_
char *p
= NULL
;
523 p
= session_bus_path(session
);
527 r
= sd_bus_message_append(reply
, "(susso)",
529 (uint32_t) session
->user
->uid
,
531 session
->seat
? session
->seat
->id
: "",
537 r
= sd_bus_message_close_container(reply
);
541 return sd_bus_send(NULL
, reply
, NULL
);
544 static int method_list_users(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
545 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
546 Manager
*m
= userdata
;
554 r
= sd_bus_message_new_method_return(message
, &reply
);
558 r
= sd_bus_message_open_container(reply
, 'a', "(uso)");
562 HASHMAP_FOREACH(user
, m
->users
, i
) {
563 _cleanup_free_
char *p
= NULL
;
565 p
= user_bus_path(user
);
569 r
= sd_bus_message_append(reply
, "(uso)",
570 (uint32_t) user
->uid
,
577 r
= sd_bus_message_close_container(reply
);
581 return sd_bus_send(NULL
, reply
, NULL
);
584 static int method_list_seats(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
585 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
586 Manager
*m
= userdata
;
594 r
= sd_bus_message_new_method_return(message
, &reply
);
598 r
= sd_bus_message_open_container(reply
, 'a', "(so)");
602 HASHMAP_FOREACH(seat
, m
->seats
, i
) {
603 _cleanup_free_
char *p
= NULL
;
605 p
= seat_bus_path(seat
);
609 r
= sd_bus_message_append(reply
, "(so)", seat
->id
, p
);
614 r
= sd_bus_message_close_container(reply
);
618 return sd_bus_send(NULL
, reply
, NULL
);
621 static int method_list_inhibitors(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
622 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
623 Manager
*m
= userdata
;
624 Inhibitor
*inhibitor
;
631 r
= sd_bus_message_new_method_return(message
, &reply
);
635 r
= sd_bus_message_open_container(reply
, 'a', "(ssssuu)");
639 HASHMAP_FOREACH(inhibitor
, m
->inhibitors
, i
) {
641 r
= sd_bus_message_append(reply
, "(ssssuu)",
642 strempty(inhibit_what_to_string(inhibitor
->what
)),
643 strempty(inhibitor
->who
),
644 strempty(inhibitor
->why
),
645 strempty(inhibit_mode_to_string(inhibitor
->mode
)),
646 (uint32_t) inhibitor
->uid
,
647 (uint32_t) inhibitor
->pid
);
652 r
= sd_bus_message_close_container(reply
);
656 return sd_bus_send(NULL
, reply
, NULL
);
659 static int method_create_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
660 const char *service
, *type
, *class, *cseat
, *tty
, *display
, *remote_user
, *remote_host
, *desktop
;
661 uint32_t audit_id
= 0;
662 _cleanup_free_
char *unit
= NULL
;
663 _cleanup_free_
char *id
= NULL
;
664 Session
*session
= NULL
;
665 Manager
*m
= userdata
;
679 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
680 assert_cc(sizeof(uid_t
) == sizeof(uint32_t));
682 r
= sd_bus_message_read(message
, "uusssssussbss", &uid
, &leader
, &service
, &type
, &class, &desktop
, &cseat
, &vtnr
, &tty
, &display
, &remote
, &remote_user
, &remote_host
);
686 if (!uid_is_valid(uid
))
687 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid UID");
688 if (leader
< 0 || leader
== 1)
689 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid leader PID");
692 t
= _SESSION_TYPE_INVALID
;
694 t
= session_type_from_string(type
);
696 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid session type %s", type
);
700 c
= _SESSION_CLASS_INVALID
;
702 c
= session_class_from_string(class);
704 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid session class %s", class);
707 if (isempty(desktop
))
710 if (!string_is_safe(desktop
))
711 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid desktop string %s", desktop
);
717 seat
= hashmap_get(m
->seats
, cseat
);
719 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_SEAT
, "No seat '%s' known", cseat
);
722 if (tty_is_vc(tty
)) {
727 else if (seat
!= m
->seat0
)
728 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "TTY %s is virtual console but seat %s is not seat0", tty
, seat
->id
);
730 v
= vtnr_from_tty(tty
);
732 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Cannot determine VT number from virtual console TTY %s", tty
);
736 else if (vtnr
!= (uint32_t) v
)
737 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified TTY and VT number do not match");
739 } else if (tty_is_console(tty
)) {
743 else if (seat
!= m
->seat0
)
744 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Console TTY specified but seat is not seat0");
747 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Console TTY specified but VT number is not 0");
751 if (seat_has_vts(seat
)) {
752 if (!vtnr
|| vtnr
> 63)
753 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "VT number out of range");
756 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Seat has no VTs but VT number not 0");
760 r
= sd_bus_message_enter_container(message
, 'a', "(sv)");
764 if (t
== _SESSION_TYPE_INVALID
) {
765 if (!isempty(display
))
767 else if (!isempty(tty
))
770 t
= SESSION_UNSPECIFIED
;
773 if (c
== _SESSION_CLASS_INVALID
) {
774 if (t
== SESSION_UNSPECIFIED
)
775 c
= SESSION_BACKGROUND
;
781 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
783 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
787 r
= sd_bus_creds_get_pid(creds
, (pid_t
*) &leader
);
793 * Check if we are already in a logind session. Or if we are in user@.service
794 * which is a special PAM session that avoids creating a logind session.
796 r
= cg_pid_get_unit(leader
, &unit
);
799 if (hashmap_get(m
->session_units
, unit
) ||
800 hashmap_get(m
->user_units
, unit
))
801 return sd_bus_error_setf(error
, BUS_ERROR_SESSION_BUSY
, "Already running in a session");
804 * Old gdm and lightdm start the user-session on the same VT as
805 * the greeter session. But they destroy the greeter session
806 * after the user-session and want the user-session to take
807 * over the VT. We need to support this for
808 * backwards-compatibility, so make sure we allow new sessions
809 * on a VT that a greeter is running on. Furthermore, to allow
810 * re-logins, we have to allow a greeter to take over a used VT for
811 * the exact same reasons.
813 if (c
!= SESSION_GREETER
&&
815 vtnr
< m
->seat0
->position_count
&&
816 m
->seat0
->positions
[vtnr
] &&
817 m
->seat0
->positions
[vtnr
]->class != SESSION_GREETER
)
818 return sd_bus_error_setf(error
, BUS_ERROR_SESSION_BUSY
, "Already occupied by a session");
820 if (hashmap_size(m
->sessions
) >= m
->sessions_max
)
821 return sd_bus_error_setf(error
, SD_BUS_ERROR_LIMITS_EXCEEDED
, "Maximum number of sessions (%" PRIu64
") reached, refusing further sessions.", m
->sessions_max
);
823 (void) audit_session_from_pid(leader
, &audit_id
);
824 if (audit_session_is_valid(audit_id
)) {
825 /* Keep our session IDs and the audit session IDs in sync */
827 if (asprintf(&id
, "%"PRIu32
, audit_id
) < 0)
830 /* Wut? There's already a session by this name and we
831 * didn't find it above? Weird, then let's not trust
832 * the audit data and let's better register a new
834 if (hashmap_get(m
->sessions
, id
)) {
835 log_warning("Existing logind session ID %s used by new audit session, ignoring", id
);
836 audit_id
= AUDIT_SESSION_INVALID
;
846 if (asprintf(&id
, "c%lu", ++m
->session_counter
) < 0)
849 } while (hashmap_get(m
->sessions
, id
));
852 r
= manager_add_user_by_uid(m
, uid
, &user
);
856 r
= manager_add_session(m
, id
, &session
);
860 session_set_user(session
, user
);
862 session
->leader
= leader
;
863 session
->audit_id
= audit_id
;
866 session
->remote
= remote
;
867 session
->vtnr
= vtnr
;
870 session
->tty
= strdup(tty
);
877 if (!isempty(display
)) {
878 session
->display
= strdup(display
);
879 if (!session
->display
) {
885 if (!isempty(remote_user
)) {
886 session
->remote_user
= strdup(remote_user
);
887 if (!session
->remote_user
) {
893 if (!isempty(remote_host
)) {
894 session
->remote_host
= strdup(remote_host
);
895 if (!session
->remote_host
) {
901 if (!isempty(service
)) {
902 session
->service
= strdup(service
);
903 if (!session
->service
) {
909 if (!isempty(desktop
)) {
910 session
->desktop
= strdup(desktop
);
911 if (!session
->desktop
) {
918 r
= seat_attach_session(seat
, session
);
923 r
= session_start(session
);
927 session
->create_message
= sd_bus_message_ref(message
);
929 /* Now, let's wait until the slice unit and stuff got
930 * created. We send the reply back from
931 * session_send_create_reply(). */
937 session_add_to_gc_queue(session
);
940 user_add_to_gc_queue(user
);
945 static int method_release_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
946 Manager
*m
= userdata
;
954 r
= sd_bus_message_read(message
, "s", &name
);
958 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
962 r
= session_release(session
);
966 return sd_bus_reply_method_return(message
, NULL
);
969 static int method_activate_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
970 Manager
*m
= userdata
;
978 r
= sd_bus_message_read(message
, "s", &name
);
982 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
986 return bus_session_method_activate(message
, session
, error
);
989 static int method_activate_session_on_seat(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
990 const char *session_name
, *seat_name
;
991 Manager
*m
= userdata
;
999 /* Same as ActivateSession() but refuses to work if
1000 * the seat doesn't match */
1002 r
= sd_bus_message_read(message
, "ss", &session_name
, &seat_name
);
1006 r
= manager_get_session_from_creds(m
, message
, session_name
, error
, &session
);
1010 r
= manager_get_seat_from_creds(m
, message
, seat_name
, error
, &seat
);
1014 if (session
->seat
!= seat
)
1015 return sd_bus_error_setf(error
, BUS_ERROR_SESSION_NOT_ON_SEAT
, "Session %s not on seat %s", session_name
, seat_name
);
1017 r
= session_activate(session
);
1021 return sd_bus_reply_method_return(message
, NULL
);
1024 static int method_lock_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1025 Manager
*m
= userdata
;
1033 r
= sd_bus_message_read(message
, "s", &name
);
1037 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
1041 return bus_session_method_lock(message
, session
, error
);
1044 static int method_lock_sessions(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1045 Manager
*m
= userdata
;
1051 r
= bus_verify_polkit_async(
1054 "org.freedesktop.login1.lock-sessions",
1058 &m
->polkit_registry
,
1063 return 1; /* Will call us back */
1065 r
= session_send_lock_all(m
, streq(sd_bus_message_get_member(message
), "LockSessions"));
1069 return sd_bus_reply_method_return(message
, NULL
);
1072 static int method_kill_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1074 Manager
*m
= userdata
;
1081 r
= sd_bus_message_read(message
, "s", &name
);
1085 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
1089 return bus_session_method_kill(message
, session
, error
);
1092 static int method_kill_user(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1093 Manager
*m
= userdata
;
1101 r
= sd_bus_message_read(message
, "u", &uid
);
1105 r
= manager_get_user_from_creds(m
, message
, uid
, error
, &user
);
1109 return bus_user_method_kill(message
, user
, error
);
1112 static int method_terminate_session(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1113 Manager
*m
= userdata
;
1121 r
= sd_bus_message_read(message
, "s", &name
);
1125 r
= manager_get_session_from_creds(m
, message
, name
, error
, &session
);
1129 return bus_session_method_terminate(message
, session
, error
);
1132 static int method_terminate_user(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1133 Manager
*m
= userdata
;
1141 r
= sd_bus_message_read(message
, "u", &uid
);
1145 r
= manager_get_user_from_creds(m
, message
, uid
, error
, &user
);
1149 return bus_user_method_terminate(message
, user
, error
);
1152 static int method_terminate_seat(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1153 Manager
*m
= userdata
;
1161 r
= sd_bus_message_read(message
, "s", &name
);
1165 r
= manager_get_seat_from_creds(m
, message
, name
, error
, &seat
);
1169 return bus_seat_method_terminate(message
, seat
, error
);
1172 static int method_set_user_linger(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1173 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
1174 _cleanup_free_
char *cc
= NULL
;
1175 Manager
*m
= userdata
;
1176 int r
, b
, interactive
;
1179 uint32_t uid
, auth_uid
;
1184 r
= sd_bus_message_read(message
, "ubb", &uid
, &b
, &interactive
);
1188 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
|
1189 SD_BUS_CREDS_OWNER_UID
|SD_BUS_CREDS_AUGMENT
, &creds
);
1193 if (!uid_is_valid(uid
)) {
1194 /* Note that we get the owner UID of the session or user unit,
1195 * not the actual client UID here! */
1196 r
= sd_bus_creds_get_owner_uid(creds
, &uid
);
1201 /* owner_uid is racy, so for authorization we must use euid */
1202 r
= sd_bus_creds_get_euid(creds
, &auth_uid
);
1209 return errno
> 0 ? -errno
: -ENOENT
;
1211 r
= bus_verify_polkit_async(
1214 uid
== auth_uid
? "org.freedesktop.login1.set-self-linger" :
1215 "org.freedesktop.login1.set-user-linger",
1219 &m
->polkit_registry
,
1224 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1226 mkdir_p_label("/var/lib/systemd", 0755);
1228 r
= mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, MKDIR_WARN_MODE
);
1232 cc
= cescape(pw
->pw_name
);
1236 path
= strjoina("/var/lib/systemd/linger/", cc
);
1244 if (manager_add_user_by_uid(m
, uid
, &u
) >= 0)
1251 if (r
< 0 && errno
!= ENOENT
)
1254 u
= hashmap_get(m
->users
, UID_TO_PTR(uid
));
1256 user_add_to_gc_queue(u
);
1259 return sd_bus_reply_method_return(message
, NULL
);
1262 static int trigger_device(Manager
*m
, struct udev_device
*d
) {
1263 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
1264 struct udev_list_entry
*first
, *item
;
1269 e
= udev_enumerate_new(m
->udev
);
1274 r
= udev_enumerate_add_match_parent(e
, d
);
1279 r
= udev_enumerate_scan_devices(e
);
1283 first
= udev_enumerate_get_list_entry(e
);
1284 udev_list_entry_foreach(item
, first
) {
1285 _cleanup_free_
char *t
= NULL
;
1288 p
= udev_list_entry_get_name(item
);
1290 t
= strappend(p
, "/uevent");
1294 (void) write_string_file(t
, "change", 0);
1300 static int attach_device(Manager
*m
, const char *seat
, const char *sysfs
) {
1301 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
1302 _cleanup_free_
char *rule
= NULL
, *file
= NULL
;
1303 const char *id_for_seat
;
1310 d
= udev_device_new_from_syspath(m
->udev
, sysfs
);
1314 if (!udev_device_has_tag(d
, "seat"))
1317 id_for_seat
= udev_device_get_property_value(d
, "ID_FOR_SEAT");
1321 if (asprintf(&file
, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat
) < 0)
1324 if (asprintf(&rule
, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat
, seat
) < 0)
1327 mkdir_p_label("/etc/udev/rules.d", 0755);
1328 r
= write_string_file_atomic_label(file
, rule
);
1332 return trigger_device(m
, d
);
1335 static int flush_devices(Manager
*m
) {
1336 _cleanup_closedir_
DIR *d
;
1340 d
= opendir("/etc/udev/rules.d");
1342 if (errno
!= ENOENT
)
1343 log_warning_errno(errno
, "Failed to open /etc/udev/rules.d: %m");
1347 FOREACH_DIRENT_ALL(de
, d
, break) {
1348 if (!dirent_is_file(de
))
1351 if (!startswith(de
->d_name
, "72-seat-"))
1354 if (!endswith(de
->d_name
, ".rules"))
1357 if (unlinkat(dirfd(d
), de
->d_name
, 0) < 0)
1358 log_warning_errno(errno
, "Failed to unlink %s: %m", de
->d_name
);
1362 return trigger_device(m
, NULL
);
1365 static int method_attach_device(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1366 const char *sysfs
, *seat
;
1367 Manager
*m
= userdata
;
1373 r
= sd_bus_message_read(message
, "ssb", &seat
, &sysfs
, &interactive
);
1377 if (!path_startswith(sysfs
, "/sys"))
1378 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not in /sys", sysfs
);
1380 if (!seat_name_is_valid(seat
))
1381 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Seat %s is not valid", seat
);
1383 r
= bus_verify_polkit_async(
1386 "org.freedesktop.login1.attach-device",
1390 &m
->polkit_registry
,
1395 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1397 r
= attach_device(m
, seat
, sysfs
);
1401 return sd_bus_reply_method_return(message
, NULL
);
1404 static int method_flush_devices(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1405 Manager
*m
= userdata
;
1411 r
= sd_bus_message_read(message
, "b", &interactive
);
1415 r
= bus_verify_polkit_async(
1418 "org.freedesktop.login1.flush-devices",
1422 &m
->polkit_registry
,
1427 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1429 r
= flush_devices(m
);
1433 return sd_bus_reply_method_return(message
, NULL
);
1436 static int have_multiple_sessions(
1445 /* Check for other users' sessions. Greeter sessions do not
1446 * count, and non-login sessions do not count either. */
1447 HASHMAP_FOREACH(session
, m
->sessions
, i
)
1448 if (session
->class == SESSION_USER
&&
1449 session
->user
->uid
!= uid
)
1455 static int bus_manager_log_shutdown(
1457 const char *unit_name
) {
1464 if (streq(unit_name
, SPECIAL_POWEROFF_TARGET
)) {
1465 p
= "MESSAGE=System is powering down";
1466 q
= "SHUTDOWN=power-off";
1467 } else if (streq(unit_name
, SPECIAL_REBOOT_TARGET
)) {
1468 p
= "MESSAGE=System is rebooting";
1469 q
= "SHUTDOWN=reboot";
1470 } else if (streq(unit_name
, SPECIAL_HALT_TARGET
)) {
1471 p
= "MESSAGE=System is halting";
1472 q
= "SHUTDOWN=halt";
1473 } else if (streq(unit_name
, SPECIAL_KEXEC_TARGET
)) {
1474 p
= "MESSAGE=System is rebooting with kexec";
1475 q
= "SHUTDOWN=kexec";
1477 p
= "MESSAGE=System is shutting down";
1481 if (isempty(m
->wall_message
))
1482 p
= strjoina(p
, ".");
1484 p
= strjoina(p
, " (", m
->wall_message
, ").");
1486 return log_struct(LOG_NOTICE
,
1487 "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR
,
1493 static int lid_switch_ignore_handler(sd_event_source
*e
, uint64_t usec
, void *userdata
) {
1494 Manager
*m
= userdata
;
1499 m
->lid_switch_ignore_event_source
= sd_event_source_unref(m
->lid_switch_ignore_event_source
);
1503 int manager_set_lid_switch_ignore(Manager
*m
, usec_t until
) {
1508 if (until
<= now(CLOCK_MONOTONIC
))
1511 /* We want to ignore the lid switch for a while after each
1512 * suspend, and after boot-up. Hence let's install a timer for
1513 * this. As long as the event source exists we ignore the lid
1516 if (m
->lid_switch_ignore_event_source
) {
1519 r
= sd_event_source_get_time(m
->lid_switch_ignore_event_source
, &u
);
1526 r
= sd_event_source_set_time(m
->lid_switch_ignore_event_source
, until
);
1528 r
= sd_event_add_time(
1530 &m
->lid_switch_ignore_event_source
,
1533 lid_switch_ignore_handler
, m
);
1538 static int send_prepare_for(Manager
*m
, InhibitWhat w
, bool _active
) {
1540 static const char * const signal_name
[_INHIBIT_WHAT_MAX
] = {
1541 [INHIBIT_SHUTDOWN
] = "PrepareForShutdown",
1542 [INHIBIT_SLEEP
] = "PrepareForSleep"
1545 int active
= _active
;
1549 assert(w
< _INHIBIT_WHAT_MAX
);
1550 assert(signal_name
[w
]);
1552 return sd_bus_emit_signal(m
->bus
,
1553 "/org/freedesktop/login1",
1554 "org.freedesktop.login1.Manager",
1560 static int execute_shutdown_or_sleep(
1563 const char *unit_name
,
1564 sd_bus_error
*error
) {
1566 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1573 assert(w
< _INHIBIT_WHAT_MAX
);
1576 if (w
== INHIBIT_SHUTDOWN
)
1577 bus_manager_log_shutdown(m
, unit_name
);
1579 r
= sd_bus_call_method(
1581 "org.freedesktop.systemd1",
1582 "/org/freedesktop/systemd1",
1583 "org.freedesktop.systemd1.Manager",
1587 "ss", unit_name
, "replace-irreversibly");
1591 r
= sd_bus_message_read(reply
, "o", &p
);
1601 m
->action_unit
= unit_name
;
1602 free(m
->action_job
);
1606 /* Make sure the lid switch is ignored for a while */
1607 manager_set_lid_switch_ignore(m
, now(CLOCK_MONOTONIC
) + m
->holdoff_timeout_usec
);
1612 /* Tell people that they now may take a lock again */
1613 (void) send_prepare_for(m
, w
, false);
1618 int manager_dispatch_delayed(Manager
*manager
, bool timeout
) {
1620 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1621 Inhibitor
*offending
= NULL
;
1626 if (manager
->action_what
== 0 || manager
->action_job
)
1629 if (manager_is_inhibited(manager
, manager
->action_what
, INHIBIT_DELAY
, NULL
, false, false, 0, &offending
)) {
1630 _cleanup_free_
char *comm
= NULL
, *u
= NULL
;
1635 (void) get_process_comm(offending
->pid
, &comm
);
1636 u
= uid_to_name(offending
->uid
);
1638 log_notice("Delay lock is active (UID "UID_FMT
"/%s, PID "PID_FMT
"/%s) but inhibitor timeout is reached.",
1639 offending
->uid
, strna(u
),
1640 offending
->pid
, strna(comm
));
1643 /* Actually do the operation */
1644 r
= execute_shutdown_or_sleep(manager
, manager
->action_what
, manager
->action_unit
, &error
);
1646 log_warning("Error during inhibitor-delayed operation (already returned success to client): %s",
1647 bus_error_message(&error
, r
));
1649 manager
->action_unit
= NULL
;
1650 manager
->action_what
= 0;
1657 static int manager_inhibit_timeout_handler(
1662 Manager
*manager
= userdata
;
1666 assert(manager
->inhibit_timeout_source
== s
);
1668 r
= manager_dispatch_delayed(manager
, true);
1669 return (r
< 0) ? r
: 0;
1672 static int delay_shutdown_or_sleep(
1675 const char *unit_name
) {
1682 assert(w
< _INHIBIT_WHAT_MAX
);
1685 timeout_val
= now(CLOCK_MONOTONIC
) + m
->inhibit_delay_max
;
1687 if (m
->inhibit_timeout_source
) {
1688 r
= sd_event_source_set_time(m
->inhibit_timeout_source
, timeout_val
);
1690 return log_error_errno(r
, "sd_event_source_set_time() failed: %m");
1692 r
= sd_event_source_set_enabled(m
->inhibit_timeout_source
, SD_EVENT_ONESHOT
);
1694 return log_error_errno(r
, "sd_event_source_set_enabled() failed: %m");
1696 r
= sd_event_add_time(m
->event
, &m
->inhibit_timeout_source
, CLOCK_MONOTONIC
,
1697 timeout_val
, 0, manager_inhibit_timeout_handler
, m
);
1702 m
->action_unit
= unit_name
;
1708 int bus_manager_shutdown_or_sleep_now_or_later(
1710 const char *unit_name
,
1712 sd_bus_error
*error
) {
1720 assert(w
<= _INHIBIT_WHAT_MAX
);
1721 assert(!m
->action_job
);
1723 /* Tell everybody to prepare for shutdown/sleep */
1724 (void) send_prepare_for(m
, w
, true);
1727 m
->inhibit_delay_max
> 0 &&
1728 manager_is_inhibited(m
, w
, INHIBIT_DELAY
, NULL
, false, false, 0, NULL
);
1731 /* Shutdown is delayed, keep in mind what we
1732 * want to do, and start a timeout */
1733 r
= delay_shutdown_or_sleep(m
, w
, unit_name
);
1735 /* Shutdown is not delayed, execute it
1737 r
= execute_shutdown_or_sleep(m
, w
, unit_name
, error
);
1742 static int verify_shutdown_creds(
1744 sd_bus_message
*message
,
1748 const char *action_multiple_sessions
,
1749 const char *action_ignore_inhibit
,
1750 sd_bus_error
*error
) {
1752 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
1753 bool multiple_sessions
, blocked
;
1760 assert(w
<= _INHIBIT_WHAT_MAX
);
1762 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
1766 r
= sd_bus_creds_get_euid(creds
, &uid
);
1770 r
= have_multiple_sessions(m
, uid
);
1774 multiple_sessions
= r
> 0;
1775 blocked
= manager_is_inhibited(m
, w
, INHIBIT_BLOCK
, NULL
, false, true, uid
, NULL
);
1777 if (multiple_sessions
&& action_multiple_sessions
) {
1778 r
= bus_verify_polkit_async(message
, CAP_SYS_BOOT
, action_multiple_sessions
, NULL
, interactive
, UID_INVALID
, &m
->polkit_registry
, error
);
1782 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1785 if (blocked
&& action_ignore_inhibit
) {
1786 r
= bus_verify_polkit_async(message
, CAP_SYS_BOOT
, action_ignore_inhibit
, NULL
, interactive
, UID_INVALID
, &m
->polkit_registry
, error
);
1790 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1793 if (!multiple_sessions
&& !blocked
&& action
) {
1794 r
= bus_verify_polkit_async(message
, CAP_SYS_BOOT
, action
, NULL
, interactive
, UID_INVALID
, &m
->polkit_registry
, error
);
1798 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1804 static int method_do_shutdown_or_sleep(
1806 sd_bus_message
*message
,
1807 const char *unit_name
,
1810 const char *action_multiple_sessions
,
1811 const char *action_ignore_inhibit
,
1812 const char *sleep_verb
,
1813 sd_bus_error
*error
) {
1821 assert(w
<= _INHIBIT_WHAT_MAX
);
1823 r
= sd_bus_message_read(message
, "b", &interactive
);
1827 /* Don't allow multiple jobs being executed at the same time */
1829 return sd_bus_error_setf(error
, BUS_ERROR_OPERATION_IN_PROGRESS
, "There's already a shutdown or sleep operation in progress");
1832 r
= can_sleep(sleep_verb
);
1837 return sd_bus_error_setf(error
, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED
, "Sleep verb not supported");
1840 r
= verify_shutdown_creds(m
, message
, w
, interactive
, action
, action_multiple_sessions
,
1841 action_ignore_inhibit
, error
);
1845 r
= bus_manager_shutdown_or_sleep_now_or_later(m
, unit_name
, w
, error
);
1849 return sd_bus_reply_method_return(message
, NULL
);
1852 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1853 Manager
*m
= userdata
;
1855 return method_do_shutdown_or_sleep(
1857 SPECIAL_POWEROFF_TARGET
,
1859 "org.freedesktop.login1.power-off",
1860 "org.freedesktop.login1.power-off-multiple-sessions",
1861 "org.freedesktop.login1.power-off-ignore-inhibit",
1866 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1867 Manager
*m
= userdata
;
1869 return method_do_shutdown_or_sleep(
1871 SPECIAL_REBOOT_TARGET
,
1873 "org.freedesktop.login1.reboot",
1874 "org.freedesktop.login1.reboot-multiple-sessions",
1875 "org.freedesktop.login1.reboot-ignore-inhibit",
1880 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1881 Manager
*m
= userdata
;
1883 return method_do_shutdown_or_sleep(
1885 SPECIAL_HALT_TARGET
,
1887 "org.freedesktop.login1.halt",
1888 "org.freedesktop.login1.halt-multiple-sessions",
1889 "org.freedesktop.login1.halt-ignore-inhibit",
1894 static int method_suspend(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1895 Manager
*m
= userdata
;
1897 return method_do_shutdown_or_sleep(
1899 SPECIAL_SUSPEND_TARGET
,
1901 "org.freedesktop.login1.suspend",
1902 "org.freedesktop.login1.suspend-multiple-sessions",
1903 "org.freedesktop.login1.suspend-ignore-inhibit",
1908 static int method_hibernate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1909 Manager
*m
= userdata
;
1911 return method_do_shutdown_or_sleep(
1913 SPECIAL_HIBERNATE_TARGET
,
1915 "org.freedesktop.login1.hibernate",
1916 "org.freedesktop.login1.hibernate-multiple-sessions",
1917 "org.freedesktop.login1.hibernate-ignore-inhibit",
1922 static int method_hybrid_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1923 Manager
*m
= userdata
;
1925 return method_do_shutdown_or_sleep(
1927 SPECIAL_HYBRID_SLEEP_TARGET
,
1929 "org.freedesktop.login1.hibernate",
1930 "org.freedesktop.login1.hibernate-multiple-sessions",
1931 "org.freedesktop.login1.hibernate-ignore-inhibit",
1936 static int method_suspend_to_hibernate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1937 Manager
*m
= userdata
;
1939 return method_do_shutdown_or_sleep(
1941 SPECIAL_SUSPEND_TO_HIBERNATE_TARGET
,
1943 "org.freedesktop.login1.hibernate",
1944 "org.freedesktop.login1.hibernate-multiple-sessions",
1945 "org.freedesktop.login1.hibernate-ignore-inhibit",
1950 static int nologin_timeout_handler(
1955 Manager
*m
= userdata
;
1957 log_info("Creating /run/nologin, blocking further logins...");
1960 create_shutdown_run_nologin_or_warn() >= 0;
1965 static int update_schedule_file(Manager
*m
) {
1966 _cleanup_free_
char *temp_path
= NULL
;
1967 _cleanup_fclose_
FILE *f
= NULL
;
1972 r
= mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, MKDIR_WARN_MODE
);
1974 return log_error_errno(r
, "Failed to create shutdown subdirectory: %m");
1976 r
= fopen_temporary("/run/systemd/shutdown/scheduled", &f
, &temp_path
);
1978 return log_error_errno(r
, "Failed to save information about scheduled shutdowns: %m");
1980 (void) fchmod(fileno(f
), 0644);
1986 m
->scheduled_shutdown_timeout
,
1987 m
->enable_wall_messages
,
1988 m
->scheduled_shutdown_type
);
1990 if (!isempty(m
->wall_message
)) {
1991 _cleanup_free_
char *t
;
1993 t
= cescape(m
->wall_message
);
1999 fprintf(f
, "WALL_MESSAGE=%s\n", t
);
2002 r
= fflush_and_check(f
);
2006 if (rename(temp_path
, "/run/systemd/shutdown/scheduled") < 0) {
2014 (void) unlink(temp_path
);
2015 (void) unlink("/run/systemd/shutdown/scheduled");
2017 return log_error_errno(r
, "Failed to write information about scheduled shutdowns: %m");
2020 static void reset_scheduled_shutdown(Manager
*m
) {
2023 m
->scheduled_shutdown_timeout_source
= sd_event_source_unref(m
->scheduled_shutdown_timeout_source
);
2024 m
->wall_message_timeout_source
= sd_event_source_unref(m
->wall_message_timeout_source
);
2025 m
->nologin_timeout_source
= sd_event_source_unref(m
->nologin_timeout_source
);
2027 m
->scheduled_shutdown_type
= mfree(m
->scheduled_shutdown_type
);
2028 m
->scheduled_shutdown_timeout
= 0;
2029 m
->shutdown_dry_run
= false;
2031 if (m
->unlink_nologin
) {
2032 (void) unlink_or_warn("/run/nologin");
2033 m
->unlink_nologin
= false;
2036 (void) unlink("/run/systemd/shutdown/scheduled");
2039 static int manager_scheduled_shutdown_handler(
2044 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2045 Manager
*m
= userdata
;
2051 if (isempty(m
->scheduled_shutdown_type
))
2054 if (streq(m
->scheduled_shutdown_type
, "poweroff"))
2055 target
= SPECIAL_POWEROFF_TARGET
;
2056 else if (streq(m
->scheduled_shutdown_type
, "reboot"))
2057 target
= SPECIAL_REBOOT_TARGET
;
2058 else if (streq(m
->scheduled_shutdown_type
, "halt"))
2059 target
= SPECIAL_HALT_TARGET
;
2061 assert_not_reached("unexpected shutdown type");
2063 /* Don't allow multiple jobs being executed at the same time */
2064 if (m
->action_what
) {
2066 log_error("Scheduled shutdown to %s failed: shutdown or sleep operation already in progress", target
);
2070 if (m
->shutdown_dry_run
) {
2071 /* We do not process delay inhibitors here. Otherwise, we
2072 * would have to be considered "in progress" (like the check
2073 * above) for some seconds after our admin has seen the final
2076 bus_manager_log_shutdown(m
, target
);
2077 log_info("Running in dry run, suppressing action.");
2078 reset_scheduled_shutdown(m
);
2083 r
= bus_manager_shutdown_or_sleep_now_or_later(m
, target
, INHIBIT_SHUTDOWN
, &error
);
2085 log_error_errno(r
, "Scheduled shutdown to %s failed: %m", target
);
2092 reset_scheduled_shutdown(m
);
2096 static int method_schedule_shutdown(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2097 Manager
*m
= userdata
;
2098 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
2099 const char *action_multiple_sessions
= NULL
;
2100 const char *action_ignore_inhibit
= NULL
;
2101 const char *action
= NULL
;
2105 bool dry_run
= false;
2110 r
= sd_bus_message_read(message
, "st", &type
, &elapse
);
2114 if (startswith(type
, "dry-")) {
2119 if (streq(type
, "poweroff")) {
2120 action
= "org.freedesktop.login1.power-off";
2121 action_multiple_sessions
= "org.freedesktop.login1.power-off-multiple-sessions";
2122 action_ignore_inhibit
= "org.freedesktop.login1.power-off-ignore-inhibit";
2123 } else if (streq(type
, "reboot")) {
2124 action
= "org.freedesktop.login1.reboot";
2125 action_multiple_sessions
= "org.freedesktop.login1.reboot-multiple-sessions";
2126 action_ignore_inhibit
= "org.freedesktop.login1.reboot-ignore-inhibit";
2127 } else if (streq(type
, "halt")) {
2128 action
= "org.freedesktop.login1.halt";
2129 action_multiple_sessions
= "org.freedesktop.login1.halt-multiple-sessions";
2130 action_ignore_inhibit
= "org.freedesktop.login1.halt-ignore-inhibit";
2132 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unsupported shutdown type");
2134 r
= verify_shutdown_creds(m
, message
, INHIBIT_SHUTDOWN
, false,
2135 action
, action_multiple_sessions
, action_ignore_inhibit
, error
);
2139 if (m
->scheduled_shutdown_timeout_source
) {
2140 r
= sd_event_source_set_time(m
->scheduled_shutdown_timeout_source
, elapse
);
2142 return log_error_errno(r
, "sd_event_source_set_time() failed: %m");
2144 r
= sd_event_source_set_enabled(m
->scheduled_shutdown_timeout_source
, SD_EVENT_ONESHOT
);
2146 return log_error_errno(r
, "sd_event_source_set_enabled() failed: %m");
2148 r
= sd_event_add_time(m
->event
, &m
->scheduled_shutdown_timeout_source
,
2149 CLOCK_REALTIME
, elapse
, 0, manager_scheduled_shutdown_handler
, m
);
2151 return log_error_errno(r
, "sd_event_add_time() failed: %m");
2154 r
= free_and_strdup(&m
->scheduled_shutdown_type
, type
);
2156 m
->scheduled_shutdown_timeout_source
= sd_event_source_unref(m
->scheduled_shutdown_timeout_source
);
2160 m
->shutdown_dry_run
= dry_run
;
2162 if (m
->nologin_timeout_source
) {
2163 r
= sd_event_source_set_time(m
->nologin_timeout_source
, elapse
);
2165 return log_error_errno(r
, "sd_event_source_set_time() failed: %m");
2167 r
= sd_event_source_set_enabled(m
->nologin_timeout_source
, SD_EVENT_ONESHOT
);
2169 return log_error_errno(r
, "sd_event_source_set_enabled() failed: %m");
2171 r
= sd_event_add_time(m
->event
, &m
->nologin_timeout_source
,
2172 CLOCK_REALTIME
, elapse
- 5 * USEC_PER_MINUTE
, 0, nologin_timeout_handler
, m
);
2174 return log_error_errno(r
, "sd_event_add_time() failed: %m");
2177 m
->scheduled_shutdown_timeout
= elapse
;
2179 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_AUGMENT
|SD_BUS_CREDS_TTY
|SD_BUS_CREDS_UID
, &creds
);
2181 const char *tty
= NULL
;
2183 (void) sd_bus_creds_get_uid(creds
, &m
->scheduled_shutdown_uid
);
2184 (void) sd_bus_creds_get_tty(creds
, &tty
);
2186 r
= free_and_strdup(&m
->scheduled_shutdown_tty
, tty
);
2188 m
->scheduled_shutdown_timeout_source
= sd_event_source_unref(m
->scheduled_shutdown_timeout_source
);
2193 r
= manager_setup_wall_message_timer(m
);
2197 r
= update_schedule_file(m
);
2201 return sd_bus_reply_method_return(message
, NULL
);
2204 static int method_cancel_scheduled_shutdown(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2205 Manager
*m
= userdata
;
2211 cancelled
= m
->scheduled_shutdown_type
!= NULL
;
2212 reset_scheduled_shutdown(m
);
2215 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
2216 const char *tty
= NULL
;
2220 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_AUGMENT
|SD_BUS_CREDS_TTY
|SD_BUS_CREDS_UID
, &creds
);
2222 (void) sd_bus_creds_get_uid(creds
, &uid
);
2223 (void) sd_bus_creds_get_tty(creds
, &tty
);
2226 utmp_wall("The system shutdown has been cancelled",
2227 uid_to_name(uid
), tty
, logind_wall_tty_filter
, m
);
2230 return sd_bus_reply_method_return(message
, "b", cancelled
);
2233 static int method_can_shutdown_or_sleep(
2235 sd_bus_message
*message
,
2238 const char *action_multiple_sessions
,
2239 const char *action_ignore_inhibit
,
2240 const char *sleep_verb
,
2241 sd_bus_error
*error
) {
2243 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
2244 bool multiple_sessions
, challenge
, blocked
;
2245 const char *result
= NULL
;
2252 assert(w
<= _INHIBIT_WHAT_MAX
);
2254 assert(action_multiple_sessions
);
2255 assert(action_ignore_inhibit
);
2258 r
= can_sleep(sleep_verb
);
2262 return sd_bus_reply_method_return(message
, "s", "na");
2265 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
2269 r
= sd_bus_creds_get_euid(creds
, &uid
);
2273 r
= have_multiple_sessions(m
, uid
);
2277 multiple_sessions
= r
> 0;
2278 blocked
= manager_is_inhibited(m
, w
, INHIBIT_BLOCK
, NULL
, false, true, uid
, NULL
);
2280 if (multiple_sessions
) {
2281 r
= bus_test_polkit(message
, CAP_SYS_BOOT
, action_multiple_sessions
, NULL
, UID_INVALID
, &challenge
, error
);
2288 result
= "challenge";
2294 r
= bus_test_polkit(message
, CAP_SYS_BOOT
, action_ignore_inhibit
, NULL
, UID_INVALID
, &challenge
, error
);
2298 if (r
> 0 && !result
)
2300 else if (challenge
&& (!result
|| streq(result
, "yes")))
2301 result
= "challenge";
2306 if (!multiple_sessions
&& !blocked
) {
2307 /* If neither inhibit nor multiple sessions
2308 * apply then just check the normal policy */
2310 r
= bus_test_polkit(message
, CAP_SYS_BOOT
, action
, NULL
, UID_INVALID
, &challenge
, error
);
2317 result
= "challenge";
2322 return sd_bus_reply_method_return(message
, "s", result
);
2325 static int method_can_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2326 Manager
*m
= userdata
;
2328 return method_can_shutdown_or_sleep(
2331 "org.freedesktop.login1.power-off",
2332 "org.freedesktop.login1.power-off-multiple-sessions",
2333 "org.freedesktop.login1.power-off-ignore-inhibit",
2338 static int method_can_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2339 Manager
*m
= userdata
;
2341 return method_can_shutdown_or_sleep(
2344 "org.freedesktop.login1.reboot",
2345 "org.freedesktop.login1.reboot-multiple-sessions",
2346 "org.freedesktop.login1.reboot-ignore-inhibit",
2351 static int method_can_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2352 Manager
*m
= userdata
;
2354 return method_can_shutdown_or_sleep(
2357 "org.freedesktop.login1.halt",
2358 "org.freedesktop.login1.halt-multiple-sessions",
2359 "org.freedesktop.login1.halt-ignore-inhibit",
2364 static int method_can_suspend(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2365 Manager
*m
= userdata
;
2367 return method_can_shutdown_or_sleep(
2370 "org.freedesktop.login1.suspend",
2371 "org.freedesktop.login1.suspend-multiple-sessions",
2372 "org.freedesktop.login1.suspend-ignore-inhibit",
2377 static int method_can_hibernate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2378 Manager
*m
= userdata
;
2380 return method_can_shutdown_or_sleep(
2383 "org.freedesktop.login1.hibernate",
2384 "org.freedesktop.login1.hibernate-multiple-sessions",
2385 "org.freedesktop.login1.hibernate-ignore-inhibit",
2390 static int method_can_hybrid_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2391 Manager
*m
= userdata
;
2393 return method_can_shutdown_or_sleep(
2396 "org.freedesktop.login1.hibernate",
2397 "org.freedesktop.login1.hibernate-multiple-sessions",
2398 "org.freedesktop.login1.hibernate-ignore-inhibit",
2403 static int method_can_suspend_to_hibernate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2404 Manager
*m
= userdata
;
2406 return method_can_shutdown_or_sleep(
2409 "org.freedesktop.login1.hibernate",
2410 "org.freedesktop.login1.hibernate-multiple-sessions",
2411 "org.freedesktop.login1.hibernate-ignore-inhibit",
2412 "suspend-to-hibernate",
2416 static int property_get_reboot_to_firmware_setup(
2419 const char *interface
,
2420 const char *property
,
2421 sd_bus_message
*reply
,
2423 sd_bus_error
*error
) {
2430 r
= efi_get_reboot_to_firmware();
2431 if (r
< 0 && r
!= -EOPNOTSUPP
)
2432 log_warning_errno(r
, "Failed to determine reboot-to-firmware state: %m");
2434 return sd_bus_message_append(reply
, "b", r
> 0);
2437 static int method_set_reboot_to_firmware_setup(
2438 sd_bus_message
*message
,
2440 sd_bus_error
*error
) {
2443 Manager
*m
= userdata
;
2448 r
= sd_bus_message_read(message
, "b", &b
);
2452 r
= bus_verify_polkit_async(message
,
2454 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2458 &m
->polkit_registry
,
2463 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2465 r
= efi_set_reboot_to_firmware(b
);
2469 return sd_bus_reply_method_return(message
, NULL
);
2472 static int method_can_reboot_to_firmware_setup(
2473 sd_bus_message
*message
,
2475 sd_bus_error
*error
) {
2480 Manager
*m
= userdata
;
2485 r
= efi_reboot_to_firmware_supported();
2487 if (r
!= -EOPNOTSUPP
)
2488 log_warning_errno(errno
, "Failed to determine whether reboot to firmware is supported: %m");
2490 return sd_bus_reply_method_return(message
, "s", "na");
2493 r
= bus_test_polkit(message
,
2495 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2506 result
= "challenge";
2510 return sd_bus_reply_method_return(message
, "s", result
);
2513 static int method_set_wall_message(
2514 sd_bus_message
*message
,
2516 sd_bus_error
*error
) {
2519 Manager
*m
= userdata
;
2521 int enable_wall_messages
;
2526 r
= sd_bus_message_read(message
, "sb", &wall_message
, &enable_wall_messages
);
2530 r
= bus_verify_polkit_async(message
,
2532 "org.freedesktop.login1.set-wall-message",
2536 &m
->polkit_registry
,
2541 return 1; /* Will call us back */
2543 r
= free_and_strdup(&m
->wall_message
, empty_to_null(wall_message
));
2547 m
->enable_wall_messages
= enable_wall_messages
;
2549 return sd_bus_reply_method_return(message
, NULL
);
2552 static int method_inhibit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2553 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
2554 const char *who
, *why
, *what
, *mode
;
2555 _cleanup_free_
char *id
= NULL
;
2556 _cleanup_close_
int fifo_fd
= -1;
2557 Manager
*m
= userdata
;
2558 Inhibitor
*i
= NULL
;
2568 r
= sd_bus_message_read(message
, "ssss", &what
, &who
, &why
, &mode
);
2572 w
= inhibit_what_from_string(what
);
2574 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid what specification %s", what
);
2576 mm
= inhibit_mode_from_string(mode
);
2578 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid mode specification %s", mode
);
2580 /* Delay is only supported for shutdown/sleep */
2581 if (mm
== INHIBIT_DELAY
&& (w
& ~(INHIBIT_SHUTDOWN
|INHIBIT_SLEEP
)))
2582 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delay inhibitors only supported for shutdown and sleep");
2584 /* Don't allow taking delay locks while we are already
2585 * executing the operation. We shouldn't create the impression
2586 * that the lock was successful if the machine is about to go
2587 * down/suspend any moment. */
2588 if (m
->action_what
& w
)
2589 return sd_bus_error_setf(error
, BUS_ERROR_OPERATION_IN_PROGRESS
, "The operation inhibition has been requested for is already running");
2591 r
= bus_verify_polkit_async(
2594 w
== INHIBIT_SHUTDOWN
? (mm
== INHIBIT_BLOCK
? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2595 w
== INHIBIT_SLEEP
? (mm
== INHIBIT_BLOCK
? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2596 w
== INHIBIT_IDLE
? "org.freedesktop.login1.inhibit-block-idle" :
2597 w
== INHIBIT_HANDLE_POWER_KEY
? "org.freedesktop.login1.inhibit-handle-power-key" :
2598 w
== INHIBIT_HANDLE_SUSPEND_KEY
? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2599 w
== INHIBIT_HANDLE_HIBERNATE_KEY
? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2600 "org.freedesktop.login1.inhibit-handle-lid-switch",
2604 &m
->polkit_registry
,
2609 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2611 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
|SD_BUS_CREDS_PID
, &creds
);
2615 r
= sd_bus_creds_get_euid(creds
, &uid
);
2619 r
= sd_bus_creds_get_pid(creds
, &pid
);
2623 if (hashmap_size(m
->inhibitors
) >= m
->inhibitors_max
)
2624 return sd_bus_error_setf(error
, SD_BUS_ERROR_LIMITS_EXCEEDED
, "Maximum number of inhibitors (%" PRIu64
") reached, refusing further inhibitors.", m
->inhibitors_max
);
2629 if (asprintf(&id
, "%lu", ++m
->inhibit_counter
) < 0)
2632 } while (hashmap_get(m
->inhibitors
, id
));
2634 r
= manager_add_inhibitor(m
, id
, &i
);
2642 i
->why
= strdup(why
);
2643 i
->who
= strdup(who
);
2645 if (!i
->why
|| !i
->who
) {
2650 fifo_fd
= inhibitor_create_fifo(i
);
2658 return sd_bus_reply_method_return(message
, "h", fifo_fd
);
2667 const sd_bus_vtable manager_vtable
[] = {
2668 SD_BUS_VTABLE_START(0),
2670 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL
, NULL
, offsetof(Manager
, enable_wall_messages
), 0),
2671 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL
, NULL
, offsetof(Manager
, wall_message
), 0),
2673 SD_BUS_PROPERTY("NAutoVTs", "u", NULL
, offsetof(Manager
, n_autovts
), SD_BUS_VTABLE_PROPERTY_CONST
),
2674 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL
, offsetof(Manager
, kill_only_users
), SD_BUS_VTABLE_PROPERTY_CONST
),
2675 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL
, offsetof(Manager
, kill_exclude_users
), SD_BUS_VTABLE_PROPERTY_CONST
),
2676 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL
, offsetof(Manager
, kill_user_processes
), SD_BUS_VTABLE_PROPERTY_CONST
),
2677 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
2678 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
2679 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
2680 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
2681 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
2682 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
2683 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL
, offsetof(Manager
, inhibit_delay_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
2684 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action
, offsetof(Manager
, handle_power_key
), SD_BUS_VTABLE_PROPERTY_CONST
),
2685 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action
, offsetof(Manager
, handle_suspend_key
), SD_BUS_VTABLE_PROPERTY_CONST
),
2686 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action
, offsetof(Manager
, handle_hibernate_key
), SD_BUS_VTABLE_PROPERTY_CONST
),
2687 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action
, offsetof(Manager
, handle_lid_switch
), SD_BUS_VTABLE_PROPERTY_CONST
),
2688 SD_BUS_PROPERTY("HandleLidSwitchExternalPower", "s", property_get_handle_action
, offsetof(Manager
, handle_lid_switch_ep
), SD_BUS_VTABLE_PROPERTY_CONST
),
2689 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action
, offsetof(Manager
, handle_lid_switch_docked
), SD_BUS_VTABLE_PROPERTY_CONST
),
2690 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL
, offsetof(Manager
, holdoff_timeout_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
2691 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action
, offsetof(Manager
, idle_action
), SD_BUS_VTABLE_PROPERTY_CONST
),
2692 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL
, offsetof(Manager
, idle_action_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
2693 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing
, 0, 0),
2694 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing
, 0, 0),
2695 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown
, 0, 0),
2696 SD_BUS_PROPERTY("Docked", "b", property_get_docked
, 0, 0),
2697 SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool
, offsetof(Manager
, remove_ipc
), SD_BUS_VTABLE_PROPERTY_CONST
),
2698 SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size
, offsetof(Manager
, runtime_dir_size
), SD_BUS_VTABLE_PROPERTY_CONST
),
2699 SD_BUS_PROPERTY("InhibitorsMax", "t", NULL
, offsetof(Manager
, inhibitors_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
2700 SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors
, 0, 0),
2701 SD_BUS_PROPERTY("SessionsMax", "t", NULL
, offsetof(Manager
, sessions_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
2702 SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions
, 0, 0),
2703 SD_BUS_PROPERTY("UserTasksMax", "t", NULL
, offsetof(Manager
, user_tasks_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
2705 SD_BUS_METHOD("GetSession", "s", "o", method_get_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2706 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
2707 SD_BUS_METHOD("GetUser", "u", "o", method_get_user
, SD_BUS_VTABLE_UNPRIVILEGED
),
2708 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
2709 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat
, SD_BUS_VTABLE_UNPRIVILEGED
),
2710 SD_BUS_METHOD("ListSessions", NULL
, "a(susso)", method_list_sessions
, SD_BUS_VTABLE_UNPRIVILEGED
),
2711 SD_BUS_METHOD("ListUsers", NULL
, "a(uso)", method_list_users
, SD_BUS_VTABLE_UNPRIVILEGED
),
2712 SD_BUS_METHOD("ListSeats", NULL
, "a(so)", method_list_seats
, SD_BUS_VTABLE_UNPRIVILEGED
),
2713 SD_BUS_METHOD("ListInhibitors", NULL
, "a(ssssuu)", method_list_inhibitors
, SD_BUS_VTABLE_UNPRIVILEGED
),
2714 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session
, 0),
2715 SD_BUS_METHOD("ReleaseSession", "s", NULL
, method_release_session
, 0),
2716 SD_BUS_METHOD("ActivateSession", "s", NULL
, method_activate_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2717 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL
, method_activate_session_on_seat
, SD_BUS_VTABLE_UNPRIVILEGED
),
2718 SD_BUS_METHOD("LockSession", "s", NULL
, method_lock_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2719 SD_BUS_METHOD("UnlockSession", "s", NULL
, method_lock_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2720 SD_BUS_METHOD("LockSessions", NULL
, NULL
, method_lock_sessions
, SD_BUS_VTABLE_UNPRIVILEGED
),
2721 SD_BUS_METHOD("UnlockSessions", NULL
, NULL
, method_lock_sessions
, SD_BUS_VTABLE_UNPRIVILEGED
),
2722 SD_BUS_METHOD("KillSession", "ssi", NULL
, method_kill_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2723 SD_BUS_METHOD("KillUser", "ui", NULL
, method_kill_user
, SD_BUS_VTABLE_UNPRIVILEGED
),
2724 SD_BUS_METHOD("TerminateSession", "s", NULL
, method_terminate_session
, SD_BUS_VTABLE_UNPRIVILEGED
),
2725 SD_BUS_METHOD("TerminateUser", "u", NULL
, method_terminate_user
, SD_BUS_VTABLE_UNPRIVILEGED
),
2726 SD_BUS_METHOD("TerminateSeat", "s", NULL
, method_terminate_seat
, SD_BUS_VTABLE_UNPRIVILEGED
),
2727 SD_BUS_METHOD("SetUserLinger", "ubb", NULL
, method_set_user_linger
, SD_BUS_VTABLE_UNPRIVILEGED
),
2728 SD_BUS_METHOD("AttachDevice", "ssb", NULL
, method_attach_device
, SD_BUS_VTABLE_UNPRIVILEGED
),
2729 SD_BUS_METHOD("FlushDevices", "b", NULL
, method_flush_devices
, SD_BUS_VTABLE_UNPRIVILEGED
),
2730 SD_BUS_METHOD("PowerOff", "b", NULL
, method_poweroff
, SD_BUS_VTABLE_UNPRIVILEGED
),
2731 SD_BUS_METHOD("Reboot", "b", NULL
, method_reboot
, SD_BUS_VTABLE_UNPRIVILEGED
),
2732 SD_BUS_METHOD("Halt", "b", NULL
, method_halt
, SD_BUS_VTABLE_UNPRIVILEGED
),
2733 SD_BUS_METHOD("Suspend", "b", NULL
, method_suspend
, SD_BUS_VTABLE_UNPRIVILEGED
),
2734 SD_BUS_METHOD("Hibernate", "b", NULL
, method_hibernate
, SD_BUS_VTABLE_UNPRIVILEGED
),
2735 SD_BUS_METHOD("HybridSleep", "b", NULL
, method_hybrid_sleep
, SD_BUS_VTABLE_UNPRIVILEGED
),
2736 SD_BUS_METHOD("SuspendToHibernate", "b", NULL
, method_suspend_to_hibernate
, SD_BUS_VTABLE_UNPRIVILEGED
),
2737 SD_BUS_METHOD("CanPowerOff", NULL
, "s", method_can_poweroff
, SD_BUS_VTABLE_UNPRIVILEGED
),
2738 SD_BUS_METHOD("CanReboot", NULL
, "s", method_can_reboot
, SD_BUS_VTABLE_UNPRIVILEGED
),
2739 SD_BUS_METHOD("CanHalt", NULL
, "s", method_can_halt
, SD_BUS_VTABLE_UNPRIVILEGED
),
2740 SD_BUS_METHOD("CanSuspend", NULL
, "s", method_can_suspend
, SD_BUS_VTABLE_UNPRIVILEGED
),
2741 SD_BUS_METHOD("CanHibernate", NULL
, "s", method_can_hibernate
, SD_BUS_VTABLE_UNPRIVILEGED
),
2742 SD_BUS_METHOD("CanHybridSleep", NULL
, "s", method_can_hybrid_sleep
, SD_BUS_VTABLE_UNPRIVILEGED
),
2743 SD_BUS_METHOD("CanSuspendToHibernate", NULL
, "s", method_can_suspend_to_hibernate
, SD_BUS_VTABLE_UNPRIVILEGED
),
2744 SD_BUS_METHOD("ScheduleShutdown", "st", NULL
, method_schedule_shutdown
, SD_BUS_VTABLE_UNPRIVILEGED
),
2745 SD_BUS_METHOD("CancelScheduledShutdown", NULL
, "b", method_cancel_scheduled_shutdown
, SD_BUS_VTABLE_UNPRIVILEGED
),
2746 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit
, SD_BUS_VTABLE_UNPRIVILEGED
),
2747 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL
, "s", method_can_reboot_to_firmware_setup
, SD_BUS_VTABLE_UNPRIVILEGED
),
2748 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL
, method_set_reboot_to_firmware_setup
, SD_BUS_VTABLE_UNPRIVILEGED
),
2749 SD_BUS_METHOD("SetWallMessage", "sb", NULL
, method_set_wall_message
, SD_BUS_VTABLE_UNPRIVILEGED
),
2751 SD_BUS_SIGNAL("SessionNew", "so", 0),
2752 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2753 SD_BUS_SIGNAL("UserNew", "uo", 0),
2754 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2755 SD_BUS_SIGNAL("SeatNew", "so", 0),
2756 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2757 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2758 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2763 static int session_jobs_reply(Session
*s
, const char *unit
, const char *result
) {
2772 if (streq(result
, "done"))
2773 r
= session_send_create_reply(s
, NULL
);
2775 _cleanup_(sd_bus_error_free
) sd_bus_error e
= SD_BUS_ERROR_NULL
;
2777 sd_bus_error_setf(&e
, BUS_ERROR_JOB_FAILED
, "Start job for unit %s failed with '%s'", unit
, result
);
2778 r
= session_send_create_reply(s
, &e
);
2784 int match_job_removed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2785 const char *path
, *result
, *unit
;
2786 Manager
*m
= userdata
;
2795 r
= sd_bus_message_read(message
, "uoss", &id
, &path
, &unit
, &result
);
2797 bus_log_parse_error(r
);
2801 if (m
->action_job
&& streq(m
->action_job
, path
)) {
2802 log_info("Operation '%s' finished.", inhibit_what_to_string(m
->action_what
));
2804 /* Tell people that they now may take a lock again */
2805 (void) send_prepare_for(m
, m
->action_what
, false);
2807 m
->action_job
= mfree(m
->action_job
);
2808 m
->action_unit
= NULL
;
2813 session
= hashmap_get(m
->session_units
, unit
);
2814 if (session
&& streq_ptr(path
, session
->scope_job
)) {
2815 session
->scope_job
= mfree(session
->scope_job
);
2816 session_jobs_reply(session
, unit
, result
);
2818 session_save(session
);
2819 user_save(session
->user
);
2820 session_add_to_gc_queue(session
);
2823 user
= hashmap_get(m
->user_units
, unit
);
2825 (streq_ptr(path
, user
->service_job
) ||
2826 streq_ptr(path
, user
->slice_job
))) {
2828 if (streq_ptr(path
, user
->service_job
))
2829 user
->service_job
= mfree(user
->service_job
);
2831 if (streq_ptr(path
, user
->slice_job
))
2832 user
->slice_job
= mfree(user
->slice_job
);
2834 LIST_FOREACH(sessions_by_user
, session
, user
->sessions
)
2835 session_jobs_reply(session
, unit
, result
);
2838 user_add_to_gc_queue(user
);
2844 int match_unit_removed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2845 const char *path
, *unit
;
2846 Manager
*m
= userdata
;
2854 r
= sd_bus_message_read(message
, "so", &unit
, &path
);
2856 bus_log_parse_error(r
);
2860 session
= hashmap_get(m
->session_units
, unit
);
2862 session_add_to_gc_queue(session
);
2864 user
= hashmap_get(m
->user_units
, unit
);
2866 user_add_to_gc_queue(user
);
2871 int match_properties_changed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2872 _cleanup_free_
char *unit
= NULL
;
2873 Manager
*m
= userdata
;
2882 path
= sd_bus_message_get_path(message
);
2886 r
= unit_name_from_dbus_path(path
, &unit
);
2887 if (r
== -EINVAL
) /* not a unit */
2894 session
= hashmap_get(m
->session_units
, unit
);
2896 session_add_to_gc_queue(session
);
2898 user
= hashmap_get(m
->user_units
, unit
);
2900 user_add_to_gc_queue(user
);
2905 int match_reloading(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
2906 Manager
*m
= userdata
;
2914 r
= sd_bus_message_read(message
, "b", &b
);
2916 bus_log_parse_error(r
);
2923 /* systemd finished reloading, let's recheck all our sessions */
2924 log_debug("System manager has been reloaded, rechecking sessions...");
2926 HASHMAP_FOREACH(session
, m
->sessions
, i
)
2927 session_add_to_gc_queue(session
);
2932 int manager_send_changed(Manager
*manager
, const char *property
, ...) {
2937 l
= strv_from_stdarg_alloca(property
);
2939 return sd_bus_emit_properties_changed_strv(
2941 "/org/freedesktop/login1",
2942 "org.freedesktop.login1.Manager",
2946 static int strdup_job(sd_bus_message
*reply
, char **job
) {
2951 r
= sd_bus_message_read(reply
, "o", &j
);
2963 int manager_start_slice(
2966 const char *description
,
2970 sd_bus_error
*error
,
2973 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
2980 r
= sd_bus_message_new_method_call(
2983 "org.freedesktop.systemd1",
2984 "/org/freedesktop/systemd1",
2985 "org.freedesktop.systemd1.Manager",
2986 "StartTransientUnit");
2990 r
= sd_bus_message_append(m
, "ss", strempty(slice
), "fail");
2994 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
2998 if (!isempty(description
)) {
2999 r
= sd_bus_message_append(m
, "(sv)", "Description", "s", description
);
3004 if (!isempty(after
)) {
3005 r
= sd_bus_message_append(m
, "(sv)", "After", "as", 1, after
);
3010 if (!isempty(after2
)) {
3011 r
= sd_bus_message_append(m
, "(sv)", "After", "as", 1, after2
);
3016 r
= sd_bus_message_append(m
, "(sv)", "TasksMax", "t", tasks_max
);
3020 r
= sd_bus_message_close_container(m
);
3024 r
= sd_bus_message_append(m
, "a(sa(sv))", 0);
3028 r
= sd_bus_call(manager
->bus
, m
, 0, error
, &reply
);
3032 return strdup_job(reply
, job
);
3035 int manager_start_scope(
3040 const char *description
,
3044 sd_bus_error
*error
,
3047 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
3055 r
= sd_bus_message_new_method_call(
3058 "org.freedesktop.systemd1",
3059 "/org/freedesktop/systemd1",
3060 "org.freedesktop.systemd1.Manager",
3061 "StartTransientUnit");
3065 r
= sd_bus_message_append(m
, "ss", strempty(scope
), "fail");
3069 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
3073 if (!isempty(slice
)) {
3074 r
= sd_bus_message_append(m
, "(sv)", "Slice", "s", slice
);
3079 if (!isempty(description
)) {
3080 r
= sd_bus_message_append(m
, "(sv)", "Description", "s", description
);
3085 if (!isempty(after
)) {
3086 r
= sd_bus_message_append(m
, "(sv)", "After", "as", 1, after
);
3091 if (!isempty(after2
)) {
3092 r
= sd_bus_message_append(m
, "(sv)", "After", "as", 1, after2
);
3097 /* cgroup empty notification is not available in containers
3098 * currently. To make this less problematic, let's shorten the
3099 * stop timeout for sessions, so that we don't wait
3102 /* Make sure that the session shells are terminated with
3103 * SIGHUP since bash and friends tend to ignore SIGTERM */
3104 r
= sd_bus_message_append(m
, "(sv)", "SendSIGHUP", "b", true);
3108 r
= sd_bus_message_append(m
, "(sv)", "PIDs", "au", 1, pid
);
3112 r
= sd_bus_message_append(m
, "(sv)", "TasksMax", "t", tasks_max
);
3116 r
= sd_bus_message_close_container(m
);
3120 r
= sd_bus_message_append(m
, "a(sa(sv))", 0);
3124 r
= sd_bus_call(manager
->bus
, m
, 0, error
, &reply
);
3128 return strdup_job(reply
, job
);
3131 int manager_start_unit(Manager
*manager
, const char *unit
, sd_bus_error
*error
, char **job
) {
3132 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3139 r
= sd_bus_call_method(
3141 "org.freedesktop.systemd1",
3142 "/org/freedesktop/systemd1",
3143 "org.freedesktop.systemd1.Manager",
3147 "ss", unit
, "replace");
3151 return strdup_job(reply
, job
);
3154 int manager_stop_unit(Manager
*manager
, const char *unit
, sd_bus_error
*error
, char **job
) {
3155 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3162 r
= sd_bus_call_method(
3164 "org.freedesktop.systemd1",
3165 "/org/freedesktop/systemd1",
3166 "org.freedesktop.systemd1.Manager",
3170 "ss", unit
, "fail");
3172 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) ||
3173 sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
)) {
3176 sd_bus_error_free(error
);
3183 return strdup_job(reply
, job
);
3186 int manager_abandon_scope(Manager
*manager
, const char *scope
, sd_bus_error
*error
) {
3187 _cleanup_free_
char *path
= NULL
;
3193 path
= unit_dbus_path_from_name(scope
);
3197 r
= sd_bus_call_method(
3199 "org.freedesktop.systemd1",
3201 "org.freedesktop.systemd1.Scope",
3207 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) ||
3208 sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
) ||
3209 sd_bus_error_has_name(error
, BUS_ERROR_SCOPE_NOT_RUNNING
)) {
3210 sd_bus_error_free(error
);
3220 int manager_kill_unit(Manager
*manager
, const char *unit
, KillWho who
, int signo
, sd_bus_error
*error
) {
3224 return sd_bus_call_method(
3226 "org.freedesktop.systemd1",
3227 "/org/freedesktop/systemd1",
3228 "org.freedesktop.systemd1.Manager",
3232 "ssi", unit
, who
== KILL_LEADER
? "main" : "all", signo
);
3235 int manager_unit_is_active(Manager
*manager
, const char *unit
) {
3236 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3237 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3238 _cleanup_free_
char *path
= NULL
;
3245 path
= unit_dbus_path_from_name(unit
);
3249 r
= sd_bus_get_property(
3251 "org.freedesktop.systemd1",
3253 "org.freedesktop.systemd1.Unit",
3259 /* systemd might have droppped off momentarily, let's
3260 * not make this an error */
3261 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_NO_REPLY
) ||
3262 sd_bus_error_has_name(&error
, SD_BUS_ERROR_DISCONNECTED
))
3265 /* If the unit is already unloaded then it's not
3267 if (sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
) ||
3268 sd_bus_error_has_name(&error
, BUS_ERROR_LOAD_FAILED
))
3274 r
= sd_bus_message_read(reply
, "s", &state
);
3278 return !streq(state
, "inactive") && !streq(state
, "failed");
3281 int manager_job_is_active(Manager
*manager
, const char *path
) {
3282 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3283 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3289 r
= sd_bus_get_property(
3291 "org.freedesktop.systemd1",
3293 "org.freedesktop.systemd1.Job",
3299 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_NO_REPLY
) ||
3300 sd_bus_error_has_name(&error
, SD_BUS_ERROR_DISCONNECTED
))
3303 if (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_OBJECT
))
3309 /* We don't actually care about the state really. The fact
3310 * that we could read the job state is enough for us */