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