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