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