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