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