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