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