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