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