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