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