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