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