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