]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind-dbus.c
94c8f1f14204bfd540c761f13d246621b7844eac
[thirdparty/systemd.git] / src / login / logind-dbus.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2011 Lennart Poettering
6
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.
11
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.
16
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/>.
19 ***/
20
21 #include <errno.h>
22 #include <pwd.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #include "sd-messages.h"
27
28 #include "alloc-util.h"
29 #include "audit-util.h"
30 #include "bus-common-errors.h"
31 #include "bus-error.h"
32 #include "bus-util.h"
33 #include "dirent-util.h"
34 #include "efivars.h"
35 #include "escape.h"
36 #include "fd-util.h"
37 #include "fileio-label.h"
38 #include "format-util.h"
39 #include "fs-util.h"
40 #include "logind.h"
41 #include "mkdir.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"
47 #include "special.h"
48 #include "strv.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"
54
55 static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) {
56
57 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
58 const char *name;
59 Session *session;
60 int r;
61
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);
66 if (r < 0)
67 return r;
68
69 r = sd_bus_creds_get_session(creds, &name);
70 if (r == -ENXIO)
71 goto err_no_session;
72 if (r < 0)
73 return r;
74
75 session = hashmap_get(m->sessions, name);
76 if (!session)
77 goto err_no_session;
78
79 *ret = session;
80 return 0;
81
82 err_no_session:
83 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
84 "Caller does not belong to any known session");
85 }
86
87 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
88 Session *session;
89
90 assert(m);
91 assert(message);
92 assert(ret);
93
94 if (isempty(name))
95 return get_sender_session(m, message, error, ret);
96
97 session = hashmap_get(m->sessions, name);
98 if (!session)
99 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
100
101 *ret = session;
102 return 0;
103 }
104
105 static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) {
106
107 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
108 uid_t uid;
109 User *user;
110 int r;
111
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);
114 if (r < 0)
115 return r;
116
117 r = sd_bus_creds_get_owner_uid(creds, &uid);
118 if (r == -ENXIO)
119 goto err_no_user;
120 if (r < 0)
121 return r;
122
123 user = hashmap_get(m->users, UID_TO_PTR(uid));
124 if (!user)
125 goto err_no_user;
126
127 *ret = user;
128 return 0;
129
130 err_no_user:
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");
132 }
133
134 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
135 User *user;
136
137 assert(m);
138 assert(message);
139 assert(ret);
140
141 if (!uid_is_valid(uid))
142 return get_sender_user(m, message, error, ret);
143
144 user = hashmap_get(m->users, UID_TO_PTR(uid));
145 if (!user)
146 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "User ID "UID_FMT" is not logged in or lingering", uid);
147
148 *ret = user;
149 return 0;
150 }
151
152 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
153 Seat *seat;
154 int r;
155
156 assert(m);
157 assert(message);
158 assert(ret);
159
160 if (isempty(name)) {
161 Session *session;
162
163 r = manager_get_session_from_creds(m, message, NULL, error, &session);
164 if (r < 0)
165 return r;
166
167 seat = session->seat;
168 if (!seat)
169 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
170 } else {
171 seat = hashmap_get(m->seats, name);
172 if (!seat)
173 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
174 }
175
176 *ret = seat;
177 return 0;
178 }
179
180 static int property_get_idle_hint(
181 sd_bus *bus,
182 const char *path,
183 const char *interface,
184 const char *property,
185 sd_bus_message *reply,
186 void *userdata,
187 sd_bus_error *error) {
188
189 Manager *m = userdata;
190
191 assert(bus);
192 assert(reply);
193 assert(m);
194
195 return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
196 }
197
198 static int property_get_idle_since_hint(
199 sd_bus *bus,
200 const char *path,
201 const char *interface,
202 const char *property,
203 sd_bus_message *reply,
204 void *userdata,
205 sd_bus_error *error) {
206
207 Manager *m = userdata;
208 dual_timestamp t = DUAL_TIMESTAMP_NULL;
209
210 assert(bus);
211 assert(reply);
212 assert(m);
213
214 manager_get_idle_hint(m, &t);
215
216 return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
217 }
218
219 static int property_get_inhibited(
220 sd_bus *bus,
221 const char *path,
222 const char *interface,
223 const char *property,
224 sd_bus_message *reply,
225 void *userdata,
226 sd_bus_error *error) {
227
228 Manager *m = userdata;
229 InhibitWhat w;
230
231 assert(bus);
232 assert(reply);
233 assert(m);
234
235 w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
236
237 return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
238 }
239
240 static int property_get_preparing(
241 sd_bus *bus,
242 const char *path,
243 const char *interface,
244 const char *property,
245 sd_bus_message *reply,
246 void *userdata,
247 sd_bus_error *error) {
248
249 Manager *m = userdata;
250 bool b;
251
252 assert(bus);
253 assert(reply);
254 assert(m);
255
256 if (streq(property, "PreparingForShutdown"))
257 b = !!(m->action_what & INHIBIT_SHUTDOWN);
258 else
259 b = !!(m->action_what & INHIBIT_SLEEP);
260
261 return sd_bus_message_append(reply, "b", b);
262 }
263
264 static int property_get_scheduled_shutdown(
265 sd_bus *bus,
266 const char *path,
267 const char *interface,
268 const char *property,
269 sd_bus_message *reply,
270 void *userdata,
271 sd_bus_error *error) {
272
273 Manager *m = userdata;
274 int r;
275
276 assert(bus);
277 assert(reply);
278 assert(m);
279
280 r = sd_bus_message_open_container(reply, 'r', "st");
281 if (r < 0)
282 return r;
283
284 r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
285 if (r < 0)
286 return r;
287
288 return sd_bus_message_close_container(reply);
289 }
290
291 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
292
293 static int property_get_docked(
294 sd_bus *bus,
295 const char *path,
296 const char *interface,
297 const char *property,
298 sd_bus_message *reply,
299 void *userdata,
300 sd_bus_error *error) {
301
302 Manager *m = userdata;
303
304 assert(bus);
305 assert(reply);
306 assert(m);
307
308 return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
309 }
310
311 static int property_get_current_sessions(
312 sd_bus *bus,
313 const char *path,
314 const char *interface,
315 const char *property,
316 sd_bus_message *reply,
317 void *userdata,
318 sd_bus_error *error) {
319
320 Manager *m = userdata;
321
322 assert(bus);
323 assert(reply);
324 assert(m);
325
326 return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions));
327 }
328
329 static int property_get_current_inhibitors(
330 sd_bus *bus,
331 const char *path,
332 const char *interface,
333 const char *property,
334 sd_bus_message *reply,
335 void *userdata,
336 sd_bus_error *error) {
337
338 Manager *m = userdata;
339
340 assert(bus);
341 assert(reply);
342 assert(m);
343
344 return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors));
345 }
346
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;
350 const char *name;
351 Session *session;
352 int r;
353
354 assert(message);
355 assert(m);
356
357 r = sd_bus_message_read(message, "s", &name);
358 if (r < 0)
359 return r;
360
361 r = manager_get_session_from_creds(m, message, name, error, &session);
362 if (r < 0)
363 return r;
364
365 p = session_bus_path(session);
366 if (!p)
367 return -ENOMEM;
368
369 return sd_bus_reply_method_return(message, "o", p);
370 }
371
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;
379 pid_t pid;
380 int r;
381
382 assert(message);
383 assert(m);
384
385 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
386
387 r = sd_bus_message_read(message, "u", &pid);
388 if (r < 0)
389 return r;
390 if (pid < 0)
391 return -EINVAL;
392
393 if (pid == 0) {
394 r = manager_get_session_from_creds(m, message, NULL, error, &session);
395 if (r < 0)
396 return r;
397 } else {
398 r = manager_get_session_by_pid(m, pid, &session);
399 if (r < 0)
400 return r;
401
402 if (!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);
404 }
405
406 p = session_bus_path(session);
407 if (!p)
408 return -ENOMEM;
409
410 return sd_bus_reply_method_return(message, "o", p);
411 }
412
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;
416 uint32_t uid;
417 User *user;
418 int r;
419
420 assert(message);
421 assert(m);
422
423 r = sd_bus_message_read(message, "u", &uid);
424 if (r < 0)
425 return r;
426
427 r = manager_get_user_from_creds(m, message, uid, error, &user);
428 if (r < 0)
429 return r;
430
431 p = user_bus_path(user);
432 if (!p)
433 return -ENOMEM;
434
435 return sd_bus_reply_method_return(message, "o", p);
436 }
437
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;
441 User *user = NULL;
442 pid_t pid;
443 int r;
444
445 assert(message);
446 assert(m);
447
448 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
449
450 r = sd_bus_message_read(message, "u", &pid);
451 if (r < 0)
452 return r;
453 if (pid < 0)
454 return -EINVAL;
455
456 if (pid == 0) {
457 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
458 if (r < 0)
459 return r;
460 } else {
461 r = manager_get_user_by_pid(m, pid, &user);
462 if (r < 0)
463 return r;
464 if (!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",
467 pid);
468 }
469
470 p = user_bus_path(user);
471 if (!p)
472 return -ENOMEM;
473
474 return sd_bus_reply_method_return(message, "o", p);
475 }
476
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;
480 const char *name;
481 Seat *seat;
482 int r;
483
484 assert(message);
485 assert(m);
486
487 r = sd_bus_message_read(message, "s", &name);
488 if (r < 0)
489 return r;
490
491 r = manager_get_seat_from_creds(m, message, name, error, &seat);
492 if (r < 0)
493 return r;
494
495 p = seat_bus_path(seat);
496 if (!p)
497 return -ENOMEM;
498
499 return sd_bus_reply_method_return(message, "o", p);
500 }
501
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;
505 Session *session;
506 Iterator i;
507 int r;
508
509 assert(message);
510 assert(m);
511
512 r = sd_bus_message_new_method_return(message, &reply);
513 if (r < 0)
514 return r;
515
516 r = sd_bus_message_open_container(reply, 'a', "(susso)");
517 if (r < 0)
518 return r;
519
520 HASHMAP_FOREACH(session, m->sessions, i) {
521 _cleanup_free_ char *p = NULL;
522
523 p = session_bus_path(session);
524 if (!p)
525 return -ENOMEM;
526
527 r = sd_bus_message_append(reply, "(susso)",
528 session->id,
529 (uint32_t) session->user->uid,
530 session->user->name,
531 session->seat ? session->seat->id : "",
532 p);
533 if (r < 0)
534 return r;
535 }
536
537 r = sd_bus_message_close_container(reply);
538 if (r < 0)
539 return r;
540
541 return sd_bus_send(NULL, reply, NULL);
542 }
543
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;
547 User *user;
548 Iterator i;
549 int r;
550
551 assert(message);
552 assert(m);
553
554 r = sd_bus_message_new_method_return(message, &reply);
555 if (r < 0)
556 return r;
557
558 r = sd_bus_message_open_container(reply, 'a', "(uso)");
559 if (r < 0)
560 return r;
561
562 HASHMAP_FOREACH(user, m->users, i) {
563 _cleanup_free_ char *p = NULL;
564
565 p = user_bus_path(user);
566 if (!p)
567 return -ENOMEM;
568
569 r = sd_bus_message_append(reply, "(uso)",
570 (uint32_t) user->uid,
571 user->name,
572 p);
573 if (r < 0)
574 return r;
575 }
576
577 r = sd_bus_message_close_container(reply);
578 if (r < 0)
579 return r;
580
581 return sd_bus_send(NULL, reply, NULL);
582 }
583
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;
587 Seat *seat;
588 Iterator i;
589 int r;
590
591 assert(message);
592 assert(m);
593
594 r = sd_bus_message_new_method_return(message, &reply);
595 if (r < 0)
596 return r;
597
598 r = sd_bus_message_open_container(reply, 'a', "(so)");
599 if (r < 0)
600 return r;
601
602 HASHMAP_FOREACH(seat, m->seats, i) {
603 _cleanup_free_ char *p = NULL;
604
605 p = seat_bus_path(seat);
606 if (!p)
607 return -ENOMEM;
608
609 r = sd_bus_message_append(reply, "(so)", seat->id, p);
610 if (r < 0)
611 return r;
612 }
613
614 r = sd_bus_message_close_container(reply);
615 if (r < 0)
616 return r;
617
618 return sd_bus_send(NULL, reply, NULL);
619 }
620
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;
625 Iterator i;
626 int r;
627
628 assert(message);
629 assert(m);
630
631 r = sd_bus_message_new_method_return(message, &reply);
632 if (r < 0)
633 return r;
634
635 r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
636 if (r < 0)
637 return r;
638
639 HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
640
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);
648 if (r < 0)
649 return r;
650 }
651
652 r = sd_bus_message_close_container(reply);
653 if (r < 0)
654 return r;
655
656 return sd_bus_send(NULL, reply, NULL);
657 }
658
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 _cleanup_free_ char *id = NULL;
662 Session *session = NULL;
663 uint32_t audit_id = 0;
664 Manager *m = userdata;
665 User *user = NULL;
666 Seat *seat = NULL;
667 pid_t leader;
668 uid_t uid;
669 int remote;
670 uint32_t vtnr = 0;
671 SessionType t;
672 SessionClass c;
673 int r;
674
675 assert(message);
676 assert(m);
677
678 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
679 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
680
681 r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
682 if (r < 0)
683 return r;
684
685 if (!uid_is_valid(uid))
686 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID");
687 if (leader < 0 || leader == 1 || leader == getpid_cached())
688 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
689
690 if (isempty(type))
691 t = _SESSION_TYPE_INVALID;
692 else {
693 t = session_type_from_string(type);
694 if (t < 0)
695 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
696 }
697
698 if (isempty(class))
699 c = _SESSION_CLASS_INVALID;
700 else {
701 c = session_class_from_string(class);
702 if (c < 0)
703 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
704 }
705
706 if (isempty(desktop))
707 desktop = NULL;
708 else {
709 if (!string_is_safe(desktop))
710 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
711 }
712
713 if (isempty(cseat))
714 seat = NULL;
715 else {
716 seat = hashmap_get(m->seats, cseat);
717 if (!seat)
718 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
719 }
720
721 if (tty_is_vc(tty)) {
722 int v;
723
724 if (!seat)
725 seat = m->seat0;
726 else if (seat != m->seat0)
727 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);
728
729 v = vtnr_from_tty(tty);
730 if (v <= 0)
731 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
732
733 if (vtnr == 0)
734 vtnr = (uint32_t) v;
735 else if (vtnr != (uint32_t) v)
736 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
737
738 } else if (tty_is_console(tty)) {
739
740 if (!seat)
741 seat = m->seat0;
742 else if (seat != m->seat0)
743 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
744
745 if (vtnr != 0)
746 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
747 }
748
749 if (seat) {
750 if (seat_has_vts(seat)) {
751 if (vtnr <= 0 || vtnr > 63)
752 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
753 } else {
754 if (vtnr != 0)
755 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
756 }
757 }
758
759 r = sd_bus_message_enter_container(message, 'a', "(sv)");
760 if (r < 0)
761 return r;
762
763 if (t == _SESSION_TYPE_INVALID) {
764 if (!isempty(display))
765 t = SESSION_X11;
766 else if (!isempty(tty))
767 t = SESSION_TTY;
768 else
769 t = SESSION_UNSPECIFIED;
770 }
771
772 if (c == _SESSION_CLASS_INVALID) {
773 if (t == SESSION_UNSPECIFIED)
774 c = SESSION_BACKGROUND;
775 else
776 c = SESSION_USER;
777 }
778
779 if (leader == 0) {
780 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
781
782 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
783 if (r < 0)
784 return r;
785
786 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
787 if (r < 0)
788 return r;
789 }
790
791 /* Check if we are already in a logind session. Or if we are in user@.service which is a special PAM session
792 * that avoids creating a logind session. */
793 r = manager_get_user_by_pid(m, leader, NULL);
794 if (r < 0)
795 return r;
796 if (r > 0)
797 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session or user slice");
798
799 /*
800 * Old gdm and lightdm start the user-session on the same VT as
801 * the greeter session. But they destroy the greeter session
802 * after the user-session and want the user-session to take
803 * over the VT. We need to support this for
804 * backwards-compatibility, so make sure we allow new sessions
805 * on a VT that a greeter is running on. Furthermore, to allow
806 * re-logins, we have to allow a greeter to take over a used VT for
807 * the exact same reasons.
808 */
809 if (c != SESSION_GREETER &&
810 vtnr > 0 &&
811 vtnr < m->seat0->position_count &&
812 m->seat0->positions[vtnr] &&
813 m->seat0->positions[vtnr]->class != SESSION_GREETER)
814 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
815
816 if (hashmap_size(m->sessions) >= m->sessions_max)
817 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.", m->sessions_max);
818
819 (void) audit_session_from_pid(leader, &audit_id);
820 if (audit_session_is_valid(audit_id)) {
821 /* Keep our session IDs and the audit session IDs in sync */
822
823 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
824 return -ENOMEM;
825
826 /* Wut? There's already a session by this name and we
827 * didn't find it above? Weird, then let's not trust
828 * the audit data and let's better register a new
829 * ID */
830 if (hashmap_get(m->sessions, id)) {
831 log_warning("Existing logind session ID %s used by new audit session, ignoring.", id);
832 audit_id = AUDIT_SESSION_INVALID;
833 id = mfree(id);
834 }
835 }
836
837 if (!id) {
838 do {
839 id = mfree(id);
840
841 if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
842 return -ENOMEM;
843
844 } while (hashmap_get(m->sessions, id));
845 }
846
847 r = manager_add_user_by_uid(m, uid, &user);
848 if (r < 0)
849 goto fail;
850
851 r = manager_add_session(m, id, &session);
852 if (r < 0)
853 goto fail;
854
855 session_set_user(session, user);
856
857 session->leader = leader;
858 session->audit_id = audit_id;
859 session->type = t;
860 session->class = c;
861 session->remote = remote;
862 session->vtnr = vtnr;
863
864 if (!isempty(tty)) {
865 session->tty = strdup(tty);
866 if (!session->tty) {
867 r = -ENOMEM;
868 goto fail;
869 }
870 }
871
872 if (!isempty(display)) {
873 session->display = strdup(display);
874 if (!session->display) {
875 r = -ENOMEM;
876 goto fail;
877 }
878 }
879
880 if (!isempty(remote_user)) {
881 session->remote_user = strdup(remote_user);
882 if (!session->remote_user) {
883 r = -ENOMEM;
884 goto fail;
885 }
886 }
887
888 if (!isempty(remote_host)) {
889 session->remote_host = strdup(remote_host);
890 if (!session->remote_host) {
891 r = -ENOMEM;
892 goto fail;
893 }
894 }
895
896 if (!isempty(service)) {
897 session->service = strdup(service);
898 if (!session->service) {
899 r = -ENOMEM;
900 goto fail;
901 }
902 }
903
904 if (!isempty(desktop)) {
905 session->desktop = strdup(desktop);
906 if (!session->desktop) {
907 r = -ENOMEM;
908 goto fail;
909 }
910 }
911
912 if (seat) {
913 r = seat_attach_session(seat, session);
914 if (r < 0)
915 goto fail;
916 }
917
918 r = session_start(session);
919 if (r < 0)
920 goto fail;
921
922 session->create_message = sd_bus_message_ref(message);
923
924 /* Now, let's wait until the slice unit and stuff got created. We send the reply back from
925 * session_send_create_reply(). */
926
927 return 1;
928
929 fail:
930 if (session)
931 session_add_to_gc_queue(session);
932
933 if (user)
934 user_add_to_gc_queue(user);
935
936 return r;
937 }
938
939 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
940 Manager *m = userdata;
941 Session *session;
942 const char *name;
943 int r;
944
945 assert(message);
946 assert(m);
947
948 r = sd_bus_message_read(message, "s", &name);
949 if (r < 0)
950 return r;
951
952 r = manager_get_session_from_creds(m, message, name, error, &session);
953 if (r < 0)
954 return r;
955
956 r = session_release(session);
957 if (r < 0)
958 return r;
959
960 return sd_bus_reply_method_return(message, NULL);
961 }
962
963 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
964 Manager *m = userdata;
965 Session *session;
966 const char *name;
967 int r;
968
969 assert(message);
970 assert(m);
971
972 r = sd_bus_message_read(message, "s", &name);
973 if (r < 0)
974 return r;
975
976 r = manager_get_session_from_creds(m, message, name, error, &session);
977 if (r < 0)
978 return r;
979
980 return bus_session_method_activate(message, session, error);
981 }
982
983 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
984 const char *session_name, *seat_name;
985 Manager *m = userdata;
986 Session *session;
987 Seat *seat;
988 int r;
989
990 assert(message);
991 assert(m);
992
993 /* Same as ActivateSession() but refuses to work if
994 * the seat doesn't match */
995
996 r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
997 if (r < 0)
998 return r;
999
1000 r = manager_get_session_from_creds(m, message, session_name, error, &session);
1001 if (r < 0)
1002 return r;
1003
1004 r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
1005 if (r < 0)
1006 return r;
1007
1008 if (session->seat != seat)
1009 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
1010
1011 r = session_activate(session);
1012 if (r < 0)
1013 return r;
1014
1015 return sd_bus_reply_method_return(message, NULL);
1016 }
1017
1018 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1019 Manager *m = userdata;
1020 Session *session;
1021 const char *name;
1022 int r;
1023
1024 assert(message);
1025 assert(m);
1026
1027 r = sd_bus_message_read(message, "s", &name);
1028 if (r < 0)
1029 return r;
1030
1031 r = manager_get_session_from_creds(m, message, name, error, &session);
1032 if (r < 0)
1033 return r;
1034
1035 return bus_session_method_lock(message, session, error);
1036 }
1037
1038 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1039 Manager *m = userdata;
1040 int r;
1041
1042 assert(message);
1043 assert(m);
1044
1045 r = bus_verify_polkit_async(
1046 message,
1047 CAP_SYS_ADMIN,
1048 "org.freedesktop.login1.lock-sessions",
1049 NULL,
1050 false,
1051 UID_INVALID,
1052 &m->polkit_registry,
1053 error);
1054 if (r < 0)
1055 return r;
1056 if (r == 0)
1057 return 1; /* Will call us back */
1058
1059 r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
1060 if (r < 0)
1061 return r;
1062
1063 return sd_bus_reply_method_return(message, NULL);
1064 }
1065
1066 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1067 const char *name;
1068 Manager *m = userdata;
1069 Session *session;
1070 int r;
1071
1072 assert(message);
1073 assert(m);
1074
1075 r = sd_bus_message_read(message, "s", &name);
1076 if (r < 0)
1077 return r;
1078
1079 r = manager_get_session_from_creds(m, message, name, error, &session);
1080 if (r < 0)
1081 return r;
1082
1083 return bus_session_method_kill(message, session, error);
1084 }
1085
1086 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1087 Manager *m = userdata;
1088 uint32_t uid;
1089 User *user;
1090 int r;
1091
1092 assert(message);
1093 assert(m);
1094
1095 r = sd_bus_message_read(message, "u", &uid);
1096 if (r < 0)
1097 return r;
1098
1099 r = manager_get_user_from_creds(m, message, uid, error, &user);
1100 if (r < 0)
1101 return r;
1102
1103 return bus_user_method_kill(message, user, error);
1104 }
1105
1106 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1107 Manager *m = userdata;
1108 const char *name;
1109 Session *session;
1110 int r;
1111
1112 assert(message);
1113 assert(m);
1114
1115 r = sd_bus_message_read(message, "s", &name);
1116 if (r < 0)
1117 return r;
1118
1119 r = manager_get_session_from_creds(m, message, name, error, &session);
1120 if (r < 0)
1121 return r;
1122
1123 return bus_session_method_terminate(message, session, error);
1124 }
1125
1126 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1127 Manager *m = userdata;
1128 uint32_t uid;
1129 User *user;
1130 int r;
1131
1132 assert(message);
1133 assert(m);
1134
1135 r = sd_bus_message_read(message, "u", &uid);
1136 if (r < 0)
1137 return r;
1138
1139 r = manager_get_user_from_creds(m, message, uid, error, &user);
1140 if (r < 0)
1141 return r;
1142
1143 return bus_user_method_terminate(message, user, error);
1144 }
1145
1146 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1147 Manager *m = userdata;
1148 const char *name;
1149 Seat *seat;
1150 int r;
1151
1152 assert(message);
1153 assert(m);
1154
1155 r = sd_bus_message_read(message, "s", &name);
1156 if (r < 0)
1157 return r;
1158
1159 r = manager_get_seat_from_creds(m, message, name, error, &seat);
1160 if (r < 0)
1161 return r;
1162
1163 return bus_seat_method_terminate(message, seat, error);
1164 }
1165
1166 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1167 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1168 _cleanup_free_ char *cc = NULL;
1169 Manager *m = userdata;
1170 int r, b, interactive;
1171 struct passwd *pw;
1172 const char *path;
1173 uint32_t uid, auth_uid;
1174
1175 assert(message);
1176 assert(m);
1177
1178 r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1179 if (r < 0)
1180 return r;
1181
1182 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID |
1183 SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1184 if (r < 0)
1185 return r;
1186
1187 if (!uid_is_valid(uid)) {
1188 /* Note that we get the owner UID of the session or user unit,
1189 * not the actual client UID here! */
1190 r = sd_bus_creds_get_owner_uid(creds, &uid);
1191 if (r < 0)
1192 return r;
1193 }
1194
1195 /* owner_uid is racy, so for authorization we must use euid */
1196 r = sd_bus_creds_get_euid(creds, &auth_uid);
1197 if (r < 0)
1198 return r;
1199
1200 errno = 0;
1201 pw = getpwuid(uid);
1202 if (!pw)
1203 return errno > 0 ? -errno : -ENOENT;
1204
1205 r = bus_verify_polkit_async(
1206 message,
1207 CAP_SYS_ADMIN,
1208 uid == auth_uid ? "org.freedesktop.login1.set-self-linger" :
1209 "org.freedesktop.login1.set-user-linger",
1210 NULL,
1211 interactive,
1212 UID_INVALID,
1213 &m->polkit_registry,
1214 error);
1215 if (r < 0)
1216 return r;
1217 if (r == 0)
1218 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1219
1220 mkdir_p_label("/var/lib/systemd", 0755);
1221
1222 r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, MKDIR_WARN_MODE);
1223 if (r < 0)
1224 return r;
1225
1226 cc = cescape(pw->pw_name);
1227 if (!cc)
1228 return -ENOMEM;
1229
1230 path = strjoina("/var/lib/systemd/linger/", cc);
1231 if (b) {
1232 User *u;
1233
1234 r = touch(path);
1235 if (r < 0)
1236 return r;
1237
1238 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1239 user_start(u);
1240
1241 } else {
1242 User *u;
1243
1244 r = unlink(path);
1245 if (r < 0 && errno != ENOENT)
1246 return -errno;
1247
1248 u = hashmap_get(m->users, UID_TO_PTR(uid));
1249 if (u)
1250 user_add_to_gc_queue(u);
1251 }
1252
1253 return sd_bus_reply_method_return(message, NULL);
1254 }
1255
1256 static int trigger_device(Manager *m, struct udev_device *d) {
1257 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1258 struct udev_list_entry *first, *item;
1259 int r;
1260
1261 assert(m);
1262
1263 e = udev_enumerate_new(m->udev);
1264 if (!e)
1265 return -ENOMEM;
1266
1267 if (d) {
1268 r = udev_enumerate_add_match_parent(e, d);
1269 if (r < 0)
1270 return r;
1271 }
1272
1273 r = udev_enumerate_scan_devices(e);
1274 if (r < 0)
1275 return r;
1276
1277 first = udev_enumerate_get_list_entry(e);
1278 udev_list_entry_foreach(item, first) {
1279 _cleanup_free_ char *t = NULL;
1280 const char *p;
1281
1282 p = udev_list_entry_get_name(item);
1283
1284 t = strappend(p, "/uevent");
1285 if (!t)
1286 return -ENOMEM;
1287
1288 (void) write_string_file(t, "change", 0);
1289 }
1290
1291 return 0;
1292 }
1293
1294 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1295 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1296 _cleanup_free_ char *rule = NULL, *file = NULL;
1297 const char *id_for_seat;
1298 int r;
1299
1300 assert(m);
1301 assert(seat);
1302 assert(sysfs);
1303
1304 d = udev_device_new_from_syspath(m->udev, sysfs);
1305 if (!d)
1306 return -ENODEV;
1307
1308 if (!udev_device_has_tag(d, "seat"))
1309 return -ENODEV;
1310
1311 id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1312 if (!id_for_seat)
1313 return -ENODEV;
1314
1315 if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1316 return -ENOMEM;
1317
1318 if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1319 return -ENOMEM;
1320
1321 mkdir_p_label("/etc/udev/rules.d", 0755);
1322 r = write_string_file_atomic_label(file, rule);
1323 if (r < 0)
1324 return r;
1325
1326 return trigger_device(m, d);
1327 }
1328
1329 static int flush_devices(Manager *m) {
1330 _cleanup_closedir_ DIR *d;
1331
1332 assert(m);
1333
1334 d = opendir("/etc/udev/rules.d");
1335 if (!d) {
1336 if (errno != ENOENT)
1337 log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1338 } else {
1339 struct dirent *de;
1340
1341 FOREACH_DIRENT_ALL(de, d, break) {
1342 if (!dirent_is_file(de))
1343 continue;
1344
1345 if (!startswith(de->d_name, "72-seat-"))
1346 continue;
1347
1348 if (!endswith(de->d_name, ".rules"))
1349 continue;
1350
1351 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1352 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1353 }
1354 }
1355
1356 return trigger_device(m, NULL);
1357 }
1358
1359 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1360 const char *sysfs, *seat;
1361 Manager *m = userdata;
1362 int interactive, r;
1363
1364 assert(message);
1365 assert(m);
1366
1367 r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1368 if (r < 0)
1369 return r;
1370
1371 if (!path_startswith(sysfs, "/sys"))
1372 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1373
1374 if (!seat_name_is_valid(seat))
1375 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1376
1377 r = bus_verify_polkit_async(
1378 message,
1379 CAP_SYS_ADMIN,
1380 "org.freedesktop.login1.attach-device",
1381 NULL,
1382 interactive,
1383 UID_INVALID,
1384 &m->polkit_registry,
1385 error);
1386 if (r < 0)
1387 return r;
1388 if (r == 0)
1389 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1390
1391 r = attach_device(m, seat, sysfs);
1392 if (r < 0)
1393 return r;
1394
1395 return sd_bus_reply_method_return(message, NULL);
1396 }
1397
1398 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1399 Manager *m = userdata;
1400 int interactive, r;
1401
1402 assert(message);
1403 assert(m);
1404
1405 r = sd_bus_message_read(message, "b", &interactive);
1406 if (r < 0)
1407 return r;
1408
1409 r = bus_verify_polkit_async(
1410 message,
1411 CAP_SYS_ADMIN,
1412 "org.freedesktop.login1.flush-devices",
1413 NULL,
1414 interactive,
1415 UID_INVALID,
1416 &m->polkit_registry,
1417 error);
1418 if (r < 0)
1419 return r;
1420 if (r == 0)
1421 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1422
1423 r = flush_devices(m);
1424 if (r < 0)
1425 return r;
1426
1427 return sd_bus_reply_method_return(message, NULL);
1428 }
1429
1430 static int have_multiple_sessions(
1431 Manager *m,
1432 uid_t uid) {
1433
1434 Session *session;
1435 Iterator i;
1436
1437 assert(m);
1438
1439 /* Check for other users' sessions. Greeter sessions do not
1440 * count, and non-login sessions do not count either. */
1441 HASHMAP_FOREACH(session, m->sessions, i)
1442 if (session->class == SESSION_USER &&
1443 session->user->uid != uid)
1444 return true;
1445
1446 return false;
1447 }
1448
1449 static int bus_manager_log_shutdown(
1450 Manager *m,
1451 const char *unit_name) {
1452
1453 const char *p, *q;
1454
1455 assert(m);
1456 assert(unit_name);
1457
1458 if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1459 p = "MESSAGE=System is powering down";
1460 q = "SHUTDOWN=power-off";
1461 } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1462 p = "MESSAGE=System is rebooting";
1463 q = "SHUTDOWN=reboot";
1464 } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1465 p = "MESSAGE=System is halting";
1466 q = "SHUTDOWN=halt";
1467 } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1468 p = "MESSAGE=System is rebooting with kexec";
1469 q = "SHUTDOWN=kexec";
1470 } else {
1471 p = "MESSAGE=System is shutting down";
1472 q = NULL;
1473 }
1474
1475 if (isempty(m->wall_message))
1476 p = strjoina(p, ".");
1477 else
1478 p = strjoina(p, " (", m->wall_message, ").");
1479
1480 return log_struct(LOG_NOTICE,
1481 "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR,
1482 p,
1483 q,
1484 NULL);
1485 }
1486
1487 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1488 Manager *m = userdata;
1489
1490 assert(e);
1491 assert(m);
1492
1493 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1494 return 0;
1495 }
1496
1497 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1498 int r;
1499
1500 assert(m);
1501
1502 if (until <= now(CLOCK_MONOTONIC))
1503 return 0;
1504
1505 /* We want to ignore the lid switch for a while after each
1506 * suspend, and after boot-up. Hence let's install a timer for
1507 * this. As long as the event source exists we ignore the lid
1508 * switch. */
1509
1510 if (m->lid_switch_ignore_event_source) {
1511 usec_t u;
1512
1513 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1514 if (r < 0)
1515 return r;
1516
1517 if (until <= u)
1518 return 0;
1519
1520 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1521 } else
1522 r = sd_event_add_time(
1523 m->event,
1524 &m->lid_switch_ignore_event_source,
1525 CLOCK_MONOTONIC,
1526 until, 0,
1527 lid_switch_ignore_handler, m);
1528
1529 return r;
1530 }
1531
1532 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1533
1534 static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1535 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1536 [INHIBIT_SLEEP] = "PrepareForSleep"
1537 };
1538
1539 int active = _active;
1540
1541 assert(m);
1542 assert(w >= 0);
1543 assert(w < _INHIBIT_WHAT_MAX);
1544 assert(signal_name[w]);
1545
1546 return sd_bus_emit_signal(m->bus,
1547 "/org/freedesktop/login1",
1548 "org.freedesktop.login1.Manager",
1549 signal_name[w],
1550 "b",
1551 active);
1552 }
1553
1554 static int execute_shutdown_or_sleep(
1555 Manager *m,
1556 InhibitWhat w,
1557 const char *unit_name,
1558 sd_bus_error *error) {
1559
1560 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1561 char *c = NULL;
1562 const char *p;
1563 int r;
1564
1565 assert(m);
1566 assert(w > 0);
1567 assert(w < _INHIBIT_WHAT_MAX);
1568 assert(unit_name);
1569
1570 if (w == INHIBIT_SHUTDOWN)
1571 bus_manager_log_shutdown(m, unit_name);
1572
1573 r = sd_bus_call_method(
1574 m->bus,
1575 "org.freedesktop.systemd1",
1576 "/org/freedesktop/systemd1",
1577 "org.freedesktop.systemd1.Manager",
1578 "StartUnit",
1579 error,
1580 &reply,
1581 "ss", unit_name, "replace-irreversibly");
1582 if (r < 0)
1583 goto error;
1584
1585 r = sd_bus_message_read(reply, "o", &p);
1586 if (r < 0)
1587 goto error;
1588
1589 c = strdup(p);
1590 if (!c) {
1591 r = -ENOMEM;
1592 goto error;
1593 }
1594
1595 m->action_unit = unit_name;
1596 free(m->action_job);
1597 m->action_job = c;
1598 m->action_what = w;
1599
1600 /* Make sure the lid switch is ignored for a while */
1601 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1602
1603 return 0;
1604
1605 error:
1606 /* Tell people that they now may take a lock again */
1607 (void) send_prepare_for(m, w, false);
1608
1609 return r;
1610 }
1611
1612 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1613
1614 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1615 Inhibitor *offending = NULL;
1616 int r;
1617
1618 assert(manager);
1619
1620 if (manager->action_what == 0 || manager->action_job)
1621 return 0;
1622
1623 if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1624 _cleanup_free_ char *comm = NULL, *u = NULL;
1625
1626 if (!timeout)
1627 return 0;
1628
1629 (void) get_process_comm(offending->pid, &comm);
1630 u = uid_to_name(offending->uid);
1631
1632 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1633 offending->uid, strna(u),
1634 offending->pid, strna(comm));
1635 }
1636
1637 /* Actually do the operation */
1638 r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1639 if (r < 0) {
1640 log_warning("Error during inhibitor-delayed operation (already returned success to client): %s",
1641 bus_error_message(&error, r));
1642
1643 manager->action_unit = NULL;
1644 manager->action_what = 0;
1645 return r;
1646 }
1647
1648 return 1;
1649 }
1650
1651 static int manager_inhibit_timeout_handler(
1652 sd_event_source *s,
1653 uint64_t usec,
1654 void *userdata) {
1655
1656 Manager *manager = userdata;
1657 int r;
1658
1659 assert(manager);
1660 assert(manager->inhibit_timeout_source == s);
1661
1662 r = manager_dispatch_delayed(manager, true);
1663 return (r < 0) ? r : 0;
1664 }
1665
1666 static int delay_shutdown_or_sleep(
1667 Manager *m,
1668 InhibitWhat w,
1669 const char *unit_name) {
1670
1671 int r;
1672 usec_t timeout_val;
1673
1674 assert(m);
1675 assert(w >= 0);
1676 assert(w < _INHIBIT_WHAT_MAX);
1677 assert(unit_name);
1678
1679 timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1680
1681 if (m->inhibit_timeout_source) {
1682 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1683 if (r < 0)
1684 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1685
1686 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1687 if (r < 0)
1688 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1689 } else {
1690 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1691 timeout_val, 0, manager_inhibit_timeout_handler, m);
1692 if (r < 0)
1693 return r;
1694 }
1695
1696 m->action_unit = unit_name;
1697 m->action_what = w;
1698
1699 return 0;
1700 }
1701
1702 int bus_manager_shutdown_or_sleep_now_or_later(
1703 Manager *m,
1704 const char *unit_name,
1705 InhibitWhat w,
1706 sd_bus_error *error) {
1707
1708 bool delayed;
1709 int r;
1710
1711 assert(m);
1712 assert(unit_name);
1713 assert(w > 0);
1714 assert(w <= _INHIBIT_WHAT_MAX);
1715 assert(!m->action_job);
1716
1717 /* Tell everybody to prepare for shutdown/sleep */
1718 (void) send_prepare_for(m, w, true);
1719
1720 delayed =
1721 m->inhibit_delay_max > 0 &&
1722 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1723
1724 if (delayed)
1725 /* Shutdown is delayed, keep in mind what we
1726 * want to do, and start a timeout */
1727 r = delay_shutdown_or_sleep(m, w, unit_name);
1728 else
1729 /* Shutdown is not delayed, execute it
1730 * immediately */
1731 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1732
1733 return r;
1734 }
1735
1736 static int verify_shutdown_creds(
1737 Manager *m,
1738 sd_bus_message *message,
1739 InhibitWhat w,
1740 bool interactive,
1741 const char *action,
1742 const char *action_multiple_sessions,
1743 const char *action_ignore_inhibit,
1744 sd_bus_error *error) {
1745
1746 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1747 bool multiple_sessions, blocked;
1748 uid_t uid;
1749 int r;
1750
1751 assert(m);
1752 assert(message);
1753 assert(w >= 0);
1754 assert(w <= _INHIBIT_WHAT_MAX);
1755
1756 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1757 if (r < 0)
1758 return r;
1759
1760 r = sd_bus_creds_get_euid(creds, &uid);
1761 if (r < 0)
1762 return r;
1763
1764 r = have_multiple_sessions(m, uid);
1765 if (r < 0)
1766 return r;
1767
1768 multiple_sessions = r > 0;
1769 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1770
1771 if (multiple_sessions && action_multiple_sessions) {
1772 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1773 if (r < 0)
1774 return r;
1775 if (r == 0)
1776 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1777 }
1778
1779 if (blocked && action_ignore_inhibit) {
1780 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1781 if (r < 0)
1782 return r;
1783 if (r == 0)
1784 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1785 }
1786
1787 if (!multiple_sessions && !blocked && action) {
1788 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1789 if (r < 0)
1790 return r;
1791 if (r == 0)
1792 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1793 }
1794
1795 return 0;
1796 }
1797
1798 static int method_do_shutdown_or_sleep(
1799 Manager *m,
1800 sd_bus_message *message,
1801 const char *unit_name,
1802 InhibitWhat w,
1803 const char *action,
1804 const char *action_multiple_sessions,
1805 const char *action_ignore_inhibit,
1806 const char *sleep_verb,
1807 sd_bus_error *error) {
1808
1809 int interactive, r;
1810
1811 assert(m);
1812 assert(message);
1813 assert(unit_name);
1814 assert(w >= 0);
1815 assert(w <= _INHIBIT_WHAT_MAX);
1816
1817 r = sd_bus_message_read(message, "b", &interactive);
1818 if (r < 0)
1819 return r;
1820
1821 /* Don't allow multiple jobs being executed at the same time */
1822 if (m->action_what)
1823 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1824
1825 if (sleep_verb) {
1826 r = can_sleep(sleep_verb);
1827 if (r < 0)
1828 return r;
1829
1830 if (r == 0)
1831 return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1832 }
1833
1834 r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1835 action_ignore_inhibit, error);
1836 if (r != 0)
1837 return r;
1838
1839 r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1840 if (r < 0)
1841 return r;
1842
1843 return sd_bus_reply_method_return(message, NULL);
1844 }
1845
1846 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1847 Manager *m = userdata;
1848
1849 return method_do_shutdown_or_sleep(
1850 m, message,
1851 SPECIAL_POWEROFF_TARGET,
1852 INHIBIT_SHUTDOWN,
1853 "org.freedesktop.login1.power-off",
1854 "org.freedesktop.login1.power-off-multiple-sessions",
1855 "org.freedesktop.login1.power-off-ignore-inhibit",
1856 NULL,
1857 error);
1858 }
1859
1860 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1861 Manager *m = userdata;
1862
1863 return method_do_shutdown_or_sleep(
1864 m, message,
1865 SPECIAL_REBOOT_TARGET,
1866 INHIBIT_SHUTDOWN,
1867 "org.freedesktop.login1.reboot",
1868 "org.freedesktop.login1.reboot-multiple-sessions",
1869 "org.freedesktop.login1.reboot-ignore-inhibit",
1870 NULL,
1871 error);
1872 }
1873
1874 static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1875 Manager *m = userdata;
1876
1877 return method_do_shutdown_or_sleep(
1878 m, message,
1879 SPECIAL_HALT_TARGET,
1880 INHIBIT_SHUTDOWN,
1881 "org.freedesktop.login1.halt",
1882 "org.freedesktop.login1.halt-multiple-sessions",
1883 "org.freedesktop.login1.halt-ignore-inhibit",
1884 NULL,
1885 error);
1886 }
1887
1888 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1889 Manager *m = userdata;
1890
1891 return method_do_shutdown_or_sleep(
1892 m, message,
1893 SPECIAL_SUSPEND_TARGET,
1894 INHIBIT_SLEEP,
1895 "org.freedesktop.login1.suspend",
1896 "org.freedesktop.login1.suspend-multiple-sessions",
1897 "org.freedesktop.login1.suspend-ignore-inhibit",
1898 "suspend",
1899 error);
1900 }
1901
1902 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1903 Manager *m = userdata;
1904
1905 return method_do_shutdown_or_sleep(
1906 m, message,
1907 SPECIAL_HIBERNATE_TARGET,
1908 INHIBIT_SLEEP,
1909 "org.freedesktop.login1.hibernate",
1910 "org.freedesktop.login1.hibernate-multiple-sessions",
1911 "org.freedesktop.login1.hibernate-ignore-inhibit",
1912 "hibernate",
1913 error);
1914 }
1915
1916 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1917 Manager *m = userdata;
1918
1919 return method_do_shutdown_or_sleep(
1920 m, message,
1921 SPECIAL_HYBRID_SLEEP_TARGET,
1922 INHIBIT_SLEEP,
1923 "org.freedesktop.login1.hibernate",
1924 "org.freedesktop.login1.hibernate-multiple-sessions",
1925 "org.freedesktop.login1.hibernate-ignore-inhibit",
1926 "hybrid-sleep",
1927 error);
1928 }
1929
1930 static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1931 Manager *m = userdata;
1932
1933 return method_do_shutdown_or_sleep(
1934 m, message,
1935 SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET,
1936 INHIBIT_SLEEP,
1937 "org.freedesktop.login1.hibernate",
1938 "org.freedesktop.login1.hibernate-multiple-sessions",
1939 "org.freedesktop.login1.hibernate-ignore-inhibit",
1940 "hybrid-sleep",
1941 error);
1942 }
1943
1944 static int nologin_timeout_handler(
1945 sd_event_source *s,
1946 uint64_t usec,
1947 void *userdata) {
1948
1949 Manager *m = userdata;
1950
1951 log_info("Creating /run/nologin, blocking further logins...");
1952
1953 m->unlink_nologin =
1954 create_shutdown_run_nologin_or_warn() >= 0;
1955
1956 return 0;
1957 }
1958
1959 static int update_schedule_file(Manager *m) {
1960 _cleanup_free_ char *temp_path = NULL;
1961 _cleanup_fclose_ FILE *f = NULL;
1962 int r;
1963
1964 assert(m);
1965
1966 r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, MKDIR_WARN_MODE);
1967 if (r < 0)
1968 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1969
1970 r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1971 if (r < 0)
1972 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1973
1974 (void) fchmod(fileno(f), 0644);
1975
1976 fprintf(f,
1977 "USEC="USEC_FMT"\n"
1978 "WARN_WALL=%i\n"
1979 "MODE=%s\n",
1980 m->scheduled_shutdown_timeout,
1981 m->enable_wall_messages,
1982 m->scheduled_shutdown_type);
1983
1984 if (!isempty(m->wall_message)) {
1985 _cleanup_free_ char *t;
1986
1987 t = cescape(m->wall_message);
1988 if (!t) {
1989 r = -ENOMEM;
1990 goto fail;
1991 }
1992
1993 fprintf(f, "WALL_MESSAGE=%s\n", t);
1994 }
1995
1996 r = fflush_and_check(f);
1997 if (r < 0)
1998 goto fail;
1999
2000 if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
2001 r = -errno;
2002 goto fail;
2003 }
2004
2005 return 0;
2006
2007 fail:
2008 (void) unlink(temp_path);
2009 (void) unlink("/run/systemd/shutdown/scheduled");
2010
2011 return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
2012 }
2013
2014 static void reset_scheduled_shutdown(Manager *m) {
2015 assert(m);
2016
2017 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2018 m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
2019 m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
2020
2021 m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
2022 m->scheduled_shutdown_timeout = 0;
2023 m->shutdown_dry_run = false;
2024
2025 if (m->unlink_nologin) {
2026 (void) unlink_or_warn("/run/nologin");
2027 m->unlink_nologin = false;
2028 }
2029
2030 (void) unlink("/run/systemd/shutdown/scheduled");
2031 }
2032
2033 static int manager_scheduled_shutdown_handler(
2034 sd_event_source *s,
2035 uint64_t usec,
2036 void *userdata) {
2037
2038 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2039 Manager *m = userdata;
2040 const char *target;
2041 int r;
2042
2043 assert(m);
2044
2045 if (isempty(m->scheduled_shutdown_type))
2046 return 0;
2047
2048 if (streq(m->scheduled_shutdown_type, "poweroff"))
2049 target = SPECIAL_POWEROFF_TARGET;
2050 else if (streq(m->scheduled_shutdown_type, "reboot"))
2051 target = SPECIAL_REBOOT_TARGET;
2052 else if (streq(m->scheduled_shutdown_type, "halt"))
2053 target = SPECIAL_HALT_TARGET;
2054 else
2055 assert_not_reached("unexpected shutdown type");
2056
2057 /* Don't allow multiple jobs being executed at the same time */
2058 if (m->action_what) {
2059 r = -EALREADY;
2060 log_error("Scheduled shutdown to %s failed: shutdown or sleep operation already in progress", target);
2061 goto error;
2062 }
2063
2064 if (m->shutdown_dry_run) {
2065 /* We do not process delay inhibitors here. Otherwise, we
2066 * would have to be considered "in progress" (like the check
2067 * above) for some seconds after our admin has seen the final
2068 * wall message. */
2069
2070 bus_manager_log_shutdown(m, target);
2071 log_info("Running in dry run, suppressing action.");
2072 reset_scheduled_shutdown(m);
2073
2074 return 0;
2075 }
2076
2077 r = bus_manager_shutdown_or_sleep_now_or_later(m, target, INHIBIT_SHUTDOWN, &error);
2078 if (r < 0) {
2079 log_error_errno(r, "Scheduled shutdown to %s failed: %m", target);
2080 goto error;
2081 }
2082
2083 return 0;
2084
2085 error:
2086 reset_scheduled_shutdown(m);
2087 return r;
2088 }
2089
2090 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2091 Manager *m = userdata;
2092 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2093 const char *action_multiple_sessions = NULL;
2094 const char *action_ignore_inhibit = NULL;
2095 const char *action = NULL;
2096 uint64_t elapse;
2097 char *type;
2098 int r;
2099 bool dry_run = false;
2100
2101 assert(m);
2102 assert(message);
2103
2104 r = sd_bus_message_read(message, "st", &type, &elapse);
2105 if (r < 0)
2106 return r;
2107
2108 if (startswith(type, "dry-")) {
2109 type += 4;
2110 dry_run = true;
2111 }
2112
2113 if (streq(type, "poweroff")) {
2114 action = "org.freedesktop.login1.power-off";
2115 action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions";
2116 action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit";
2117 } else if (streq(type, "reboot")) {
2118 action = "org.freedesktop.login1.reboot";
2119 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
2120 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
2121 } else if (streq(type, "halt")) {
2122 action = "org.freedesktop.login1.halt";
2123 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
2124 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
2125 } else
2126 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
2127
2128 r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
2129 action, action_multiple_sessions, action_ignore_inhibit, error);
2130 if (r != 0)
2131 return r;
2132
2133 if (m->scheduled_shutdown_timeout_source) {
2134 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
2135 if (r < 0)
2136 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
2137
2138 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
2139 if (r < 0)
2140 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
2141 } else {
2142 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
2143 CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
2144 if (r < 0)
2145 return log_error_errno(r, "sd_event_add_time() failed: %m");
2146 }
2147
2148 r = free_and_strdup(&m->scheduled_shutdown_type, type);
2149 if (r < 0) {
2150 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2151 return log_oom();
2152 }
2153
2154 m->shutdown_dry_run = dry_run;
2155
2156 if (m->nologin_timeout_source) {
2157 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
2158 if (r < 0)
2159 return log_error_errno(r, "sd_event_source_set_time() failed: %m");
2160
2161 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
2162 if (r < 0)
2163 return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
2164 } else {
2165 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
2166 CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
2167 if (r < 0)
2168 return log_error_errno(r, "sd_event_add_time() failed: %m");
2169 }
2170
2171 m->scheduled_shutdown_timeout = elapse;
2172
2173 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2174 if (r >= 0) {
2175 const char *tty = NULL;
2176
2177 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
2178 (void) sd_bus_creds_get_tty(creds, &tty);
2179
2180 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
2181 if (r < 0) {
2182 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2183 return log_oom();
2184 }
2185 }
2186
2187 r = manager_setup_wall_message_timer(m);
2188 if (r < 0)
2189 return r;
2190
2191 r = update_schedule_file(m);
2192 if (r < 0)
2193 return r;
2194
2195 return sd_bus_reply_method_return(message, NULL);
2196 }
2197
2198 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2199 Manager *m = userdata;
2200 bool cancelled;
2201
2202 assert(m);
2203 assert(message);
2204
2205 cancelled = m->scheduled_shutdown_type != NULL;
2206 reset_scheduled_shutdown(m);
2207
2208 if (cancelled) {
2209 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2210 const char *tty = NULL;
2211 uid_t uid = 0;
2212 int r;
2213
2214 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2215 if (r >= 0) {
2216 (void) sd_bus_creds_get_uid(creds, &uid);
2217 (void) sd_bus_creds_get_tty(creds, &tty);
2218 }
2219
2220 utmp_wall("The system shutdown has been cancelled",
2221 uid_to_name(uid), tty, logind_wall_tty_filter, m);
2222 }
2223
2224 return sd_bus_reply_method_return(message, "b", cancelled);
2225 }
2226
2227 static int method_can_shutdown_or_sleep(
2228 Manager *m,
2229 sd_bus_message *message,
2230 InhibitWhat w,
2231 const char *action,
2232 const char *action_multiple_sessions,
2233 const char *action_ignore_inhibit,
2234 const char *sleep_verb,
2235 sd_bus_error *error) {
2236
2237 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2238 bool multiple_sessions, challenge, blocked;
2239 const char *result = NULL;
2240 uid_t uid;
2241 int r;
2242
2243 assert(m);
2244 assert(message);
2245 assert(w >= 0);
2246 assert(w <= _INHIBIT_WHAT_MAX);
2247 assert(action);
2248 assert(action_multiple_sessions);
2249 assert(action_ignore_inhibit);
2250
2251 if (sleep_verb) {
2252 r = can_sleep(sleep_verb);
2253 if (r < 0)
2254 return r;
2255 if (r == 0)
2256 return sd_bus_reply_method_return(message, "s", "na");
2257 }
2258
2259 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2260 if (r < 0)
2261 return r;
2262
2263 r = sd_bus_creds_get_euid(creds, &uid);
2264 if (r < 0)
2265 return r;
2266
2267 r = have_multiple_sessions(m, uid);
2268 if (r < 0)
2269 return r;
2270
2271 multiple_sessions = r > 0;
2272 blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2273
2274 if (multiple_sessions) {
2275 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2276 if (r < 0)
2277 return r;
2278
2279 if (r > 0)
2280 result = "yes";
2281 else if (challenge)
2282 result = "challenge";
2283 else
2284 result = "no";
2285 }
2286
2287 if (blocked) {
2288 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2289 if (r < 0)
2290 return r;
2291
2292 if (r > 0 && !result)
2293 result = "yes";
2294 else if (challenge && (!result || streq(result, "yes")))
2295 result = "challenge";
2296 else
2297 result = "no";
2298 }
2299
2300 if (!multiple_sessions && !blocked) {
2301 /* If neither inhibit nor multiple sessions
2302 * apply then just check the normal policy */
2303
2304 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2305 if (r < 0)
2306 return r;
2307
2308 if (r > 0)
2309 result = "yes";
2310 else if (challenge)
2311 result = "challenge";
2312 else
2313 result = "no";
2314 }
2315
2316 return sd_bus_reply_method_return(message, "s", result);
2317 }
2318
2319 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2320 Manager *m = userdata;
2321
2322 return method_can_shutdown_or_sleep(
2323 m, message,
2324 INHIBIT_SHUTDOWN,
2325 "org.freedesktop.login1.power-off",
2326 "org.freedesktop.login1.power-off-multiple-sessions",
2327 "org.freedesktop.login1.power-off-ignore-inhibit",
2328 NULL,
2329 error);
2330 }
2331
2332 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2333 Manager *m = userdata;
2334
2335 return method_can_shutdown_or_sleep(
2336 m, message,
2337 INHIBIT_SHUTDOWN,
2338 "org.freedesktop.login1.reboot",
2339 "org.freedesktop.login1.reboot-multiple-sessions",
2340 "org.freedesktop.login1.reboot-ignore-inhibit",
2341 NULL,
2342 error);
2343 }
2344
2345 static int method_can_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2346 Manager *m = userdata;
2347
2348 return method_can_shutdown_or_sleep(
2349 m, message,
2350 INHIBIT_SHUTDOWN,
2351 "org.freedesktop.login1.halt",
2352 "org.freedesktop.login1.halt-multiple-sessions",
2353 "org.freedesktop.login1.halt-ignore-inhibit",
2354 NULL,
2355 error);
2356 }
2357
2358 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2359 Manager *m = userdata;
2360
2361 return method_can_shutdown_or_sleep(
2362 m, message,
2363 INHIBIT_SLEEP,
2364 "org.freedesktop.login1.suspend",
2365 "org.freedesktop.login1.suspend-multiple-sessions",
2366 "org.freedesktop.login1.suspend-ignore-inhibit",
2367 "suspend",
2368 error);
2369 }
2370
2371 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2372 Manager *m = userdata;
2373
2374 return method_can_shutdown_or_sleep(
2375 m, message,
2376 INHIBIT_SLEEP,
2377 "org.freedesktop.login1.hibernate",
2378 "org.freedesktop.login1.hibernate-multiple-sessions",
2379 "org.freedesktop.login1.hibernate-ignore-inhibit",
2380 "hibernate",
2381 error);
2382 }
2383
2384 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2385 Manager *m = userdata;
2386
2387 return method_can_shutdown_or_sleep(
2388 m, message,
2389 INHIBIT_SLEEP,
2390 "org.freedesktop.login1.hibernate",
2391 "org.freedesktop.login1.hibernate-multiple-sessions",
2392 "org.freedesktop.login1.hibernate-ignore-inhibit",
2393 "hybrid-sleep",
2394 error);
2395 }
2396
2397 static int method_can_suspend_then_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2398 Manager *m = userdata;
2399
2400 return method_can_shutdown_or_sleep(
2401 m, message,
2402 INHIBIT_SLEEP,
2403 "org.freedesktop.login1.hibernate",
2404 "org.freedesktop.login1.hibernate-multiple-sessions",
2405 "org.freedesktop.login1.hibernate-ignore-inhibit",
2406 "suspend-then-hibernate",
2407 error);
2408 }
2409
2410 static int property_get_reboot_to_firmware_setup(
2411 sd_bus *bus,
2412 const char *path,
2413 const char *interface,
2414 const char *property,
2415 sd_bus_message *reply,
2416 void *userdata,
2417 sd_bus_error *error) {
2418 int r;
2419
2420 assert(bus);
2421 assert(reply);
2422 assert(userdata);
2423
2424 r = efi_get_reboot_to_firmware();
2425 if (r < 0 && r != -EOPNOTSUPP)
2426 log_warning_errno(r, "Failed to determine reboot-to-firmware state: %m");
2427
2428 return sd_bus_message_append(reply, "b", r > 0);
2429 }
2430
2431 static int method_set_reboot_to_firmware_setup(
2432 sd_bus_message *message,
2433 void *userdata,
2434 sd_bus_error *error) {
2435
2436 int b, r;
2437 Manager *m = userdata;
2438
2439 assert(message);
2440 assert(m);
2441
2442 r = sd_bus_message_read(message, "b", &b);
2443 if (r < 0)
2444 return r;
2445
2446 r = bus_verify_polkit_async(message,
2447 CAP_SYS_ADMIN,
2448 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2449 NULL,
2450 false,
2451 UID_INVALID,
2452 &m->polkit_registry,
2453 error);
2454 if (r < 0)
2455 return r;
2456 if (r == 0)
2457 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2458
2459 r = efi_set_reboot_to_firmware(b);
2460 if (r < 0)
2461 return r;
2462
2463 return sd_bus_reply_method_return(message, NULL);
2464 }
2465
2466 static int method_can_reboot_to_firmware_setup(
2467 sd_bus_message *message,
2468 void *userdata,
2469 sd_bus_error *error) {
2470
2471 int r;
2472 bool challenge;
2473 const char *result;
2474 Manager *m = userdata;
2475
2476 assert(message);
2477 assert(m);
2478
2479 r = efi_reboot_to_firmware_supported();
2480 if (r < 0) {
2481 if (r != -EOPNOTSUPP)
2482 log_warning_errno(errno, "Failed to determine whether reboot to firmware is supported: %m");
2483
2484 return sd_bus_reply_method_return(message, "s", "na");
2485 }
2486
2487 r = bus_test_polkit(message,
2488 CAP_SYS_ADMIN,
2489 "org.freedesktop.login1.set-reboot-to-firmware-setup",
2490 NULL,
2491 UID_INVALID,
2492 &challenge,
2493 error);
2494 if (r < 0)
2495 return r;
2496
2497 if (r > 0)
2498 result = "yes";
2499 else if (challenge)
2500 result = "challenge";
2501 else
2502 result = "no";
2503
2504 return sd_bus_reply_method_return(message, "s", result);
2505 }
2506
2507 static int method_set_wall_message(
2508 sd_bus_message *message,
2509 void *userdata,
2510 sd_bus_error *error) {
2511
2512 int r;
2513 Manager *m = userdata;
2514 char *wall_message;
2515 int enable_wall_messages;
2516
2517 assert(message);
2518 assert(m);
2519
2520 r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2521 if (r < 0)
2522 return r;
2523
2524 r = bus_verify_polkit_async(message,
2525 CAP_SYS_ADMIN,
2526 "org.freedesktop.login1.set-wall-message",
2527 NULL,
2528 false,
2529 UID_INVALID,
2530 &m->polkit_registry,
2531 error);
2532 if (r < 0)
2533 return r;
2534 if (r == 0)
2535 return 1; /* Will call us back */
2536
2537 r = free_and_strdup(&m->wall_message, empty_to_null(wall_message));
2538 if (r < 0)
2539 return log_oom();
2540
2541 m->enable_wall_messages = enable_wall_messages;
2542
2543 return sd_bus_reply_method_return(message, NULL);
2544 }
2545
2546 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2547 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2548 const char *who, *why, *what, *mode;
2549 _cleanup_free_ char *id = NULL;
2550 _cleanup_close_ int fifo_fd = -1;
2551 Manager *m = userdata;
2552 Inhibitor *i = NULL;
2553 InhibitMode mm;
2554 InhibitWhat w;
2555 pid_t pid;
2556 uid_t uid;
2557 int r;
2558
2559 assert(message);
2560 assert(m);
2561
2562 r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2563 if (r < 0)
2564 return r;
2565
2566 w = inhibit_what_from_string(what);
2567 if (w <= 0)
2568 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2569
2570 mm = inhibit_mode_from_string(mode);
2571 if (mm < 0)
2572 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2573
2574 /* Delay is only supported for shutdown/sleep */
2575 if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2576 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2577
2578 /* Don't allow taking delay locks while we are already
2579 * executing the operation. We shouldn't create the impression
2580 * that the lock was successful if the machine is about to go
2581 * down/suspend any moment. */
2582 if (m->action_what & w)
2583 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2584
2585 r = bus_verify_polkit_async(
2586 message,
2587 CAP_SYS_BOOT,
2588 w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2589 w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
2590 w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
2591 w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
2592 w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2593 w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2594 "org.freedesktop.login1.inhibit-handle-lid-switch",
2595 NULL,
2596 false,
2597 UID_INVALID,
2598 &m->polkit_registry,
2599 error);
2600 if (r < 0)
2601 return r;
2602 if (r == 0)
2603 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2604
2605 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2606 if (r < 0)
2607 return r;
2608
2609 r = sd_bus_creds_get_euid(creds, &uid);
2610 if (r < 0)
2611 return r;
2612
2613 r = sd_bus_creds_get_pid(creds, &pid);
2614 if (r < 0)
2615 return r;
2616
2617 if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
2618 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.", m->inhibitors_max);
2619
2620 do {
2621 id = mfree(id);
2622
2623 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2624 return -ENOMEM;
2625
2626 } while (hashmap_get(m->inhibitors, id));
2627
2628 r = manager_add_inhibitor(m, id, &i);
2629 if (r < 0)
2630 return r;
2631
2632 i->what = w;
2633 i->mode = mm;
2634 i->pid = pid;
2635 i->uid = uid;
2636 i->why = strdup(why);
2637 i->who = strdup(who);
2638
2639 if (!i->why || !i->who) {
2640 r = -ENOMEM;
2641 goto fail;
2642 }
2643
2644 fifo_fd = inhibitor_create_fifo(i);
2645 if (fifo_fd < 0) {
2646 r = fifo_fd;
2647 goto fail;
2648 }
2649
2650 inhibitor_start(i);
2651
2652 return sd_bus_reply_method_return(message, "h", fifo_fd);
2653
2654 fail:
2655 if (i)
2656 inhibitor_free(i);
2657
2658 return r;
2659 }
2660
2661 const sd_bus_vtable manager_vtable[] = {
2662 SD_BUS_VTABLE_START(0),
2663
2664 SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2665 SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2666
2667 SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2668 SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2669 SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2670 SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2671 SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2672 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2673 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2674 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2675 SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2676 SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2677 SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2678 SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2679 SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2680 SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2681 SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2682 SD_BUS_PROPERTY("HandleLidSwitchExternalPower", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_ep), SD_BUS_VTABLE_PROPERTY_CONST),
2683 SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2684 SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2685 SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2686 SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2687 SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2688 SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2689 SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2690 SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2691 SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
2692 SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
2693 SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
2694 SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0),
2695 SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
2696 SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0),
2697 SD_BUS_PROPERTY("UserTasksMax", "t", NULL, offsetof(Manager, user_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
2698
2699 SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2700 SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2701 SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2702 SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2703 SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2704 SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2705 SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2706 SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2707 SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2708 SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2709 SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2710 SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2711 SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2712 SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2713 SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2714 SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2715 SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2716 SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2717 SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2718 SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2719 SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2720 SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2721 SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2722 SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2723 SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2724 SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2725 SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2726 SD_BUS_METHOD("Halt", "b", NULL, method_halt, SD_BUS_VTABLE_UNPRIVILEGED),
2727 SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2728 SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2729 SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2730 SD_BUS_METHOD("SuspendThenHibernate", "b", NULL, method_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2731 SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2732 SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2733 SD_BUS_METHOD("CanHalt", NULL, "s", method_can_halt, SD_BUS_VTABLE_UNPRIVILEGED),
2734 SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2735 SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2736 SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2737 SD_BUS_METHOD("CanSuspendThenHibernate", NULL, "s", method_can_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2738 SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2739 SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2740 SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2741 SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2742 SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2743 SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2744
2745 SD_BUS_SIGNAL("SessionNew", "so", 0),
2746 SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2747 SD_BUS_SIGNAL("UserNew", "uo", 0),
2748 SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2749 SD_BUS_SIGNAL("SeatNew", "so", 0),
2750 SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2751 SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2752 SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2753
2754 SD_BUS_VTABLE_END
2755 };
2756
2757 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2758 int r = 0;
2759
2760 assert(s);
2761 assert(unit);
2762
2763 if (!s->started)
2764 return r;
2765
2766 if (streq(result, "done"))
2767 r = session_send_create_reply(s, NULL);
2768 else {
2769 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
2770
2771 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2772 r = session_send_create_reply(s, &e);
2773 }
2774
2775 return r;
2776 }
2777
2778 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2779 const char *path, *result, *unit;
2780 Manager *m = userdata;
2781 Session *session;
2782 uint32_t id;
2783 User *user;
2784 int r;
2785
2786 assert(message);
2787 assert(m);
2788
2789 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2790 if (r < 0) {
2791 bus_log_parse_error(r);
2792 return 0;
2793 }
2794
2795 if (m->action_job && streq(m->action_job, path)) {
2796 log_info("Operation '%s' finished.", inhibit_what_to_string(m->action_what));
2797
2798 /* Tell people that they now may take a lock again */
2799 (void) send_prepare_for(m, m->action_what, false);
2800
2801 m->action_job = mfree(m->action_job);
2802 m->action_unit = NULL;
2803 m->action_what = 0;
2804 return 0;
2805 }
2806
2807 session = hashmap_get(m->session_units, unit);
2808 if (session && streq_ptr(path, session->scope_job)) {
2809 session->scope_job = mfree(session->scope_job);
2810 session_jobs_reply(session, unit, result);
2811
2812 session_save(session);
2813 user_save(session->user);
2814 session_add_to_gc_queue(session);
2815 }
2816
2817 user = hashmap_get(m->user_units, unit);
2818 if (user &&
2819 (streq_ptr(path, user->service_job) ||
2820 streq_ptr(path, user->slice_job))) {
2821
2822 if (streq_ptr(path, user->service_job))
2823 user->service_job = mfree(user->service_job);
2824
2825 if (streq_ptr(path, user->slice_job))
2826 user->slice_job = mfree(user->slice_job);
2827
2828 LIST_FOREACH(sessions_by_user, session, user->sessions)
2829 session_jobs_reply(session, unit, result);
2830
2831 user_save(user);
2832 user_add_to_gc_queue(user);
2833 }
2834
2835 return 0;
2836 }
2837
2838 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2839 const char *path, *unit;
2840 Manager *m = userdata;
2841 Session *session;
2842 User *user;
2843 int r;
2844
2845 assert(message);
2846 assert(m);
2847
2848 r = sd_bus_message_read(message, "so", &unit, &path);
2849 if (r < 0) {
2850 bus_log_parse_error(r);
2851 return 0;
2852 }
2853
2854 session = hashmap_get(m->session_units, unit);
2855 if (session)
2856 session_add_to_gc_queue(session);
2857
2858 user = hashmap_get(m->user_units, unit);
2859 if (user)
2860 user_add_to_gc_queue(user);
2861
2862 return 0;
2863 }
2864
2865 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2866 _cleanup_free_ char *unit = NULL;
2867 Manager *m = userdata;
2868 const char *path;
2869 Session *session;
2870 User *user;
2871 int r;
2872
2873 assert(message);
2874 assert(m);
2875
2876 path = sd_bus_message_get_path(message);
2877 if (!path)
2878 return 0;
2879
2880 r = unit_name_from_dbus_path(path, &unit);
2881 if (r == -EINVAL) /* not a unit */
2882 return 0;
2883 if (r < 0) {
2884 log_oom();
2885 return 0;
2886 }
2887
2888 session = hashmap_get(m->session_units, unit);
2889 if (session)
2890 session_add_to_gc_queue(session);
2891
2892 user = hashmap_get(m->user_units, unit);
2893 if (user)
2894 user_add_to_gc_queue(user);
2895
2896 return 0;
2897 }
2898
2899 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2900 Manager *m = userdata;
2901 Session *session;
2902 Iterator i;
2903 int b, r;
2904
2905 assert(message);
2906 assert(m);
2907
2908 r = sd_bus_message_read(message, "b", &b);
2909 if (r < 0) {
2910 bus_log_parse_error(r);
2911 return 0;
2912 }
2913
2914 if (b)
2915 return 0;
2916
2917 /* systemd finished reloading, let's recheck all our sessions */
2918 log_debug("System manager has been reloaded, rechecking sessions...");
2919
2920 HASHMAP_FOREACH(session, m->sessions, i)
2921 session_add_to_gc_queue(session);
2922
2923 return 0;
2924 }
2925
2926 int manager_send_changed(Manager *manager, const char *property, ...) {
2927 char **l;
2928
2929 assert(manager);
2930
2931 l = strv_from_stdarg_alloca(property);
2932
2933 return sd_bus_emit_properties_changed_strv(
2934 manager->bus,
2935 "/org/freedesktop/login1",
2936 "org.freedesktop.login1.Manager",
2937 l);
2938 }
2939
2940 static int strdup_job(sd_bus_message *reply, char **job) {
2941 const char *j;
2942 char *copy;
2943 int r;
2944
2945 r = sd_bus_message_read(reply, "o", &j);
2946 if (r < 0)
2947 return r;
2948
2949 copy = strdup(j);
2950 if (!copy)
2951 return -ENOMEM;
2952
2953 *job = copy;
2954 return 1;
2955 }
2956
2957 int manager_start_slice(
2958 Manager *manager,
2959 const char *slice,
2960 const char *description,
2961 const char *after,
2962 const char *after2,
2963 uint64_t tasks_max,
2964 sd_bus_error *error,
2965 char **job) {
2966
2967 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
2968 int r;
2969
2970 assert(manager);
2971 assert(slice);
2972 assert(job);
2973
2974 r = sd_bus_message_new_method_call(
2975 manager->bus,
2976 &m,
2977 "org.freedesktop.systemd1",
2978 "/org/freedesktop/systemd1",
2979 "org.freedesktop.systemd1.Manager",
2980 "StartTransientUnit");
2981 if (r < 0)
2982 return r;
2983
2984 r = sd_bus_message_append(m, "ss", strempty(slice), "fail");
2985 if (r < 0)
2986 return r;
2987
2988 r = sd_bus_message_open_container(m, 'a', "(sv)");
2989 if (r < 0)
2990 return r;
2991
2992 if (!isempty(description)) {
2993 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2994 if (r < 0)
2995 return r;
2996 }
2997
2998 if (!isempty(after)) {
2999 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
3000 if (r < 0)
3001 return r;
3002 }
3003
3004 if (!isempty(after2)) {
3005 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
3006 if (r < 0)
3007 return r;
3008 }
3009
3010 r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
3011 if (r < 0)
3012 return r;
3013
3014 r = sd_bus_message_close_container(m);
3015 if (r < 0)
3016 return r;
3017
3018 r = sd_bus_message_append(m, "a(sa(sv))", 0);
3019 if (r < 0)
3020 return r;
3021
3022 r = sd_bus_call(manager->bus, m, 0, error, &reply);
3023 if (r < 0)
3024 return r;
3025
3026 return strdup_job(reply, job);
3027 }
3028
3029 int manager_start_scope(
3030 Manager *manager,
3031 const char *scope,
3032 pid_t pid,
3033 const char *slice,
3034 const char *description,
3035 const char *after,
3036 const char *after2,
3037 uint64_t tasks_max,
3038 sd_bus_error *error,
3039 char **job) {
3040
3041 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
3042 int r;
3043
3044 assert(manager);
3045 assert(scope);
3046 assert(pid > 1);
3047 assert(job);
3048
3049 r = sd_bus_message_new_method_call(
3050 manager->bus,
3051 &m,
3052 "org.freedesktop.systemd1",
3053 "/org/freedesktop/systemd1",
3054 "org.freedesktop.systemd1.Manager",
3055 "StartTransientUnit");
3056 if (r < 0)
3057 return r;
3058
3059 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
3060 if (r < 0)
3061 return r;
3062
3063 r = sd_bus_message_open_container(m, 'a', "(sv)");
3064 if (r < 0)
3065 return r;
3066
3067 if (!isempty(slice)) {
3068 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
3069 if (r < 0)
3070 return r;
3071 }
3072
3073 if (!isempty(description)) {
3074 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
3075 if (r < 0)
3076 return r;
3077 }
3078
3079 if (!isempty(after)) {
3080 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
3081 if (r < 0)
3082 return r;
3083 }
3084
3085 if (!isempty(after2)) {
3086 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
3087 if (r < 0)
3088 return r;
3089 }
3090
3091 /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore
3092 * SIGTERM */
3093 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
3094 if (r < 0)
3095 return r;
3096
3097 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
3098 if (r < 0)
3099 return r;
3100
3101 r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
3102 if (r < 0)
3103 return r;
3104
3105 r = sd_bus_message_close_container(m);
3106 if (r < 0)
3107 return r;
3108
3109 r = sd_bus_message_append(m, "a(sa(sv))", 0);
3110 if (r < 0)
3111 return r;
3112
3113 r = sd_bus_call(manager->bus, m, 0, error, &reply);
3114 if (r < 0)
3115 return r;
3116
3117 return strdup_job(reply, job);
3118 }
3119
3120 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
3121 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3122 int r;
3123
3124 assert(manager);
3125 assert(unit);
3126 assert(job);
3127
3128 r = sd_bus_call_method(
3129 manager->bus,
3130 "org.freedesktop.systemd1",
3131 "/org/freedesktop/systemd1",
3132 "org.freedesktop.systemd1.Manager",
3133 "StartUnit",
3134 error,
3135 &reply,
3136 "ss", unit, "replace");
3137 if (r < 0)
3138 return r;
3139
3140 return strdup_job(reply, job);
3141 }
3142
3143 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
3144 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3145 int r;
3146
3147 assert(manager);
3148 assert(unit);
3149 assert(job);
3150
3151 r = sd_bus_call_method(
3152 manager->bus,
3153 "org.freedesktop.systemd1",
3154 "/org/freedesktop/systemd1",
3155 "org.freedesktop.systemd1.Manager",
3156 "StopUnit",
3157 error,
3158 &reply,
3159 "ss", unit, "fail");
3160 if (r < 0) {
3161 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
3162 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
3163
3164 *job = NULL;
3165 sd_bus_error_free(error);
3166 return 0;
3167 }
3168
3169 return r;
3170 }
3171
3172 return strdup_job(reply, job);
3173 }
3174
3175 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
3176 _cleanup_free_ char *path = NULL;
3177 int r;
3178
3179 assert(manager);
3180 assert(scope);
3181
3182 path = unit_dbus_path_from_name(scope);
3183 if (!path)
3184 return -ENOMEM;
3185
3186 r = sd_bus_call_method(
3187 manager->bus,
3188 "org.freedesktop.systemd1",
3189 path,
3190 "org.freedesktop.systemd1.Scope",
3191 "Abandon",
3192 error,
3193 NULL,
3194 NULL);
3195 if (r < 0) {
3196 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
3197 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
3198 sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
3199 sd_bus_error_free(error);
3200 return 0;
3201 }
3202
3203 return r;
3204 }
3205
3206 return 1;
3207 }
3208
3209 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
3210 assert(manager);
3211 assert(unit);
3212
3213 return sd_bus_call_method(
3214 manager->bus,
3215 "org.freedesktop.systemd1",
3216 "/org/freedesktop/systemd1",
3217 "org.freedesktop.systemd1.Manager",
3218 "KillUnit",
3219 error,
3220 NULL,
3221 "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
3222 }
3223
3224 int manager_unit_is_active(Manager *manager, const char *unit) {
3225 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3226 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3227 _cleanup_free_ char *path = NULL;
3228 const char *state;
3229 int r;
3230
3231 assert(manager);
3232 assert(unit);
3233
3234 path = unit_dbus_path_from_name(unit);
3235 if (!path)
3236 return -ENOMEM;
3237
3238 r = sd_bus_get_property(
3239 manager->bus,
3240 "org.freedesktop.systemd1",
3241 path,
3242 "org.freedesktop.systemd1.Unit",
3243 "ActiveState",
3244 &error,
3245 &reply,
3246 "s");
3247 if (r < 0) {
3248 /* systemd might have droppped off momentarily, let's
3249 * not make this an error */
3250 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3251 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3252 return true;
3253
3254 /* If the unit is already unloaded then it's not
3255 * active */
3256 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
3257 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
3258 return false;
3259
3260 return r;
3261 }
3262
3263 r = sd_bus_message_read(reply, "s", &state);
3264 if (r < 0)
3265 return -EINVAL;
3266
3267 return !streq(state, "inactive") && !streq(state, "failed");
3268 }
3269
3270 int manager_job_is_active(Manager *manager, const char *path) {
3271 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3272 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3273 int r;
3274
3275 assert(manager);
3276 assert(path);
3277
3278 r = sd_bus_get_property(
3279 manager->bus,
3280 "org.freedesktop.systemd1",
3281 path,
3282 "org.freedesktop.systemd1.Job",
3283 "State",
3284 &error,
3285 &reply,
3286 "s");
3287 if (r < 0) {
3288 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3289 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3290 return true;
3291
3292 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3293 return false;
3294
3295 return r;
3296 }
3297
3298 /* We don't actually care about the state really. The fact
3299 * that we could read the job state is enough for us */
3300
3301 return true;
3302 }