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