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"
44 static int property_get_idle_hint(
47 const char *interface,
49 sd_bus_message *reply,
53 Manager *m = userdata;
59 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
62 static int property_get_idle_since_hint(
65 const char *interface,
67 sd_bus_message *reply,
71 Manager *m = userdata;
78 manager_get_idle_hint(m, &t);
80 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
83 static int property_get_inhibited(
86 const char *interface,
88 sd_bus_message *reply,
92 Manager *m = userdata;
99 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
101 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
104 static int property_get_preparing(
107 const char *interface,
108 const char *property,
109 sd_bus_message *reply,
113 Manager *m = userdata;
120 if (streq(property, "PreparingForShutdown"))
121 b = !!(m->action_what & INHIBIT_SHUTDOWN);
123 b = !!(m->action_what & INHIBIT_SLEEP);
125 return sd_bus_message_append(reply, "b", b);
128 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
130 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
131 _cleanup_free_ char *p = NULL;
132 Manager *m = userdata;
141 r = sd_bus_message_read(message, "s", &name);
143 return sd_bus_reply_method_errno(bus, message, r, NULL);
145 session = hashmap_get(m->sessions, name);
147 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
149 p = session_bus_path(session);
151 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
153 return sd_bus_reply_method_return(bus, message, "o", p);
156 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata) {
157 _cleanup_free_ char *p = NULL;
158 Session *session = NULL;
159 Manager *m = userdata;
167 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
169 r = sd_bus_message_read(message, "u", &pid);
171 return sd_bus_reply_method_errno(bus, message, r, NULL);
174 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
176 return sd_bus_reply_method_errno(bus, message, r, NULL);
179 r = manager_get_session_by_pid(m, pid, &session);
181 return sd_bus_reply_method_errno(bus, message, r, NULL);
183 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
185 p = session_bus_path(session);
187 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
189 return sd_bus_reply_method_return(bus, message, "o", p);
192 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
193 _cleanup_free_ char *p = NULL;
194 Manager *m = userdata;
203 r = sd_bus_message_read(message, "u", &uid);
205 return sd_bus_reply_method_errno(bus, message, r, NULL);
207 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
209 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
211 p = user_bus_path(user);
213 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
215 return sd_bus_reply_method_return(bus, message, "o", p);
218 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata) {
219 _cleanup_free_ char *p = NULL;
220 Manager *m = userdata;
229 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
231 r = sd_bus_message_read(message, "u", &pid);
233 return sd_bus_reply_method_errno(bus, message, r, NULL);
236 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
238 return sd_bus_reply_method_errno(bus, message, r, NULL);
241 r = manager_get_user_by_pid(m, pid, &user);
243 return sd_bus_reply_method_errno(bus, message, r, NULL);
245 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
247 p = user_bus_path(user);
249 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
251 return sd_bus_reply_method_return(bus, message, "o", p);
254 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
255 _cleanup_free_ char *p = NULL;
256 Manager *m = userdata;
265 r = sd_bus_message_read(message, "s", &name);
267 return sd_bus_reply_method_errno(bus, message, r, NULL);
269 seat = hashmap_get(m->seats, name);
271 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
273 p = seat_bus_path(seat);
275 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
277 return sd_bus_reply_method_return(bus, message, "o", p);
280 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata) {
281 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
282 Manager *m = userdata;
291 r = sd_bus_message_new_method_return(bus, message, &reply);
293 return sd_bus_reply_method_errno(bus, message, r, NULL);
295 r = sd_bus_message_open_container(reply, 'a', "(susso)");
297 return sd_bus_reply_method_errno(bus, message, r, NULL);
299 HASHMAP_FOREACH(session, m->sessions, i) {
300 _cleanup_free_ char *p = NULL;
302 p = session_bus_path(session);
304 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
306 r = sd_bus_message_append(reply, "(susso)",
308 (uint32_t) session->user->uid,
310 session->seat ? session->seat->id : "",
313 return sd_bus_reply_method_errno(bus, message, r, NULL);
316 r = sd_bus_message_close_container(reply);
318 return sd_bus_reply_method_errno(bus, message, r, NULL);
320 return sd_bus_send(bus, reply, NULL);
323 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata) {
324 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
325 Manager *m = userdata;
334 r = sd_bus_message_new_method_return(bus, message, &reply);
336 return sd_bus_reply_method_errno(bus, message, r, NULL);
338 r = sd_bus_message_open_container(reply, 'a', "(uso)");
340 return sd_bus_reply_method_errno(bus, message, r, NULL);
342 HASHMAP_FOREACH(user, m->users, i) {
343 _cleanup_free_ char *p = NULL;
345 p = user_bus_path(user);
347 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
349 r = sd_bus_message_append(reply, "(uso)",
350 (uint32_t) user->uid,
354 return sd_bus_reply_method_errno(bus, message, r, NULL);
357 r = sd_bus_message_close_container(reply);
359 return sd_bus_reply_method_errno(bus, message, r, NULL);
361 return sd_bus_send(bus, reply, NULL);
364 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata) {
365 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
366 Manager *m = userdata;
375 r = sd_bus_message_new_method_return(bus, message, &reply);
377 return sd_bus_reply_method_errno(bus, message, r, NULL);
379 r = sd_bus_message_open_container(reply, 'a', "(so)");
381 return sd_bus_reply_method_errno(bus, message, r, NULL);
383 HASHMAP_FOREACH(seat, m->seats, i) {
384 _cleanup_free_ char *p = NULL;
386 p = seat_bus_path(seat);
388 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
390 r = sd_bus_message_append(reply, "(so)", seat->id, p);
392 return sd_bus_reply_method_errno(bus, message, r, NULL);
395 r = sd_bus_message_close_container(reply);
397 return sd_bus_reply_method_errno(bus, message, r, NULL);
399 return sd_bus_send(bus, reply, NULL);
402 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata) {
403 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
404 Manager *m = userdata;
405 Inhibitor *inhibitor;
409 r = sd_bus_message_new_method_return(bus, message, &reply);
411 return sd_bus_reply_method_errno(bus, message, r, NULL);
413 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
415 return sd_bus_reply_method_errno(bus, message, r, NULL);
417 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
419 r = sd_bus_message_append(reply, "(ssssuu)",
420 strempty(inhibit_what_to_string(inhibitor->what)),
421 strempty(inhibitor->who),
422 strempty(inhibitor->why),
423 strempty(inhibit_mode_to_string(inhibitor->mode)),
424 (uint32_t) inhibitor->uid,
425 (uint32_t) inhibitor->pid);
427 return sd_bus_reply_method_errno(bus, message, r, NULL);
430 r = sd_bus_message_close_container(reply);
432 return sd_bus_reply_method_errno(bus, message, r, NULL);
434 return sd_bus_send(bus, reply, NULL);
437 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
438 const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
439 uint32_t uid, leader, audit_id = 0;
440 _cleanup_free_ char *id = NULL;
441 Session *session = NULL;
442 Manager *m = userdata;
455 r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
457 return sd_bus_reply_method_errno(bus, message, r, NULL);
460 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
463 t = _SESSION_TYPE_INVALID;
465 t = session_type_from_string(type);
467 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
471 c = _SESSION_CLASS_INVALID;
473 c = session_class_from_string(class);
475 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
481 seat = hashmap_get(m->seats, cseat);
483 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
486 if (tty_is_vc(tty)) {
491 else if (seat != m->seat0)
492 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
494 v = vtnr_from_tty(tty);
496 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
500 else if (vtnr != (uint32_t) v)
501 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
503 } else if (tty_is_console(tty)) {
507 else if (seat != m->seat0)
508 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
511 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
515 if (seat_has_vts(seat)) {
517 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
520 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
524 r = sd_bus_message_enter_container(message, 'a', "(sv)");
526 return sd_bus_reply_method_errno(bus, message, r, NULL);
528 if (t == _SESSION_TYPE_INVALID) {
529 if (!isempty(display))
531 else if (!isempty(tty))
534 t = SESSION_UNSPECIFIED;
537 if (c == _SESSION_CLASS_INVALID) {
538 if (!isempty(display) || !isempty(tty))
541 c = SESSION_BACKGROUND;
545 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
547 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
549 return sd_bus_reply_method_errno(bus, message, r, NULL);
552 manager_get_session_by_pid(m, leader, &session);
554 _cleanup_free_ char *path = NULL;
555 _cleanup_close_ int fifo_fd = -1;
557 /* Session already exists, client is probably
558 * something like "su" which changes uid but is still
559 * the same session */
561 fifo_fd = session_create_fifo(session);
563 return sd_bus_reply_method_errno(bus, message, fifo_fd, NULL);
565 path = session_bus_path(session);
567 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
569 return sd_bus_reply_method_return(
570 bus, message, "soshsub",
573 session->user->runtime_path,
575 session->seat ? session->seat->id : "",
576 (uint32_t) session->vtnr,
580 audit_session_from_pid(leader, &audit_id);
582 /* Keep our session IDs and the audit session IDs in sync */
584 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
585 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
587 /* Wut? There's already a session by this name and we
588 * didn't find it above? Weird, then let's not trust
589 * the audit data and let's better register a new
591 if (hashmap_get(m->sessions, id)) {
592 log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
605 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
606 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
608 } while (hashmap_get(m->sessions, id));
611 r = manager_add_user_by_uid(m, uid, &user);
613 r = sd_bus_reply_method_errno(bus, message, r, NULL);
617 r = manager_add_session(m, id, &session);
619 r = sd_bus_reply_method_errno(bus, message, r, NULL);
623 session_set_user(session, user);
625 session->leader = leader;
626 session->audit_id = audit_id;
629 session->remote = remote;
630 session->vtnr = vtnr;
633 session->tty = strdup(tty);
635 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
640 if (!isempty(display)) {
641 session->display = strdup(display);
642 if (!session->display) {
643 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
648 if (!isempty(remote_user)) {
649 session->remote_user = strdup(remote_user);
650 if (!session->remote_user) {
651 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
656 if (!isempty(remote_host)) {
657 session->remote_host = strdup(remote_host);
658 if (!session->remote_host) {
659 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
664 if (!isempty(service)) {
665 session->service = strdup(service);
666 if (!session->service) {
667 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
673 r = seat_attach_session(seat, session);
675 r = sd_bus_reply_method_errno(bus, message, r, NULL);
680 r = session_start(session);
682 r = sd_bus_reply_method_errno(bus, message, r, NULL);
686 session->create_message = sd_bus_message_ref(message);
688 /* Now, let's wait until the slice unit and stuff got
689 * created. We send the reply back from
690 * session_send_create_reply().*/
696 session_add_to_gc_queue(session);
699 user_add_to_gc_queue(user);
704 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
705 Manager *m = userdata;
714 r = sd_bus_message_read(message, "s", &name);
716 return sd_bus_reply_method_errno(bus, message, r, NULL);
718 session = hashmap_get(m->sessions, name);
720 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
722 /* We use the FIFO to detect stray sessions where the process
723 invoking PAM dies abnormally. We need to make sure that
724 that process is not killed if at the clean end of the
725 session it closes the FIFO. Hence, with this call
726 explicitly turn off the FIFO logic, so that the PAM code
727 can finish clean up on its own */
728 session_remove_fifo(session);
729 session_save(session);
730 user_save(session->user);
732 return sd_bus_reply_method_return(bus, message, NULL);
735 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
736 Manager *m = userdata;
745 r = sd_bus_message_read(message, "s", &name);
747 return sd_bus_reply_method_errno(bus, message, r, NULL);
749 session = hashmap_get(m->sessions, name);
751 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
753 r = session_activate(session);
755 return sd_bus_reply_method_errno(bus, message, r, NULL);
757 return sd_bus_reply_method_return(bus, message, NULL);
760 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
761 const char *session_name, *seat_name;
762 Manager *m = userdata;
771 /* Same as ActivateSession() but refuses to work if
772 * the seat doesn't match */
774 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
776 return sd_bus_reply_method_errno(bus, message, r, NULL);
778 session = hashmap_get(m->sessions, session_name);
780 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
782 seat = hashmap_get(m->seats, seat_name);
784 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
786 if (session->seat != seat)
787 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
789 r = session_activate(session);
791 return sd_bus_reply_method_errno(bus, message, r, NULL);
793 return sd_bus_reply_method_return(bus, message, NULL);
796 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
797 Manager *m = userdata;
806 r = sd_bus_message_read(message, "s", &name);
808 return sd_bus_reply_method_errno(bus, message, r, NULL);
810 session = hashmap_get(m->sessions, name);
812 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
814 r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
816 return sd_bus_reply_method_errno(bus, message, r, NULL);
818 return sd_bus_reply_method_return(bus, message, NULL);
821 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata) {
822 Manager *m = userdata;
829 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
831 return sd_bus_reply_method_errno(bus, message, r, NULL);
833 return sd_bus_reply_method_return(bus, message, NULL);
836 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
837 const char *name, *swho;
838 Manager *m = userdata;
848 r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
850 return sd_bus_reply_method_errno(bus, message, r, NULL);
855 who = kill_who_from_string(swho);
857 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
860 if (signo <= 0 || signo >= _NSIG)
861 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
863 session = hashmap_get(m->sessions, name);
865 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
867 r = session_kill(session, who, signo);
869 return sd_bus_reply_method_errno(bus, message, r, NULL);
871 return sd_bus_reply_method_return(bus, message, NULL);
874 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
875 Manager *m = userdata;
885 r = sd_bus_message_read(message, "ui", &uid, &signo);
887 return sd_bus_reply_method_errno(bus, message, r, NULL);
889 if (signo <= 0 || signo >= _NSIG)
890 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
892 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
894 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
896 r = user_kill(user, signo);
898 return sd_bus_reply_method_errno(bus, message, r, NULL);
900 return sd_bus_reply_method_return(bus, message, NULL);
903 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
904 Manager *m = userdata;
913 r = sd_bus_message_read(message, "s", &name);
915 return sd_bus_reply_method_errno(bus, message, r, NULL);
917 session = hashmap_get(m->sessions, name);
919 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
921 r = session_stop(session);
923 return sd_bus_reply_method_errno(bus, message, r, NULL);
925 return sd_bus_reply_method_return(bus, message, NULL);
928 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata) {
929 Manager *m = userdata;
938 r = sd_bus_message_read(message, "u", &uid);
940 return sd_bus_reply_method_errno(bus, message, r, NULL);
942 user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
944 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
948 return sd_bus_reply_method_errno(bus, message, r, NULL);
950 return sd_bus_reply_method_return(bus, message, NULL);
953 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata) {
954 Manager *m = userdata;
963 r = sd_bus_message_read(message, "s", &name);
965 return sd_bus_reply_method_errno(bus, message, r, NULL);
967 seat = hashmap_get(m->seats, name);
969 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
971 r = seat_stop_sessions(seat);
973 return sd_bus_reply_method_errno(bus, message, r, NULL);
975 return sd_bus_reply_method_return(bus, message, NULL);
978 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata) {
979 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
980 _cleanup_free_ char *cc = NULL;
981 Manager *m = userdata;
992 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
994 return sd_bus_reply_method_errno(bus, message, r, NULL);
999 return sd_bus_reply_method_errno(bus, message, errno ? errno : ENOENT, NULL);
1001 r = bus_verify_polkit_async(bus,
1002 &m->polkit_registry,
1004 "org.freedesktop.login1.set-user-linger",
1007 method_set_user_linger, m);
1009 return sd_bus_reply_method_errno(bus, message, r, &error);
1011 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1013 mkdir_p_label("/var/lib/systemd", 0755);
1015 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1017 return sd_bus_reply_method_errno(bus, message, r, NULL);
1019 cc = cescape(pw->pw_name);
1021 return sd_bus_reply_method_errno(bus, message, ENOMEM, NULL);
1023 path = strappenda("/var/lib/systemd/linger/", cc);
1029 return sd_bus_reply_method_errno(bus, message, r, NULL);
1031 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1038 if (r < 0 && errno != ENOENT)
1039 return sd_bus_reply_method_errno(bus, message, errno, NULL);
1041 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1043 user_add_to_gc_queue(u);
1046 return sd_bus_reply_method_return(bus, message, NULL);
1049 static int trigger_device(Manager *m, struct udev_device *d) {
1050 struct udev_enumerate *e;
1051 struct udev_list_entry *first, *item;
1056 e = udev_enumerate_new(m->udev);
1063 if (udev_enumerate_add_match_parent(e, d) < 0) {
1069 if (udev_enumerate_scan_devices(e) < 0) {
1074 first = udev_enumerate_get_list_entry(e);
1075 udev_list_entry_foreach(item, first) {
1076 _cleanup_free_ char *t = NULL;
1079 p = udev_list_entry_get_name(item);
1081 t = strappend(p, "/uevent");
1087 write_string_file(t, "change");
1094 udev_enumerate_unref(e);
1099 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1100 _cleanup_free_ char *rule = NULL, *file = NULL;
1101 const char *id_for_seat;
1102 struct udev_device *d;
1109 d = udev_device_new_from_syspath(m->udev, sysfs);
1113 if (!udev_device_has_tag(d, "seat")) {
1118 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1124 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
1129 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1134 mkdir_p_label("/etc/udev/rules.d", 0755);
1136 r = write_string_file_atomic_label(file, rule);
1140 r = trigger_device(m, d);
1144 udev_device_unref(d);
1149 static int flush_devices(Manager *m) {
1150 _cleanup_closedir_ DIR *d;
1154 d = opendir("/etc/udev/rules.d");
1156 if (errno != ENOENT)
1157 log_warning("Failed to open /etc/udev/rules.d: %m");
1161 while ((de = readdir(d))) {
1163 if (!dirent_is_file(de))
1166 if (!startswith(de->d_name, "72-seat-"))
1169 if (!endswith(de->d_name, ".rules"))
1172 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1173 log_warning("Failed to unlink %s: %m", de->d_name);
1177 return trigger_device(m, NULL);
1180 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata) {
1181 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1182 const char *sysfs, *seat;
1183 Manager *m = userdata;
1190 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1192 return sd_bus_reply_method_errno(bus, message, r, NULL);
1194 if (!path_startswith(sysfs, "/sys"))
1195 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1197 if (!seat_name_is_valid(seat))
1198 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1200 r = bus_verify_polkit_async(bus,
1201 &m->polkit_registry,
1203 "org.freedesktop.login1.attach-device",
1206 method_attach_device, m);
1208 return sd_bus_reply_method_errno(bus, message, r, &error);
1210 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1212 r = attach_device(m, seat, sysfs);
1214 return sd_bus_reply_method_errno(bus, message, r, NULL);
1216 return sd_bus_reply_method_return(bus, message, NULL);
1219 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata) {
1220 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1221 Manager *m = userdata;
1228 r = sd_bus_message_read(message, "b", &interactive);
1230 return sd_bus_reply_method_errno(bus, message, r, NULL);
1232 r = bus_verify_polkit_async(bus,
1233 &m->polkit_registry,
1235 "org.freedesktop.login1.flush-devices",
1238 method_flush_devices, m);
1240 return sd_bus_reply_method_errno(bus, message, r, &error);
1242 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1244 r = flush_devices(m);
1246 return sd_bus_reply_method_errno(bus, message, r, &error);
1248 return sd_bus_reply_method_return(bus, message, NULL);
1251 static int have_multiple_sessions(
1260 /* Check for other users' sessions. Greeter sessions do not
1261 * count, and non-login sessions do not count either. */
1262 HASHMAP_FOREACH(session, m->sessions, i)
1263 if (session->class == SESSION_USER &&
1264 !session->closing &&
1265 session->user->uid != uid)
1271 static int bus_manager_log_shutdown(
1274 const char *unit_name) {
1281 if (w != INHIBIT_SHUTDOWN)
1284 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1285 p = "MESSAGE=System is powering down.";
1286 q = "SHUTDOWN=power-off";
1287 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1288 p = "MESSAGE=System is halting.";
1289 q = "SHUTDOWN=halt";
1290 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1291 p = "MESSAGE=System is rebooting.";
1292 q = "SHUTDOWN=reboot";
1293 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1294 p = "MESSAGE=System is rebooting with kexec.";
1295 q = "SHUTDOWN=kexec";
1297 p = "MESSAGE=System is shutting down.";
1301 return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1306 static int execute_shutdown_or_sleep(
1309 const char *unit_name,
1310 sd_bus_error *error) {
1312 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1319 assert(w < _INHIBIT_WHAT_MAX);
1322 bus_manager_log_shutdown(m, w, unit_name);
1324 r = sd_bus_call_method(
1326 "org.freedesktop.systemd1",
1327 "/org/freedesktop/systemd1",
1328 "org.freedesktop.systemd1.Manager",
1332 "ss", unit_name, "replace-irreversibly");
1336 r = sd_bus_message_read(reply, "o", &p);
1344 m->action_unit = unit_name;
1345 free(m->action_job);
1352 static int delay_shutdown_or_sleep(
1355 const char *unit_name) {
1359 assert(w < _INHIBIT_WHAT_MAX);
1362 m->action_timestamp = now(CLOCK_MONOTONIC);
1363 m->action_unit = unit_name;
1369 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1371 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1372 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1373 [INHIBIT_SLEEP] = "PrepareForSleep"
1376 int active = _active;
1380 assert(w < _INHIBIT_WHAT_MAX);
1381 assert(signal_name[w]);
1383 return sd_bus_emit_signal(m->bus,
1384 "/org/freedesktop/login1",
1385 "org.freedesktop.login1.Manager",
1391 int bus_manager_shutdown_or_sleep_now_or_later(
1393 const char *unit_name,
1395 sd_bus_error *error) {
1403 assert(w <= _INHIBIT_WHAT_MAX);
1404 assert(!m->action_job);
1406 /* Tell everybody to prepare for shutdown/sleep */
1407 send_prepare_for(m, w, true);
1410 m->inhibit_delay_max > 0 &&
1411 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0);
1414 /* Shutdown is delayed, keep in mind what we
1415 * want to do, and start a timeout */
1416 r = delay_shutdown_or_sleep(m, w, unit_name);
1418 /* Shutdown is not delayed, execute it
1420 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1425 static int method_do_shutdown_or_sleep(
1427 sd_bus_message *message,
1428 const char *unit_name,
1431 const char *action_multiple_sessions,
1432 const char *action_ignore_inhibit,
1433 const char *sleep_verb,
1434 sd_bus_message_handler_t method) {
1436 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1437 bool multiple_sessions, blocked;
1445 assert(w <= _INHIBIT_WHAT_MAX);
1447 assert(action_multiple_sessions);
1448 assert(action_ignore_inhibit);
1451 r = sd_bus_message_read(message, "b", &interactive);
1453 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1455 /* Don't allow multiple jobs being executed at the same time */
1457 return sd_bus_reply_method_errorf(m->bus, message, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1460 r = can_sleep(sleep_verb);
1462 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1465 return sd_bus_reply_method_errorf(m->bus, message, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1468 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1470 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1472 r = have_multiple_sessions(m, uid);
1474 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1476 multiple_sessions = r > 0;
1477 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1479 if (multiple_sessions) {
1480 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1481 action_multiple_sessions, interactive, &error, method, m);
1483 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1487 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1488 action_ignore_inhibit, interactive, &error, method, m);
1490 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1493 if (!multiple_sessions && !blocked) {
1494 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1495 action, interactive, &error, method, m);
1497 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1500 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, &error);
1502 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1504 return sd_bus_reply_method_return(m->bus, message, NULL);
1507 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata) {
1508 Manager *m = userdata;
1510 return method_do_shutdown_or_sleep(
1512 SPECIAL_POWEROFF_TARGET,
1514 "org.freedesktop.login1.power-off",
1515 "org.freedesktop.login1.power-off-multiple-sessions",
1516 "org.freedesktop.login1.power-off-ignore-inhibit",
1521 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata) {
1522 Manager *m = userdata;
1524 return method_do_shutdown_or_sleep(
1526 SPECIAL_REBOOT_TARGET,
1528 "org.freedesktop.login1.reboot",
1529 "org.freedesktop.login1.reboot-multiple-sessions",
1530 "org.freedesktop.login1.reboot-ignore-inhibit",
1535 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata) {
1536 Manager *m = userdata;
1538 return method_do_shutdown_or_sleep(
1540 SPECIAL_SUSPEND_TARGET,
1542 "org.freedesktop.login1.suspend",
1543 "org.freedesktop.login1.suspend-multiple-sessions",
1544 "org.freedesktop.login1.suspend-ignore-inhibit",
1549 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata) {
1550 Manager *m = userdata;
1552 return method_do_shutdown_or_sleep(
1554 SPECIAL_HIBERNATE_TARGET,
1556 "org.freedesktop.login1.hibernate",
1557 "org.freedesktop.login1.hibernate-multiple-sessions",
1558 "org.freedesktop.login1.hibernate-ignore-inhibit",
1563 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata) {
1564 Manager *m = userdata;
1566 return method_do_shutdown_or_sleep(
1568 SPECIAL_HYBRID_SLEEP_TARGET,
1570 "org.freedesktop.login1.hibernate",
1571 "org.freedesktop.login1.hibernate-multiple-sessions",
1572 "org.freedesktop.login1.hibernate-ignore-inhibit",
1574 method_hybrid_sleep);
1577 static int method_can_shutdown_or_sleep(
1579 sd_bus_message *message,
1582 const char *action_multiple_sessions,
1583 const char *action_ignore_inhibit,
1584 const char *sleep_verb) {
1586 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1587 bool multiple_sessions, challenge, blocked;
1588 const char *result = NULL;
1595 assert(w <= _INHIBIT_WHAT_MAX);
1597 assert(action_multiple_sessions);
1598 assert(action_ignore_inhibit);
1601 r = can_sleep(sleep_verb);
1603 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1605 return sd_bus_reply_method_return(m->bus, message, "s", "na");
1608 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1610 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1612 r = have_multiple_sessions(m, uid);
1614 return sd_bus_reply_method_errno(m->bus, message, r, NULL);
1616 multiple_sessions = r > 0;
1617 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1619 if (multiple_sessions) {
1620 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, &error);
1622 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1627 result = "challenge";
1633 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, &error);
1635 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1637 if (r > 0 && !result)
1639 else if (challenge && (!result || streq(result, "yes")))
1640 result = "challenge";
1645 if (!multiple_sessions && !blocked) {
1646 /* If neither inhibit nor multiple sessions
1647 * apply then just check the normal policy */
1649 r = bus_verify_polkit(m->bus, message, action, false, &challenge, &error);
1651 return sd_bus_reply_method_errno(m->bus, message, r, &error);
1656 result = "challenge";
1661 return sd_bus_reply_method_return(m->bus, message, "s", result);
1664 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata) {
1665 Manager *m = userdata;
1667 return method_can_shutdown_or_sleep(
1670 "org.freedesktop.login1.power-off",
1671 "org.freedesktop.login1.power-off-multiple-sessions",
1672 "org.freedesktop.login1.power-off-ignore-inhibit",
1676 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata) {
1677 Manager *m = userdata;
1679 return method_can_shutdown_or_sleep(
1682 "org.freedesktop.login1.reboot",
1683 "org.freedesktop.login1.reboot-multiple-sessions",
1684 "org.freedesktop.login1.reboot-ignore-inhibit",
1688 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata) {
1689 Manager *m = userdata;
1691 return method_can_shutdown_or_sleep(
1694 "org.freedesktop.login1.suspend",
1695 "org.freedesktop.login1.suspend-multiple-sessions",
1696 "org.freedesktop.login1.suspend-ignore-inhibit",
1700 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata) {
1701 Manager *m = userdata;
1703 return method_can_shutdown_or_sleep(
1706 "org.freedesktop.login1.hibernate",
1707 "org.freedesktop.login1.hibernate-multiple-sessions",
1708 "org.freedesktop.login1.hibernate-ignore-inhibit",
1712 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata) {
1713 Manager *m = userdata;
1715 return method_can_shutdown_or_sleep(
1718 "org.freedesktop.login1.hibernate",
1719 "org.freedesktop.login1.hibernate-multiple-sessions",
1720 "org.freedesktop.login1.hibernate-ignore-inhibit",
1724 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata) {
1725 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1726 const char *who, *why, *what, *mode;
1727 _cleanup_free_ char *id = NULL;
1728 _cleanup_close_ int fifo_fd = -1;
1729 Manager *m = userdata;
1730 Inhibitor *i = NULL;
1741 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1743 return sd_bus_reply_method_errno(bus, message, r, NULL);
1745 w = inhibit_what_from_string(what);
1747 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1749 mm = inhibit_mode_from_string(mode);
1751 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1753 /* Delay is only supported for shutdown/sleep */
1754 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1755 return sd_bus_reply_method_errorf(bus, message, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1757 /* Don't allow taking delay locks while we are already
1758 * executing the operation. We shouldn't create the impression
1759 * that the lock was successful if the machine is about to go
1760 * down/suspend any moment. */
1761 if (m->action_what & w)
1762 return sd_bus_reply_method_errorf(bus, message, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1764 r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1765 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1766 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
1767 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
1768 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
1769 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1770 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1771 "org.freedesktop.login1.inhibit-handle-lid-switch",
1772 false, &error, method_inhibit, m);
1774 return sd_bus_reply_method_errno(bus, message, r, &error);
1776 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1778 r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1780 return sd_bus_reply_method_errno(bus, message, r, NULL);
1782 r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
1784 return sd_bus_reply_method_errno(bus, message, r, NULL);
1790 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1791 return sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
1793 } while (hashmap_get(m->inhibitors, id));
1795 r = manager_add_inhibitor(m, id, &i);
1797 return sd_bus_reply_method_errno(bus, message, r, NULL);
1803 i->why = strdup(why);
1804 i->who = strdup(who);
1806 if (!i->why || !i->who) {
1807 r = sd_bus_reply_method_errno(bus, message, -ENOMEM, NULL);
1811 fifo_fd = inhibitor_create_fifo(i);
1813 r = sd_bus_reply_method_errno(bus, message, fifo_fd, NULL);
1819 return sd_bus_reply_method_return(bus, message, "h", fifo_fd);
1828 const sd_bus_vtable manager_vtable[] = {
1829 SD_BUS_VTABLE_START(0),
1831 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1832 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1833 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1834 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1835 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1836 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1837 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1838 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1839 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1840 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1841 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1842 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1843 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1844 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1845 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1846 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1847 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1848 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1850 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1851 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1852 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1853 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1854 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1855 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1856 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1857 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1858 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1859 SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshsub", method_create_session, 0),
1860 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1861 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1862 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1863 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1864 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1865 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1866 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1867 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1868 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1869 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1870 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1871 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1872 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1873 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1874 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1875 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1876 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1877 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1878 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1879 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1880 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1881 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1882 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1883 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1884 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1885 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1887 SD_BUS_SIGNAL("SessionNew", "so", 0),
1888 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1889 SD_BUS_SIGNAL("UserNew", "uo", 0),
1890 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1891 SD_BUS_SIGNAL("SeatNew", "so", 0),
1892 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1893 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1894 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1899 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
1900 const char *path, *result, *unit;
1901 Manager *m = userdata;
1911 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1913 log_error("Failed to parse JobRemoved message: %s", strerror(-r));
1917 if (m->action_job && streq(m->action_job, path)) {
1918 log_info("Operation finished.");
1920 /* Tell people that they now may take a lock again */
1921 send_prepare_for(m, m->action_what, false);
1923 free(m->action_job);
1924 m->action_job = NULL;
1925 m->action_unit = NULL;
1930 session = hashmap_get(m->session_units, unit);
1933 if (streq_ptr(path, session->scope_job)) {
1934 free(session->scope_job);
1935 session->scope_job = NULL;
1938 if (session->started) {
1939 if (streq(result, "done"))
1940 session_send_create_reply(session, NULL);
1942 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1944 sd_bus_error_setf(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1945 session_send_create_reply(session, &error);
1948 session_save(session);
1950 session_add_to_gc_queue(session);
1953 user = hashmap_get(m->user_units, unit);
1956 if (streq_ptr(path, user->service_job)) {
1957 free(user->service_job);
1958 user->service_job = NULL;
1961 if (streq_ptr(path, user->slice_job)) {
1962 free(user->slice_job);
1963 user->slice_job = NULL;
1967 user_add_to_gc_queue(user);
1973 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
1974 const char *path, *unit;
1975 Manager *m = userdata;
1984 r = sd_bus_message_read(message, "so", &unit, &path);
1986 log_error("Failed to parse UnitRemoved message: %s", strerror(-r));
1990 session = hashmap_get(m->session_units, unit);
1992 session_add_to_gc_queue(session);
1994 user = hashmap_get(m->user_units, unit);
1996 user_add_to_gc_queue(user);
2001 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
2002 _cleanup_free_ char *unit = NULL;
2003 Manager *m = userdata;
2012 path = sd_bus_message_get_path(message);
2016 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) {
2032 Manager *m = userdata;
2039 r = sd_bus_message_read(message, "b", &b);
2041 log_error("Failed to parse Reloading message: %s", strerror(-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) {
2058 const char *name, *old, *new;
2059 Manager *m = userdata;
2067 r = sd_bus_message_read(message, "sss", &name, &old, &new);
2069 log_error("Failed to parse NameOwnerChanged message: %s", strerror(-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_send_with_reply_and_block(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 */