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