chiark / gitweb /
logind: fix delayed execution regression
[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                         free(id);
730                         id = NULL;
731                 }
732         }
733
734         if (!id) {
735                 do {
736                         free(id);
737                         id = NULL;
738
739                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
740                                 return -ENOMEM;
741
742                 } while (hashmap_get(m->sessions, id));
743         }
744
745         r = manager_add_user_by_uid(m, uid, &user);
746         if (r < 0)
747                 goto fail;
748
749         r = manager_add_session(m, id, &session);
750         if (r < 0)
751                 goto fail;
752
753         session_set_user(session, user);
754
755         session->leader = leader;
756         session->audit_id = audit_id;
757         session->type = t;
758         session->class = c;
759         session->remote = remote;
760         session->vtnr = vtnr;
761
762         if (!isempty(tty)) {
763                 session->tty = strdup(tty);
764                 if (!session->tty) {
765                         r = -ENOMEM;
766                         goto fail;
767                 }
768         }
769
770         if (!isempty(display)) {
771                 session->display = strdup(display);
772                 if (!session->display) {
773                         r = -ENOMEM;
774                         goto fail;
775                 }
776         }
777
778         if (!isempty(remote_user)) {
779                 session->remote_user = strdup(remote_user);
780                 if (!session->remote_user) {
781                         r = -ENOMEM;
782                         goto fail;
783                 }
784         }
785
786         if (!isempty(remote_host)) {
787                 session->remote_host = strdup(remote_host);
788                 if (!session->remote_host) {
789                         r = -ENOMEM;
790                         goto fail;
791                 }
792         }
793
794         if (!isempty(service)) {
795                 session->service = strdup(service);
796                 if (!session->service) {
797                         r = -ENOMEM;
798                         goto fail;
799                 }
800         }
801
802         if (!isempty(desktop)) {
803                 session->desktop = strdup(desktop);
804                 if (!session->desktop) {
805                         r = -ENOMEM;
806                         goto fail;
807                 }
808         }
809
810         if (seat) {
811                 r = seat_attach_session(seat, session);
812                 if (r < 0)
813                         goto fail;
814         }
815
816         r = session_start(session);
817         if (r < 0)
818                 goto fail;
819
820         session->create_message = sd_bus_message_ref(message);
821
822         /* Now, let's wait until the slice unit and stuff got
823          * created. We send the reply back from
824          * session_send_create_reply(). */
825
826         return 1;
827
828 fail:
829         if (session)
830                 session_add_to_gc_queue(session);
831
832         if (user)
833                 user_add_to_gc_queue(user);
834
835         return r;
836 }
837
838 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
839         Manager *m = userdata;
840         Session *session;
841         const char *name;
842         int r;
843
844         assert(message);
845         assert(m);
846
847         r = sd_bus_message_read(message, "s", &name);
848         if (r < 0)
849                 return r;
850
851         r = manager_get_session_from_creds(m, message, name, error, &session);
852         if (r < 0)
853                 return r;
854
855         r = session_release(session);
856         if (r < 0)
857                 return r;
858
859         return sd_bus_reply_method_return(message, NULL);
860 }
861
862 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
863         Manager *m = userdata;
864         Session *session;
865         const char *name;
866         int r;
867
868         assert(message);
869         assert(m);
870
871         r = sd_bus_message_read(message, "s", &name);
872         if (r < 0)
873                 return r;
874
875         r = manager_get_session_from_creds(m, message, name, error, &session);
876         if (r < 0)
877                 return r;
878
879         return bus_session_method_activate(message, session, error);
880 }
881
882 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
883         const char *session_name, *seat_name;
884         Manager *m = userdata;
885         Session *session;
886         Seat *seat;
887         int r;
888
889         assert(message);
890         assert(m);
891
892         /* Same as ActivateSession() but refuses to work if
893          * the seat doesn't match */
894
895         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
896         if (r < 0)
897                 return r;
898
899         r = manager_get_session_from_creds(m, message, session_name, error, &session);
900         if (r < 0)
901                 return r;
902
903         r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
904         if (r < 0)
905                 return r;
906
907         if (session->seat != seat)
908                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
909
910         r = session_activate(session);
911         if (r < 0)
912                 return r;
913
914         return sd_bus_reply_method_return(message, NULL);
915 }
916
917 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
918         Manager *m = userdata;
919         Session *session;
920         const char *name;
921         int r;
922
923         assert(message);
924         assert(m);
925
926         r = sd_bus_message_read(message, "s", &name);
927         if (r < 0)
928                 return r;
929
930         r = manager_get_session_from_creds(m, message, name, error, &session);
931         if (r < 0)
932                 return r;
933
934         return bus_session_method_lock(message, session, error);
935 }
936
937 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
938         Manager *m = userdata;
939         int r;
940
941         assert(message);
942         assert(m);
943
944         r = bus_verify_polkit_async(
945                         message,
946                         CAP_SYS_ADMIN,
947                         "org.freedesktop.login1.lock-sessions",
948                         false,
949                         UID_INVALID,
950                         &m->polkit_registry,
951                         error);
952         if (r < 0)
953                 return r;
954         if (r == 0)
955                 return 1; /* Will call us back */
956
957         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
958         if (r < 0)
959                 return r;
960
961         return sd_bus_reply_method_return(message, NULL);
962 }
963
964 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
965         const char *name;
966         Manager *m = userdata;
967         Session *session;
968         int r;
969
970         assert(message);
971         assert(m);
972
973         r = sd_bus_message_read(message, "s", &name);
974         if (r < 0)
975                 return r;
976
977         r = manager_get_session_from_creds(m, message, name, error, &session);
978         if (r < 0)
979                 return r;
980
981         return bus_session_method_kill(message, session, error);
982 }
983
984 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
985         Manager *m = userdata;
986         uint32_t uid;
987         User *user;
988         int r;
989
990         assert(message);
991         assert(m);
992
993         r = sd_bus_message_read(message, "u", &uid);
994         if (r < 0)
995                 return r;
996
997         r = manager_get_user_from_creds(m, message, uid, error, &user);
998         if (r < 0)
999                 return r;
1000
1001         return bus_user_method_kill(message, user, error);
1002 }
1003
1004 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1005         Manager *m = userdata;
1006         const char *name;
1007         Session *session;
1008         int r;
1009
1010         assert(message);
1011         assert(m);
1012
1013         r = sd_bus_message_read(message, "s", &name);
1014         if (r < 0)
1015                 return r;
1016
1017         r = manager_get_session_from_creds(m, message, name, error, &session);
1018         if (r < 0)
1019                 return r;
1020
1021         return bus_session_method_terminate(message, session, error);
1022 }
1023
1024 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1025         Manager *m = userdata;
1026         uint32_t uid;
1027         User *user;
1028         int r;
1029
1030         assert(message);
1031         assert(m);
1032
1033         r = sd_bus_message_read(message, "u", &uid);
1034         if (r < 0)
1035                 return r;
1036
1037         r = manager_get_user_from_creds(m, message, uid, error, &user);
1038         if (r < 0)
1039                 return r;
1040
1041         return bus_user_method_terminate(message, user, error);
1042 }
1043
1044 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1045         Manager *m = userdata;
1046         const char *name;
1047         Seat *seat;
1048         int r;
1049
1050         assert(message);
1051         assert(m);
1052
1053         r = sd_bus_message_read(message, "s", &name);
1054         if (r < 0)
1055                 return r;
1056
1057         r = manager_get_seat_from_creds(m, message, name, error, &seat);
1058         if (r < 0)
1059                 return r;
1060
1061         return bus_seat_method_terminate(message, seat, error);
1062 }
1063
1064 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1065         _cleanup_free_ char *cc = NULL;
1066         Manager *m = userdata;
1067         int b, r;
1068         struct passwd *pw;
1069         const char *path;
1070         uint32_t uid;
1071         int interactive;
1072
1073         assert(message);
1074         assert(m);
1075
1076         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1077         if (r < 0)
1078                 return r;
1079
1080         if (uid == UID_INVALID) {
1081                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1082
1083                 /* Note that we get the owner UID of the session, not the actual client UID here! */
1084                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1085                 if (r < 0)
1086                         return r;
1087
1088                 r = sd_bus_creds_get_owner_uid(creds, &uid);
1089                 if (r < 0)
1090                         return r;
1091         }
1092
1093         errno = 0;
1094         pw = getpwuid(uid);
1095         if (!pw)
1096                 return errno ? -errno : -ENOENT;
1097
1098         r = bus_verify_polkit_async(
1099                         message,
1100                         CAP_SYS_ADMIN,
1101                         "org.freedesktop.login1.set-user-linger",
1102                         interactive,
1103                         UID_INVALID,
1104                         &m->polkit_registry,
1105                         error);
1106         if (r < 0)
1107                 return r;
1108         if (r == 0)
1109                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1110
1111         mkdir_p_label("/var/lib/systemd", 0755);
1112
1113         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1114         if (r < 0)
1115                 return r;
1116
1117         cc = cescape(pw->pw_name);
1118         if (!cc)
1119                 return -ENOMEM;
1120
1121         path = strjoina("/var/lib/systemd/linger/", cc);
1122         if (b) {
1123                 User *u;
1124
1125                 r = touch(path);
1126                 if (r < 0)
1127                         return r;
1128
1129                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1130                         user_start(u);
1131
1132         } else {
1133                 User *u;
1134
1135                 r = unlink(path);
1136                 if (r < 0 && errno != ENOENT)
1137                         return -errno;
1138
1139                 u = hashmap_get(m->users, UID_TO_PTR(uid));
1140                 if (u)
1141                         user_add_to_gc_queue(u);
1142         }
1143
1144         return sd_bus_reply_method_return(message, NULL);
1145 }
1146
1147 static int trigger_device(Manager *m, struct udev_device *d) {
1148         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1149         struct udev_list_entry *first, *item;
1150         int r;
1151
1152         assert(m);
1153
1154         e = udev_enumerate_new(m->udev);
1155         if (!e)
1156                 return -ENOMEM;
1157
1158         if (d) {
1159                 r = udev_enumerate_add_match_parent(e, d);
1160                 if (r < 0)
1161                         return r;
1162         }
1163
1164         r = udev_enumerate_scan_devices(e);
1165         if (r < 0)
1166                 return r;
1167
1168         first = udev_enumerate_get_list_entry(e);
1169         udev_list_entry_foreach(item, first) {
1170                 _cleanup_free_ char *t = NULL;
1171                 const char *p;
1172
1173                 p = udev_list_entry_get_name(item);
1174
1175                 t = strappend(p, "/uevent");
1176                 if (!t)
1177                         return -ENOMEM;
1178
1179                 write_string_file(t, "change");
1180         }
1181
1182         return 0;
1183 }
1184
1185 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1186         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1187         _cleanup_free_ char *rule = NULL, *file = NULL;
1188         const char *id_for_seat;
1189         int r;
1190
1191         assert(m);
1192         assert(seat);
1193         assert(sysfs);
1194
1195         d = udev_device_new_from_syspath(m->udev, sysfs);
1196         if (!d)
1197                 return -ENODEV;
1198
1199         if (!udev_device_has_tag(d, "seat"))
1200                 return -ENODEV;
1201
1202         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1203         if (!id_for_seat)
1204                 return -ENODEV;
1205
1206         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1207                 return -ENOMEM;
1208
1209         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1210                 return -ENOMEM;
1211
1212         mkdir_p_label("/etc/udev/rules.d", 0755);
1213         mac_selinux_init("/etc");
1214         r = write_string_file_atomic_label(file, rule);
1215         if (r < 0)
1216                 return r;
1217
1218         return trigger_device(m, d);
1219 }
1220
1221 static int flush_devices(Manager *m) {
1222         _cleanup_closedir_ DIR *d;
1223
1224         assert(m);
1225
1226         d = opendir("/etc/udev/rules.d");
1227         if (!d) {
1228                 if (errno != ENOENT)
1229                         log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1230         } else {
1231                 struct dirent *de;
1232
1233                 while ((de = readdir(d))) {
1234
1235                         if (!dirent_is_file(de))
1236                                 continue;
1237
1238                         if (!startswith(de->d_name, "72-seat-"))
1239                                 continue;
1240
1241                         if (!endswith(de->d_name, ".rules"))
1242                                 continue;
1243
1244                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1245                                 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1246                 }
1247         }
1248
1249         return trigger_device(m, NULL);
1250 }
1251
1252 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1253         const char *sysfs, *seat;
1254         Manager *m = userdata;
1255         int interactive, r;
1256
1257         assert(message);
1258         assert(m);
1259
1260         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1261         if (r < 0)
1262                 return r;
1263
1264         if (!path_startswith(sysfs, "/sys"))
1265                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1266
1267         if (!seat_name_is_valid(seat))
1268                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1269
1270         r = bus_verify_polkit_async(
1271                         message,
1272                         CAP_SYS_ADMIN,
1273                         "org.freedesktop.login1.attach-device",
1274                         interactive,
1275                         UID_INVALID,
1276                         &m->polkit_registry,
1277                         error);
1278         if (r < 0)
1279                 return r;
1280         if (r == 0)
1281                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1282
1283         r = attach_device(m, seat, sysfs);
1284         if (r < 0)
1285                 return r;
1286
1287         return sd_bus_reply_method_return(message, NULL);
1288 }
1289
1290 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1291         Manager *m = userdata;
1292         int interactive, r;
1293
1294         assert(message);
1295         assert(m);
1296
1297         r = sd_bus_message_read(message, "b", &interactive);
1298         if (r < 0)
1299                 return r;
1300
1301         r = bus_verify_polkit_async(
1302                         message,
1303                         CAP_SYS_ADMIN,
1304                         "org.freedesktop.login1.flush-devices",
1305                         interactive,
1306                         UID_INVALID,
1307                         &m->polkit_registry,
1308                         error);
1309         if (r < 0)
1310                 return r;
1311         if (r == 0)
1312                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1313
1314         r = flush_devices(m);
1315         if (r < 0)
1316                 return r;
1317
1318         return sd_bus_reply_method_return(message, NULL);
1319 }
1320
1321 static int have_multiple_sessions(
1322                 Manager *m,
1323                 uid_t uid) {
1324
1325         Session *session;
1326         Iterator i;
1327
1328         assert(m);
1329
1330         /* Check for other users' sessions. Greeter sessions do not
1331          * count, and non-login sessions do not count either. */
1332         HASHMAP_FOREACH(session, m->sessions, i)
1333                 if (session->class == SESSION_USER &&
1334                     session->user->uid != uid)
1335                         return true;
1336
1337         return false;
1338 }
1339
1340 static int bus_manager_log_shutdown(
1341                 Manager *m,
1342                 InhibitWhat w,
1343                 const char *unit_name) {
1344
1345         const char *p, *q;
1346
1347         assert(m);
1348         assert(unit_name);
1349
1350         if (w != INHIBIT_SHUTDOWN)
1351                 return 0;
1352
1353         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1354                 p = "MESSAGE=System is powering down.";
1355                 q = "SHUTDOWN=power-off";
1356         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1357                 p = "MESSAGE=System is halting.";
1358                 q = "SHUTDOWN=halt";
1359         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1360                 p = "MESSAGE=System is rebooting.";
1361                 q = "SHUTDOWN=reboot";
1362         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1363                 p = "MESSAGE=System is rebooting with kexec.";
1364                 q = "SHUTDOWN=kexec";
1365         } else {
1366                 p = "MESSAGE=System is shutting down.";
1367                 q = NULL;
1368         }
1369
1370         return log_struct(LOG_NOTICE,
1371                           LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1372                           p,
1373                           q,
1374                           NULL);
1375 }
1376
1377 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1378         Manager *m = userdata;
1379
1380         assert(e);
1381         assert(m);
1382
1383         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1384         return 0;
1385 }
1386
1387 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1388         int r;
1389
1390         assert(m);
1391
1392         if (until <= now(CLOCK_MONOTONIC))
1393                 return 0;
1394
1395         /* We want to ignore the lid switch for a while after each
1396          * suspend, and after boot-up. Hence let's install a timer for
1397          * this. As long as the event source exists we ignore the lid
1398          * switch. */
1399
1400         if (m->lid_switch_ignore_event_source) {
1401                 usec_t u;
1402
1403                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1404                 if (r < 0)
1405                         return r;
1406
1407                 if (until <= u)
1408                         return 0;
1409
1410                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1411         } else
1412                 r = sd_event_add_time(
1413                                 m->event,
1414                                 &m->lid_switch_ignore_event_source,
1415                                 CLOCK_MONOTONIC,
1416                                 until, 0,
1417                                 lid_switch_ignore_handler, m);
1418
1419         return r;
1420 }
1421
1422 static int execute_shutdown_or_sleep(
1423                 Manager *m,
1424                 InhibitWhat w,
1425                 const char *unit_name,
1426                 sd_bus_error *error) {
1427
1428         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1429         const char *p;
1430         char *c;
1431         int r;
1432
1433         assert(m);
1434         assert(w >= 0);
1435         assert(w < _INHIBIT_WHAT_MAX);
1436         assert(unit_name);
1437
1438         bus_manager_log_shutdown(m, w, unit_name);
1439
1440         r = sd_bus_call_method(
1441                         m->bus,
1442                         "org.freedesktop.systemd1",
1443                         "/org/freedesktop/systemd1",
1444                         "org.freedesktop.systemd1.Manager",
1445                         "StartUnit",
1446                         error,
1447                         &reply,
1448                         "ss", unit_name, "replace-irreversibly");
1449         if (r < 0)
1450                 return r;
1451
1452         r = sd_bus_message_read(reply, "o", &p);
1453         if (r < 0)
1454                 return r;
1455
1456         c = strdup(p);
1457         if (!c)
1458                 return -ENOMEM;
1459
1460         m->action_unit = unit_name;
1461         free(m->action_job);
1462         m->action_job = c;
1463         m->action_what = w;
1464
1465         /* Make sure the lid switch is ignored for a while */
1466         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1467
1468         return 0;
1469 }
1470
1471 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1472
1473         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1474         Inhibitor *offending = NULL;
1475         int r;
1476
1477         assert(manager);
1478
1479         if (manager->action_what == 0 || manager->action_job)
1480                 return 0;
1481
1482         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1483                 _cleanup_free_ char *comm = NULL, *u = NULL;
1484
1485                 if (!timeout)
1486                         return 0;
1487
1488                 (void) get_process_comm(offending->pid, &comm);
1489                 u = uid_to_name(offending->uid);
1490
1491                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1492                            offending->uid, strna(u),
1493                            offending->pid, strna(comm));
1494         }
1495
1496         /* Actually do the operation */
1497         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
1498         if (r < 0) {
1499                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1500
1501                 manager->action_unit = NULL;
1502                 manager->action_what = 0;
1503                 return r;
1504         }
1505
1506         return 1;
1507 }
1508
1509 static int manager_inhibit_timeout_handler(
1510                         sd_event_source *s,
1511                         uint64_t usec,
1512                         void *userdata) {
1513
1514         Manager *manager = userdata;
1515         int r;
1516
1517         assert(manager);
1518         assert(manager->inhibit_timeout_source == s);
1519
1520         r = manager_dispatch_delayed(manager, true);
1521         return (r < 0) ? r : 0;
1522 }
1523
1524 static int delay_shutdown_or_sleep(
1525                 Manager *m,
1526                 InhibitWhat w,
1527                 const char *unit_name) {
1528
1529         int r;
1530         usec_t timeout_val;
1531
1532         assert(m);
1533         assert(w >= 0);
1534         assert(w < _INHIBIT_WHAT_MAX);
1535         assert(unit_name);
1536
1537         timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1538
1539         if (m->inhibit_timeout_source) {
1540                 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1541                 if (r < 0)
1542                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1543
1544                 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1545                 if (r < 0)
1546                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1547         } else {
1548                 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1549                                       timeout_val, 0, manager_inhibit_timeout_handler, m);
1550                 if (r < 0)
1551                         return r;
1552         }
1553
1554         m->action_unit = unit_name;
1555         m->action_what = w;
1556
1557         return 0;
1558 }
1559
1560 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1561
1562         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1563                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1564                 [INHIBIT_SLEEP] = "PrepareForSleep"
1565         };
1566
1567         int active = _active;
1568
1569         assert(m);
1570         assert(w >= 0);
1571         assert(w < _INHIBIT_WHAT_MAX);
1572         assert(signal_name[w]);
1573
1574         return sd_bus_emit_signal(m->bus,
1575                                   "/org/freedesktop/login1",
1576                                   "org.freedesktop.login1.Manager",
1577                                   signal_name[w],
1578                                   "b",
1579                                   active);
1580 }
1581
1582 int bus_manager_shutdown_or_sleep_now_or_later(
1583                 Manager *m,
1584                 const char *unit_name,
1585                 InhibitWhat w,
1586                 sd_bus_error *error) {
1587
1588         bool delayed;
1589         int r;
1590
1591         assert(m);
1592         assert(unit_name);
1593         assert(w >= 0);
1594         assert(w <= _INHIBIT_WHAT_MAX);
1595         assert(!m->action_job);
1596
1597         /* Tell everybody to prepare for shutdown/sleep */
1598         send_prepare_for(m, w, true);
1599
1600         delayed =
1601                 m->inhibit_delay_max > 0 &&
1602                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1603
1604         if (delayed)
1605                 /* Shutdown is delayed, keep in mind what we
1606                  * want to do, and start a timeout */
1607                 r = delay_shutdown_or_sleep(m, w, unit_name);
1608         else
1609                 /* Shutdown is not delayed, execute it
1610                  * immediately */
1611                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1612
1613         return r;
1614 }
1615
1616 static int verify_shutdown_creds(
1617                 Manager *m,
1618                 sd_bus_message *message,
1619                 InhibitWhat w,
1620                 bool interactive,
1621                 const char *action,
1622                 const char *action_multiple_sessions,
1623                 const char *action_ignore_inhibit,
1624                 sd_bus_error *error) {
1625
1626         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1627         bool multiple_sessions, blocked;
1628         uid_t uid;
1629         int r;
1630
1631         assert(m);
1632         assert(message);
1633         assert(w >= 0);
1634         assert(w <= _INHIBIT_WHAT_MAX);
1635
1636         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1637         if (r < 0)
1638                 return r;
1639
1640         r = sd_bus_creds_get_euid(creds, &uid);
1641         if (r < 0)
1642                 return r;
1643
1644         r = have_multiple_sessions(m, uid);
1645         if (r < 0)
1646                 return r;
1647
1648         multiple_sessions = r > 0;
1649         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1650
1651         if (multiple_sessions && action_multiple_sessions) {
1652                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1653                 if (r < 0)
1654                         return r;
1655                 if (r == 0)
1656                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1657         }
1658
1659         if (blocked && action_ignore_inhibit) {
1660                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1661                 if (r < 0)
1662                         return r;
1663                 if (r == 0)
1664                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1665         }
1666
1667         if (!multiple_sessions && !blocked && action) {
1668                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1669                 if (r < 0)
1670                         return r;
1671                 if (r == 0)
1672                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1673         }
1674
1675         return 0;
1676 }
1677
1678 static int method_do_shutdown_or_sleep(
1679                 Manager *m,
1680                 sd_bus_message *message,
1681                 const char *unit_name,
1682                 InhibitWhat w,
1683                 const char *action,
1684                 const char *action_multiple_sessions,
1685                 const char *action_ignore_inhibit,
1686                 const char *sleep_verb,
1687                 sd_bus_error *error) {
1688
1689         int interactive, r;
1690
1691         assert(m);
1692         assert(message);
1693         assert(unit_name);
1694         assert(w >= 0);
1695         assert(w <= _INHIBIT_WHAT_MAX);
1696
1697         r = sd_bus_message_read(message, "b", &interactive);
1698         if (r < 0)
1699                 return r;
1700
1701         /* Don't allow multiple jobs being executed at the same time */
1702         if (m->action_what)
1703                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1704
1705         if (sleep_verb) {
1706                 r = can_sleep(sleep_verb);
1707                 if (r < 0)
1708                         return r;
1709
1710                 if (r == 0)
1711                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1712         }
1713
1714         r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1715                                   action_ignore_inhibit, error);
1716         if (r != 0)
1717                 return r;
1718
1719         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1720         if (r < 0)
1721                 return r;
1722
1723         return sd_bus_reply_method_return(message, NULL);
1724 }
1725
1726 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727         Manager *m = userdata;
1728
1729         return method_do_shutdown_or_sleep(
1730                         m, message,
1731                         SPECIAL_POWEROFF_TARGET,
1732                         INHIBIT_SHUTDOWN,
1733                         "org.freedesktop.login1.power-off",
1734                         "org.freedesktop.login1.power-off-multiple-sessions",
1735                         "org.freedesktop.login1.power-off-ignore-inhibit",
1736                         NULL,
1737                         error);
1738 }
1739
1740 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1741         Manager *m = userdata;
1742
1743         return method_do_shutdown_or_sleep(
1744                         m, message,
1745                         SPECIAL_REBOOT_TARGET,
1746                         INHIBIT_SHUTDOWN,
1747                         "org.freedesktop.login1.reboot",
1748                         "org.freedesktop.login1.reboot-multiple-sessions",
1749                         "org.freedesktop.login1.reboot-ignore-inhibit",
1750                         NULL,
1751                         error);
1752 }
1753
1754 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1755         Manager *m = userdata;
1756
1757         return method_do_shutdown_or_sleep(
1758                         m, message,
1759                         SPECIAL_SUSPEND_TARGET,
1760                         INHIBIT_SLEEP,
1761                         "org.freedesktop.login1.suspend",
1762                         "org.freedesktop.login1.suspend-multiple-sessions",
1763                         "org.freedesktop.login1.suspend-ignore-inhibit",
1764                         "suspend",
1765                         error);
1766 }
1767
1768 static int nologin_timeout_handler(
1769                         sd_event_source *s,
1770                         uint64_t usec,
1771                         void *userdata) {
1772
1773         Manager *m = userdata;
1774         int r;
1775
1776         log_info("Creating /run/nologin, blocking further logins...");
1777
1778         r = write_string_file_atomic("/run/nologin", "System is going down.");
1779         if (r < 0)
1780                 log_error_errno(r, "Failed to create /run/nologin: %m");
1781         else
1782                 m->unlink_nologin = true;
1783
1784         return 0;
1785 }
1786
1787 static int update_schedule_file(Manager *m) {
1788
1789         int r;
1790         _cleanup_fclose_ FILE *f = NULL;
1791         _cleanup_free_ char *t = NULL, *temp_path = NULL;
1792
1793         assert(m);
1794
1795         r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1796         if (r < 0)
1797                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1798
1799         t = cescape(m->wall_message);
1800         if (!t)
1801                 return log_oom();
1802
1803         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1804         if (r < 0)
1805                 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1806
1807         (void) fchmod(fileno(f), 0644);
1808
1809         fprintf(f,
1810                 "USEC="USEC_FMT"\n"
1811                 "WARN_WALL=%i\n"
1812                 "MODE=%s\n",
1813                 m->scheduled_shutdown_timeout,
1814                 m->enable_wall_messages,
1815                 m->scheduled_shutdown_type);
1816
1817         if (!isempty(m->wall_message))
1818                 fprintf(f, "WALL_MESSAGE=%s\n", t);
1819
1820         (void) fflush_and_check(f);
1821
1822         if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1823                 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
1824                 r = -errno;
1825
1826                 (void) unlink(temp_path);
1827                 (void) unlink("/run/systemd/shutdown/scheduled");
1828         }
1829
1830         return r;
1831 }
1832
1833 static int manager_scheduled_shutdown_handler(
1834                         sd_event_source *s,
1835                         uint64_t usec,
1836                         void *userdata) {
1837
1838         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1839         Manager *m = userdata;
1840         const char *target;
1841         int r;
1842
1843         assert(m);
1844
1845         if (isempty(m->scheduled_shutdown_type))
1846                 return 0;
1847
1848         if (streq(m->scheduled_shutdown_type, "halt"))
1849                 target = SPECIAL_HALT_TARGET;
1850         else if (streq(m->scheduled_shutdown_type, "poweroff"))
1851                 target = SPECIAL_POWEROFF_TARGET;
1852         else
1853                 target = SPECIAL_REBOOT_TARGET;
1854
1855         r = execute_shutdown_or_sleep(m, 0, target, &error);
1856         if (r < 0)
1857                 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
1858
1859         return 0;
1860 }
1861
1862 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1863         Manager *m = userdata;
1864         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1865         const char *action_multiple_sessions = NULL;
1866         const char *action_ignore_inhibit = NULL;
1867         const char *action = NULL;
1868         uint64_t elapse;
1869         char *type;
1870         int r;
1871
1872         assert(m);
1873         assert(message);
1874
1875         r = sd_bus_message_read(message, "st", &type, &elapse);
1876         if (r < 0)
1877                 return r;
1878
1879         if (streq(type, "reboot")) {
1880                 action = "org.freedesktop.login1.reboot";
1881                 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1882                 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1883         } else if (streq(type, "halt")) {
1884                 action = "org.freedesktop.login1.halt";
1885                 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1886                 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1887         } else if (streq(type, "poweroff")) {
1888                 action = "org.freedesktop.login1.poweroff";
1889                 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1890                 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1891         } else
1892                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1893
1894         r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1895                                   action, action_multiple_sessions, action_ignore_inhibit, error);
1896         if (r != 0)
1897                 return r;
1898
1899         if (m->scheduled_shutdown_timeout_source) {
1900                 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1901                 if (r < 0)
1902                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1903
1904                 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1905                 if (r < 0)
1906                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1907         } else {
1908                 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1909                                       CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1910                 if (r < 0)
1911                         return log_error_errno(r, "sd_event_add_time() failed: %m");
1912         }
1913
1914         r = free_and_strdup(&m->scheduled_shutdown_type, type);
1915         if (r < 0) {
1916                 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1917                 return log_oom();
1918         }
1919
1920         if (m->nologin_timeout_source) {
1921                 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1922                 if (r < 0)
1923                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1924
1925                 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1926                 if (r < 0)
1927                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1928         } else {
1929                 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1930                                       CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1931                 if (r < 0)
1932                         return log_error_errno(r, "sd_event_add_time() failed: %m");
1933         }
1934
1935         m->scheduled_shutdown_timeout = elapse;
1936
1937         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1938         if (r >= 0) {
1939                 const char *tty;
1940
1941                 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1942                 (void) sd_bus_creds_get_tty(creds, &tty);
1943
1944                 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1945                 if (r < 0) {
1946                         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1947                         return log_oom();
1948                 }
1949         }
1950
1951         r = manager_setup_wall_message_timer(m);
1952         if (r < 0)
1953                 return r;
1954
1955         if (!isempty(type)) {
1956                 r = update_schedule_file(m);
1957                 if (r < 0)
1958                         return r;
1959         } else
1960                 (void) unlink("/run/systemd/shutdown/scheduled");
1961
1962         return sd_bus_reply_method_return(message, NULL);
1963 }
1964
1965 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1966         Manager *m = userdata;
1967         bool cancelled;
1968
1969         assert(m);
1970         assert(message);
1971
1972         cancelled = m->scheduled_shutdown_type != NULL;
1973
1974         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1975         m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1976         m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1977         free(m->scheduled_shutdown_type);
1978         m->scheduled_shutdown_type = NULL;
1979         m->scheduled_shutdown_timeout = 0;
1980
1981         if (m->unlink_nologin) {
1982                 (void) unlink("/run/nologin");
1983                 m->unlink_nologin = false;
1984         }
1985
1986         if (cancelled) {
1987                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1988                 const char *tty = NULL;
1989                 uid_t uid = 0;
1990                 int r;
1991
1992                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1993                 if (r >= 0) {
1994                         (void) sd_bus_creds_get_uid(creds, &uid);
1995                         (void) sd_bus_creds_get_tty(creds, &tty);
1996                 }
1997
1998                 utmp_wall("The system shutdown has been cancelled",
1999                           lookup_uid(uid), tty, logind_wall_tty_filter, m);
2000         }
2001
2002         return sd_bus_reply_method_return(message, "b", cancelled);
2003 }
2004
2005 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2006         Manager *m = userdata;
2007
2008         return method_do_shutdown_or_sleep(
2009                         m, message,
2010                         SPECIAL_HIBERNATE_TARGET,
2011                         INHIBIT_SLEEP,
2012                         "org.freedesktop.login1.hibernate",
2013                         "org.freedesktop.login1.hibernate-multiple-sessions",
2014                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2015                         "hibernate",
2016                         error);
2017 }
2018
2019 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2020         Manager *m = userdata;
2021
2022         return method_do_shutdown_or_sleep(
2023                         m, message,
2024                         SPECIAL_HYBRID_SLEEP_TARGET,
2025                         INHIBIT_SLEEP,
2026                         "org.freedesktop.login1.hibernate",
2027                         "org.freedesktop.login1.hibernate-multiple-sessions",
2028                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2029                         "hybrid-sleep",
2030                         error);
2031 }
2032
2033 static int method_can_shutdown_or_sleep(
2034                 Manager *m,
2035                 sd_bus_message *message,
2036                 InhibitWhat w,
2037                 const char *action,
2038                 const char *action_multiple_sessions,
2039                 const char *action_ignore_inhibit,
2040                 const char *sleep_verb,
2041                 sd_bus_error *error) {
2042
2043         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2044         bool multiple_sessions, challenge, blocked;
2045         const char *result = NULL;
2046         uid_t uid;
2047         int r;
2048
2049         assert(m);
2050         assert(message);
2051         assert(w >= 0);
2052         assert(w <= _INHIBIT_WHAT_MAX);
2053         assert(action);
2054         assert(action_multiple_sessions);
2055         assert(action_ignore_inhibit);
2056
2057         if (sleep_verb) {
2058                 r = can_sleep(sleep_verb);
2059                 if (r < 0)
2060                         return r;
2061                 if (r == 0)
2062                         return sd_bus_reply_method_return(message, "s", "na");
2063         }
2064
2065         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2066         if (r < 0)
2067                 return r;
2068
2069         r = sd_bus_creds_get_euid(creds, &uid);
2070         if (r < 0)
2071                 return r;
2072
2073         r = have_multiple_sessions(m, uid);
2074         if (r < 0)
2075                 return r;
2076
2077         multiple_sessions = r > 0;
2078         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2079
2080         if (multiple_sessions) {
2081                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
2082                 if (r < 0)
2083                         return r;
2084
2085                 if (r > 0)
2086                         result = "yes";
2087                 else if (challenge)
2088                         result = "challenge";
2089                 else
2090                         result = "no";
2091         }
2092
2093         if (blocked) {
2094                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
2095                 if (r < 0)
2096                         return r;
2097
2098                 if (r > 0 && !result)
2099                         result = "yes";
2100                 else if (challenge && (!result || streq(result, "yes")))
2101                         result = "challenge";
2102                 else
2103                         result = "no";
2104         }
2105
2106         if (!multiple_sessions && !blocked) {
2107                 /* If neither inhibit nor multiple sessions
2108                  * apply then just check the normal policy */
2109
2110                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
2111                 if (r < 0)
2112                         return r;
2113
2114                 if (r > 0)
2115                         result = "yes";
2116                 else if (challenge)
2117                         result = "challenge";
2118                 else
2119                         result = "no";
2120         }
2121
2122         return sd_bus_reply_method_return(message, "s", result);
2123 }
2124
2125 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2126         Manager *m = userdata;
2127
2128         return method_can_shutdown_or_sleep(
2129                         m, message,
2130                         INHIBIT_SHUTDOWN,
2131                         "org.freedesktop.login1.power-off",
2132                         "org.freedesktop.login1.power-off-multiple-sessions",
2133                         "org.freedesktop.login1.power-off-ignore-inhibit",
2134                         NULL,
2135                         error);
2136 }
2137
2138 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2139         Manager *m = userdata;
2140
2141         return method_can_shutdown_or_sleep(
2142                         m, message,
2143                         INHIBIT_SHUTDOWN,
2144                         "org.freedesktop.login1.reboot",
2145                         "org.freedesktop.login1.reboot-multiple-sessions",
2146                         "org.freedesktop.login1.reboot-ignore-inhibit",
2147                         NULL,
2148                         error);
2149 }
2150
2151 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2152         Manager *m = userdata;
2153
2154         return method_can_shutdown_or_sleep(
2155                         m, message,
2156                         INHIBIT_SLEEP,
2157                         "org.freedesktop.login1.suspend",
2158                         "org.freedesktop.login1.suspend-multiple-sessions",
2159                         "org.freedesktop.login1.suspend-ignore-inhibit",
2160                         "suspend",
2161                         error);
2162 }
2163
2164 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2165         Manager *m = userdata;
2166
2167         return method_can_shutdown_or_sleep(
2168                         m, message,
2169                         INHIBIT_SLEEP,
2170                         "org.freedesktop.login1.hibernate",
2171                         "org.freedesktop.login1.hibernate-multiple-sessions",
2172                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2173                         "hibernate",
2174                         error);
2175 }
2176
2177 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2178         Manager *m = userdata;
2179
2180         return method_can_shutdown_or_sleep(
2181                         m, message,
2182                         INHIBIT_SLEEP,
2183                         "org.freedesktop.login1.hibernate",
2184                         "org.freedesktop.login1.hibernate-multiple-sessions",
2185                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2186                         "hybrid-sleep",
2187                         error);
2188 }
2189
2190 static int property_get_reboot_to_firmware_setup(
2191                 sd_bus *bus,
2192                 const char *path,
2193                 const char *interface,
2194                 const char *property,
2195                 sd_bus_message *reply,
2196                 void *userdata,
2197                 sd_bus_error *error) {
2198         int r;
2199
2200         assert(bus);
2201         assert(reply);
2202         assert(userdata);
2203
2204         r = efi_get_reboot_to_firmware();
2205         if (r < 0 && r != -EOPNOTSUPP)
2206                 return r;
2207
2208         return sd_bus_message_append(reply, "b", r > 0);
2209 }
2210
2211 static int method_set_reboot_to_firmware_setup(
2212                 sd_bus_message *message,
2213                 void *userdata,
2214                 sd_bus_error *error) {
2215
2216         int b, r;
2217         Manager *m = userdata;
2218
2219         assert(message);
2220         assert(m);
2221
2222         r = sd_bus_message_read(message, "b", &b);
2223         if (r < 0)
2224                 return r;
2225
2226         r = bus_verify_polkit_async(message,
2227                                     CAP_SYS_ADMIN,
2228                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
2229                                     false,
2230                                     UID_INVALID,
2231                                     &m->polkit_registry,
2232                                     error);
2233         if (r < 0)
2234                 return r;
2235         if (r == 0)
2236                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2237
2238         r = efi_set_reboot_to_firmware(b);
2239         if (r < 0)
2240                 return r;
2241
2242         return sd_bus_reply_method_return(message, NULL);
2243 }
2244
2245 static int method_can_reboot_to_firmware_setup(
2246                 sd_bus_message *message,
2247                 void *userdata,
2248                 sd_bus_error *error) {
2249
2250         int r;
2251         bool challenge;
2252         const char *result;
2253         Manager *m = userdata;
2254
2255         assert(message);
2256         assert(m);
2257
2258         r = efi_reboot_to_firmware_supported();
2259         if (r == -EOPNOTSUPP)
2260                 return sd_bus_reply_method_return(message, "s", "na");
2261         else if (r < 0)
2262                 return r;
2263
2264         r = bus_test_polkit(message,
2265                             CAP_SYS_ADMIN,
2266                             "org.freedesktop.login1.set-reboot-to-firmware-setup",
2267                             UID_INVALID,
2268                             &challenge,
2269                             error);
2270         if (r < 0)
2271                 return r;
2272
2273         if (r > 0)
2274                 result = "yes";
2275         else if (challenge)
2276                 result = "challenge";
2277         else
2278                 result = "no";
2279
2280         return sd_bus_reply_method_return(message, "s", result);
2281 }
2282
2283 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2284         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2285         const char *who, *why, *what, *mode;
2286         _cleanup_free_ char *id = NULL;
2287         _cleanup_close_ int fifo_fd = -1;
2288         Manager *m = userdata;
2289         Inhibitor *i = NULL;
2290         InhibitMode mm;
2291         InhibitWhat w;
2292         pid_t pid;
2293         uid_t uid;
2294         int r;
2295
2296         assert(message);
2297         assert(m);
2298
2299         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2300         if (r < 0)
2301                 return r;
2302
2303         w = inhibit_what_from_string(what);
2304         if (w <= 0)
2305                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2306
2307         mm = inhibit_mode_from_string(mode);
2308         if (mm < 0)
2309                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2310
2311         /* Delay is only supported for shutdown/sleep */
2312         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2313                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2314
2315         /* Don't allow taking delay locks while we are already
2316          * executing the operation. We shouldn't create the impression
2317          * that the lock was successful if the machine is about to go
2318          * down/suspend any moment. */
2319         if (m->action_what & w)
2320                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2321
2322         r = bus_verify_polkit_async(
2323                         message,
2324                         CAP_SYS_BOOT,
2325                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2326                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
2327                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
2328                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
2329                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2330                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2331                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
2332                         false,
2333                         UID_INVALID,
2334                         &m->polkit_registry,
2335                         error);
2336         if (r < 0)
2337                 return r;
2338         if (r == 0)
2339                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2340
2341         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2342         if (r < 0)
2343                 return r;
2344
2345         r = sd_bus_creds_get_euid(creds, &uid);
2346         if (r < 0)
2347                 return r;
2348
2349         r = sd_bus_creds_get_pid(creds, &pid);
2350         if (r < 0)
2351                 return r;
2352
2353         do {
2354                 free(id);
2355                 id = NULL;
2356
2357                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2358                         return -ENOMEM;
2359
2360         } while (hashmap_get(m->inhibitors, id));
2361
2362         r = manager_add_inhibitor(m, id, &i);
2363         if (r < 0)
2364                 return r;
2365
2366         i->what = w;
2367         i->mode = mm;
2368         i->pid = pid;
2369         i->uid = uid;
2370         i->why = strdup(why);
2371         i->who = strdup(who);
2372
2373         if (!i->why || !i->who) {
2374                 r = -ENOMEM;
2375                 goto fail;
2376         }
2377
2378         fifo_fd = inhibitor_create_fifo(i);
2379         if (fifo_fd < 0) {
2380                 r = fifo_fd;
2381                 goto fail;
2382         }
2383
2384         inhibitor_start(i);
2385
2386         return sd_bus_reply_method_return(message, "h", fifo_fd);
2387
2388 fail:
2389         if (i)
2390                 inhibitor_free(i);
2391
2392         return r;
2393 }
2394
2395 const sd_bus_vtable manager_vtable[] = {
2396         SD_BUS_VTABLE_START(0),
2397
2398         SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2399         SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2400
2401         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2402         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2403         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2404         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2405         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2406         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2407         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2408         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2409         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2410         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2411         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2412         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2413         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2414         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2415         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2416         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2417         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2418         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2419         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2420         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2421         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2422         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2423
2424         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2425         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2426         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2427         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2428         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2429         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2430         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2431         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2432         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2433         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2434         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2435         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2436         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2437         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2438         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2439         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2440         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2441         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2442         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2443         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2444         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2445         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2446         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2447         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2448         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2449         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2450         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2451         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2452         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2453         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2454         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2455         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2456         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2457         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2458         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2459         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2460         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2461         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2462         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2463         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2464
2465         SD_BUS_SIGNAL("SessionNew", "so", 0),
2466         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2467         SD_BUS_SIGNAL("UserNew", "uo", 0),
2468         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2469         SD_BUS_SIGNAL("SeatNew", "so", 0),
2470         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2471         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2472         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2473
2474         SD_BUS_VTABLE_END
2475 };
2476
2477 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2478         int r = 0;
2479
2480         assert(s);
2481         assert(unit);
2482
2483         if (!s->started)
2484                 return r;
2485
2486         if (streq(result, "done"))
2487                 r = session_send_create_reply(s, NULL);
2488         else {
2489                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2490
2491                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2492                 r = session_send_create_reply(s, &e);
2493         }
2494
2495         return r;
2496 }
2497
2498 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2499         const char *path, *result, *unit;
2500         Manager *m = userdata;
2501         Session *session;
2502         uint32_t id;
2503         User *user;
2504         int r;
2505
2506         assert(message);
2507         assert(m);
2508
2509         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2510         if (r < 0) {
2511                 bus_log_parse_error(r);
2512                 return r;
2513         }
2514
2515         if (m->action_job && streq(m->action_job, path)) {
2516                 log_info("Operation finished.");
2517
2518                 /* Tell people that they now may take a lock again */
2519                 send_prepare_for(m, m->action_what, false);
2520
2521                 free(m->action_job);
2522                 m->action_job = NULL;
2523                 m->action_unit = NULL;
2524                 m->action_what = 0;
2525                 return 0;
2526         }
2527
2528         session = hashmap_get(m->session_units, unit);
2529         if (session) {
2530
2531                 if (streq_ptr(path, session->scope_job)) {
2532                         free(session->scope_job);
2533                         session->scope_job = NULL;
2534                 }
2535
2536                 session_jobs_reply(session, unit, result);
2537
2538                 session_save(session);
2539                 user_save(session->user);
2540                 session_add_to_gc_queue(session);
2541         }
2542
2543         user = hashmap_get(m->user_units, unit);
2544         if (user) {
2545
2546                 if (streq_ptr(path, user->service_job)) {
2547                         free(user->service_job);
2548                         user->service_job = NULL;
2549                 }
2550
2551                 if (streq_ptr(path, user->slice_job)) {
2552                         free(user->slice_job);
2553                         user->slice_job = NULL;
2554                 }
2555
2556                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2557                         session_jobs_reply(session, unit, result);
2558                 }
2559
2560                 user_save(user);
2561                 user_add_to_gc_queue(user);
2562         }
2563
2564         return 0;
2565 }
2566
2567 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2568         const char *path, *unit;
2569         Manager *m = userdata;
2570         Session *session;
2571         User *user;
2572         int r;
2573
2574         assert(message);
2575         assert(m);
2576
2577         r = sd_bus_message_read(message, "so", &unit, &path);
2578         if (r < 0) {
2579                 bus_log_parse_error(r);
2580                 return r;
2581         }
2582
2583         session = hashmap_get(m->session_units, unit);
2584         if (session)
2585                 session_add_to_gc_queue(session);
2586
2587         user = hashmap_get(m->user_units, unit);
2588         if (user)
2589                 user_add_to_gc_queue(user);
2590
2591         return 0;
2592 }
2593
2594 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2595         _cleanup_free_ char *unit = NULL;
2596         Manager *m = userdata;
2597         const char *path;
2598         Session *session;
2599         User *user;
2600         int r;
2601
2602         assert(message);
2603         assert(m);
2604
2605         path = sd_bus_message_get_path(message);
2606         if (!path)
2607                 return 0;
2608
2609         r = unit_name_from_dbus_path(path, &unit);
2610         if (r == -EINVAL) /* not a unit */
2611                 return 0;
2612         if (r < 0)
2613                 return r;
2614
2615         session = hashmap_get(m->session_units, unit);
2616         if (session)
2617                 session_add_to_gc_queue(session);
2618
2619         user = hashmap_get(m->user_units, unit);
2620         if (user)
2621                 user_add_to_gc_queue(user);
2622
2623         return 0;
2624 }
2625
2626 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2627         Manager *m = userdata;
2628         Session *session;
2629         Iterator i;
2630         int b, r;
2631
2632         assert(message);
2633         assert(m);
2634
2635         r = sd_bus_message_read(message, "b", &b);
2636         if (r < 0) {
2637                 bus_log_parse_error(r);
2638                 return r;
2639         }
2640
2641         if (b)
2642                 return 0;
2643
2644         /* systemd finished reloading, let's recheck all our sessions */
2645         log_debug("System manager has been reloaded, rechecking sessions...");
2646
2647         HASHMAP_FOREACH(session, m->sessions, i)
2648                 session_add_to_gc_queue(session);
2649
2650         return 0;
2651 }
2652
2653 int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2654         const char *name, *old, *new;
2655         Manager *m = userdata;
2656         Session *session;
2657         Iterator i;
2658         int r;
2659         char *key;
2660
2661         assert(message);
2662         assert(m);
2663
2664         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2665         if (r < 0) {
2666                 bus_log_parse_error(r);
2667                 return r;
2668         }
2669
2670         if (isempty(old) || !isempty(new))
2671                 return 0;
2672
2673         key = set_remove(m->busnames, (char*) old);
2674         if (!key)
2675                 return 0;
2676
2677         /* Drop all controllers owned by this name */
2678
2679         free(key);
2680
2681         HASHMAP_FOREACH(session, m->sessions, i)
2682                 if (session_is_controller(session, old))
2683                         session_drop_controller(session);
2684
2685         return 0;
2686 }
2687
2688 int manager_send_changed(Manager *manager, const char *property, ...) {
2689         char **l;
2690
2691         assert(manager);
2692
2693         l = strv_from_stdarg_alloca(property);
2694
2695         return sd_bus_emit_properties_changed_strv(
2696                         manager->bus,
2697                         "/org/freedesktop/login1",
2698                         "org.freedesktop.login1.Manager",
2699                         l);
2700 }
2701
2702 int manager_start_scope(
2703                 Manager *manager,
2704                 const char *scope,
2705                 pid_t pid,
2706                 const char *slice,
2707                 const char *description,
2708                 const char *after, const char *after2,
2709                 sd_bus_error *error,
2710                 char **job) {
2711
2712         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2713         int r;
2714
2715         assert(manager);
2716         assert(scope);
2717         assert(pid > 1);
2718
2719         r = sd_bus_message_new_method_call(
2720                         manager->bus,
2721                         &m,
2722                         "org.freedesktop.systemd1",
2723                         "/org/freedesktop/systemd1",
2724                         "org.freedesktop.systemd1.Manager",
2725                         "StartTransientUnit");
2726         if (r < 0)
2727                 return r;
2728
2729         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2730         if (r < 0)
2731                 return r;
2732
2733         r = sd_bus_message_open_container(m, 'a', "(sv)");
2734         if (r < 0)
2735                 return r;
2736
2737         if (!isempty(slice)) {
2738                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2739                 if (r < 0)
2740                         return r;
2741         }
2742
2743         if (!isempty(description)) {
2744                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2745                 if (r < 0)
2746                         return r;
2747         }
2748
2749         if (!isempty(after)) {
2750                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2751                 if (r < 0)
2752                         return r;
2753         }
2754
2755         if (!isempty(after2)) {
2756                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2757                 if (r < 0)
2758                         return r;
2759         }
2760
2761         /* cgroup empty notification is not available in containers
2762          * currently. To make this less problematic, let's shorten the
2763          * stop timeout for sessions, so that we don't wait
2764          * forever. */
2765
2766         /* Make sure that the session shells are terminated with
2767          * SIGHUP since bash and friends tend to ignore SIGTERM */
2768         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2769         if (r < 0)
2770                 return r;
2771
2772         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2773         if (r < 0)
2774                 return r;
2775
2776         r = sd_bus_message_close_container(m);
2777         if (r < 0)
2778                 return r;
2779
2780         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2781         if (r < 0)
2782                 return r;
2783
2784         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2785         if (r < 0)
2786                 return r;
2787
2788         if (job) {
2789                 const char *j;
2790                 char *copy;
2791
2792                 r = sd_bus_message_read(reply, "o", &j);
2793                 if (r < 0)
2794                         return r;
2795
2796                 copy = strdup(j);
2797                 if (!copy)
2798                         return -ENOMEM;
2799
2800                 *job = copy;
2801         }
2802
2803         return 1;
2804 }
2805
2806 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2807         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2808         int r;
2809
2810         assert(manager);
2811         assert(unit);
2812
2813         r = sd_bus_call_method(
2814                         manager->bus,
2815                         "org.freedesktop.systemd1",
2816                         "/org/freedesktop/systemd1",
2817                         "org.freedesktop.systemd1.Manager",
2818                         "StartUnit",
2819                         error,
2820                         &reply,
2821                         "ss", unit, "fail");
2822         if (r < 0)
2823                 return r;
2824
2825         if (job) {
2826                 const char *j;
2827                 char *copy;
2828
2829                 r = sd_bus_message_read(reply, "o", &j);
2830                 if (r < 0)
2831                         return r;
2832
2833                 copy = strdup(j);
2834                 if (!copy)
2835                         return -ENOMEM;
2836
2837                 *job = copy;
2838         }
2839
2840         return 1;
2841 }
2842
2843 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2844         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2845         int r;
2846
2847         assert(manager);
2848         assert(unit);
2849
2850         r = sd_bus_call_method(
2851                         manager->bus,
2852                         "org.freedesktop.systemd1",
2853                         "/org/freedesktop/systemd1",
2854                         "org.freedesktop.systemd1.Manager",
2855                         "StopUnit",
2856                         error,
2857                         &reply,
2858                         "ss", unit, "fail");
2859         if (r < 0) {
2860                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2861                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2862
2863                         if (job)
2864                                 *job = NULL;
2865
2866                         sd_bus_error_free(error);
2867                         return 0;
2868                 }
2869
2870                 return r;
2871         }
2872
2873         if (job) {
2874                 const char *j;
2875                 char *copy;
2876
2877                 r = sd_bus_message_read(reply, "o", &j);
2878                 if (r < 0)
2879                         return r;
2880
2881                 copy = strdup(j);
2882                 if (!copy)
2883                         return -ENOMEM;
2884
2885                 *job = copy;
2886         }
2887
2888         return 1;
2889 }
2890
2891 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2892         _cleanup_free_ char *path = NULL;
2893         int r;
2894
2895         assert(manager);
2896         assert(scope);
2897
2898         path = unit_dbus_path_from_name(scope);
2899         if (!path)
2900                 return -ENOMEM;
2901
2902         r = sd_bus_call_method(
2903                         manager->bus,
2904                         "org.freedesktop.systemd1",
2905                         path,
2906                         "org.freedesktop.systemd1.Scope",
2907                         "Abandon",
2908                         error,
2909                         NULL,
2910                         NULL);
2911         if (r < 0) {
2912                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2913                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2914                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2915                         sd_bus_error_free(error);
2916                         return 0;
2917                 }
2918
2919                 return r;
2920         }
2921
2922         return 1;
2923 }
2924
2925 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2926         assert(manager);
2927         assert(unit);
2928
2929         return sd_bus_call_method(
2930                         manager->bus,
2931                         "org.freedesktop.systemd1",
2932                         "/org/freedesktop/systemd1",
2933                         "org.freedesktop.systemd1.Manager",
2934                         "KillUnit",
2935                         error,
2936                         NULL,
2937                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2938 }
2939
2940 int manager_unit_is_active(Manager *manager, const char *unit) {
2941         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2942         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2943         _cleanup_free_ char *path = NULL;
2944         const char *state;
2945         int r;
2946
2947         assert(manager);
2948         assert(unit);
2949
2950         path = unit_dbus_path_from_name(unit);
2951         if (!path)
2952                 return -ENOMEM;
2953
2954         r = sd_bus_get_property(
2955                         manager->bus,
2956                         "org.freedesktop.systemd1",
2957                         path,
2958                         "org.freedesktop.systemd1.Unit",
2959                         "ActiveState",
2960                         &error,
2961                         &reply,
2962                         "s");
2963         if (r < 0) {
2964                 /* systemd might have droppped off momentarily, let's
2965                  * not make this an error */
2966                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2967                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2968                         return true;
2969
2970                 /* If the unit is already unloaded then it's not
2971                  * active */
2972                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2973                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2974                         return false;
2975
2976                 return r;
2977         }
2978
2979         r = sd_bus_message_read(reply, "s", &state);
2980         if (r < 0)
2981                 return -EINVAL;
2982
2983         return !streq(state, "inactive") && !streq(state, "failed");
2984 }
2985
2986 int manager_job_is_active(Manager *manager, const char *path) {
2987         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2988         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2989         int r;
2990
2991         assert(manager);
2992         assert(path);
2993
2994         r = sd_bus_get_property(
2995                         manager->bus,
2996                         "org.freedesktop.systemd1",
2997                         path,
2998                         "org.freedesktop.systemd1.Job",
2999                         "State",
3000                         &error,
3001                         &reply,
3002                         "s");
3003         if (r < 0) {
3004                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3005                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3006                         return true;
3007
3008                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3009                         return false;
3010
3011                 return r;
3012         }
3013
3014         /* We don't actually care about the state really. The fact
3015          * that we could read the job state is enough for us */
3016
3017         return true;
3018 }