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