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