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