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