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