chiark / gitweb /
ede92822db689f7e82bff1f24fa7a517c9916c11
[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         session_add_to_gc_queue(session);
864
865         return sd_bus_reply_method_return(message, NULL);
866 }
867
868 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
869         Manager *m = userdata;
870         Session *session;
871         const char *name;
872         int r;
873
874         assert(message);
875         assert(m);
876
877         r = sd_bus_message_read(message, "s", &name);
878         if (r < 0)
879                 return r;
880
881         r = manager_get_session_from_creds(m, message, name, error, &session);
882         if (r < 0)
883                 return r;
884
885         return bus_session_method_activate(message, session, error);
886 }
887
888 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
889         const char *session_name, *seat_name;
890         Manager *m = userdata;
891         Session *session;
892         Seat *seat;
893         int r;
894
895         assert(message);
896         assert(m);
897
898         /* Same as ActivateSession() but refuses to work if
899          * the seat doesn't match */
900
901         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
902         if (r < 0)
903                 return r;
904
905         r = manager_get_session_from_creds(m, message, session_name, error, &session);
906         if (r < 0)
907                 return r;
908
909         r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
910         if (r < 0)
911                 return r;
912
913         if (session->seat != seat)
914                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
915
916         r = session_activate(session);
917         if (r < 0)
918                 return r;
919
920         return sd_bus_reply_method_return(message, NULL);
921 }
922
923 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
924         Manager *m = userdata;
925         Session *session;
926         const char *name;
927         int r;
928
929         assert(message);
930         assert(m);
931
932         r = sd_bus_message_read(message, "s", &name);
933         if (r < 0)
934                 return r;
935
936         r = manager_get_session_from_creds(m, message, name, error, &session);
937         if (r < 0)
938                 return r;
939
940         return bus_session_method_lock(message, session, error);
941 }
942
943 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
944         Manager *m = userdata;
945         int r;
946
947         assert(message);
948         assert(m);
949
950         r = bus_verify_polkit_async(
951                         message,
952                         CAP_SYS_ADMIN,
953                         "org.freedesktop.login1.lock-sessions",
954                         NULL,
955                         false,
956                         UID_INVALID,
957                         &m->polkit_registry,
958                         error);
959         if (r < 0)
960                 return r;
961         if (r == 0)
962                 return 1; /* Will call us back */
963
964         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
965         if (r < 0)
966                 return r;
967
968         return sd_bus_reply_method_return(message, NULL);
969 }
970
971 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
972         const char *name;
973         Manager *m = userdata;
974         Session *session;
975         int r;
976
977         assert(message);
978         assert(m);
979
980         r = sd_bus_message_read(message, "s", &name);
981         if (r < 0)
982                 return r;
983
984         r = manager_get_session_from_creds(m, message, name, error, &session);
985         if (r < 0)
986                 return r;
987
988         return bus_session_method_kill(message, session, error);
989 }
990
991 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
992         Manager *m = userdata;
993         uint32_t uid;
994         User *user;
995         int r;
996
997         assert(message);
998         assert(m);
999
1000         r = sd_bus_message_read(message, "u", &uid);
1001         if (r < 0)
1002                 return r;
1003
1004         r = manager_get_user_from_creds(m, message, uid, error, &user);
1005         if (r < 0)
1006                 return r;
1007
1008         return bus_user_method_kill(message, user, error);
1009 }
1010
1011 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1012         Manager *m = userdata;
1013         const char *name;
1014         Session *session;
1015         int r;
1016
1017         assert(message);
1018         assert(m);
1019
1020         r = sd_bus_message_read(message, "s", &name);
1021         if (r < 0)
1022                 return r;
1023
1024         r = manager_get_session_from_creds(m, message, name, error, &session);
1025         if (r < 0)
1026                 return r;
1027
1028         return bus_session_method_terminate(message, session, error);
1029 }
1030
1031 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1032         Manager *m = userdata;
1033         uint32_t uid;
1034         User *user;
1035         int r;
1036
1037         assert(message);
1038         assert(m);
1039
1040         r = sd_bus_message_read(message, "u", &uid);
1041         if (r < 0)
1042                 return r;
1043
1044         r = manager_get_user_from_creds(m, message, uid, error, &user);
1045         if (r < 0)
1046                 return r;
1047
1048         return bus_user_method_terminate(message, user, error);
1049 }
1050
1051 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1052         Manager *m = userdata;
1053         const char *name;
1054         Seat *seat;
1055         int r;
1056
1057         assert(message);
1058         assert(m);
1059
1060         r = sd_bus_message_read(message, "s", &name);
1061         if (r < 0)
1062                 return r;
1063
1064         r = manager_get_seat_from_creds(m, message, name, error, &seat);
1065         if (r < 0)
1066                 return r;
1067
1068         return bus_seat_method_terminate(message, seat, error);
1069 }
1070
1071 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1072         _cleanup_free_ char *cc = NULL;
1073         Manager *m = userdata;
1074         int b, r;
1075         struct passwd *pw;
1076         const char *path;
1077         uint32_t uid;
1078         int interactive;
1079
1080         assert(message);
1081         assert(m);
1082
1083         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1084         if (r < 0)
1085                 return r;
1086
1087         if (uid == UID_INVALID) {
1088                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1089
1090                 /* Note that we get the owner UID of the session, not the actual client UID here! */
1091                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1092                 if (r < 0)
1093                         return r;
1094
1095                 r = sd_bus_creds_get_owner_uid(creds, &uid);
1096                 if (r < 0)
1097                         return r;
1098         }
1099
1100         errno = 0;
1101         pw = getpwuid(uid);
1102         if (!pw)
1103                 return errno ? -errno : -ENOENT;
1104
1105         r = bus_verify_polkit_async(
1106                         message,
1107                         CAP_SYS_ADMIN,
1108                         "org.freedesktop.login1.set-user-linger",
1109                         NULL,
1110                         interactive,
1111                         UID_INVALID,
1112                         &m->polkit_registry,
1113                         error);
1114         if (r < 0)
1115                 return r;
1116         if (r == 0)
1117                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1118
1119         mkdir_p_label("/var/lib/systemd", 0755);
1120
1121         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1122         if (r < 0)
1123                 return r;
1124
1125         cc = cescape(pw->pw_name);
1126         if (!cc)
1127                 return -ENOMEM;
1128
1129         path = strjoina("/var/lib/systemd/linger/", cc);
1130         if (b) {
1131                 User *u;
1132
1133                 r = touch(path);
1134                 if (r < 0)
1135                         return r;
1136
1137                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1138                         user_start(u);
1139
1140         } else {
1141                 User *u;
1142
1143                 r = unlink(path);
1144                 if (r < 0 && errno != ENOENT)
1145                         return -errno;
1146
1147                 u = hashmap_get(m->users, UID_TO_PTR(uid));
1148                 if (u)
1149                         user_add_to_gc_queue(u);
1150         }
1151
1152         return sd_bus_reply_method_return(message, NULL);
1153 }
1154
1155 static int trigger_device(Manager *m, struct udev_device *d) {
1156         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1157         struct udev_list_entry *first, *item;
1158         int r;
1159
1160         assert(m);
1161
1162         e = udev_enumerate_new(m->udev);
1163         if (!e)
1164                 return -ENOMEM;
1165
1166         if (d) {
1167                 r = udev_enumerate_add_match_parent(e, d);
1168                 if (r < 0)
1169                         return r;
1170         }
1171
1172         r = udev_enumerate_scan_devices(e);
1173         if (r < 0)
1174                 return r;
1175
1176         first = udev_enumerate_get_list_entry(e);
1177         udev_list_entry_foreach(item, first) {
1178                 _cleanup_free_ char *t = NULL;
1179                 const char *p;
1180
1181                 p = udev_list_entry_get_name(item);
1182
1183                 t = strappend(p, "/uevent");
1184                 if (!t)
1185                         return -ENOMEM;
1186
1187                 write_string_file(t, "change");
1188         }
1189
1190         return 0;
1191 }
1192
1193 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1194         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1195         _cleanup_free_ char *rule = NULL, *file = NULL;
1196         const char *id_for_seat;
1197         int r;
1198
1199         assert(m);
1200         assert(seat);
1201         assert(sysfs);
1202
1203         d = udev_device_new_from_syspath(m->udev, sysfs);
1204         if (!d)
1205                 return -ENODEV;
1206
1207         if (!udev_device_has_tag(d, "seat"))
1208                 return -ENODEV;
1209
1210         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1211         if (!id_for_seat)
1212                 return -ENODEV;
1213
1214         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1215                 return -ENOMEM;
1216
1217         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1218                 return -ENOMEM;
1219
1220         mkdir_p_label("/etc/udev/rules.d", 0755);
1221         mac_selinux_init("/etc");
1222         r = write_string_file_atomic_label(file, rule);
1223         if (r < 0)
1224                 return r;
1225
1226         return trigger_device(m, d);
1227 }
1228
1229 static int flush_devices(Manager *m) {
1230         _cleanup_closedir_ DIR *d;
1231
1232         assert(m);
1233
1234         d = opendir("/etc/udev/rules.d");
1235         if (!d) {
1236                 if (errno != ENOENT)
1237                         log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1238         } else {
1239                 struct dirent *de;
1240
1241                 while ((de = readdir(d))) {
1242
1243                         if (!dirent_is_file(de))
1244                                 continue;
1245
1246                         if (!startswith(de->d_name, "72-seat-"))
1247                                 continue;
1248
1249                         if (!endswith(de->d_name, ".rules"))
1250                                 continue;
1251
1252                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1253                                 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1254                 }
1255         }
1256
1257         return trigger_device(m, NULL);
1258 }
1259
1260 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261         const char *sysfs, *seat;
1262         Manager *m = userdata;
1263         int interactive, r;
1264
1265         assert(message);
1266         assert(m);
1267
1268         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1269         if (r < 0)
1270                 return r;
1271
1272         if (!path_startswith(sysfs, "/sys"))
1273                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1274
1275         if (!seat_name_is_valid(seat))
1276                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1277
1278         r = bus_verify_polkit_async(
1279                         message,
1280                         CAP_SYS_ADMIN,
1281                         "org.freedesktop.login1.attach-device",
1282                         NULL,
1283                         interactive,
1284                         UID_INVALID,
1285                         &m->polkit_registry,
1286                         error);
1287         if (r < 0)
1288                 return r;
1289         if (r == 0)
1290                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1291
1292         r = attach_device(m, seat, sysfs);
1293         if (r < 0)
1294                 return r;
1295
1296         return sd_bus_reply_method_return(message, NULL);
1297 }
1298
1299 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1300         Manager *m = userdata;
1301         int interactive, r;
1302
1303         assert(message);
1304         assert(m);
1305
1306         r = sd_bus_message_read(message, "b", &interactive);
1307         if (r < 0)
1308                 return r;
1309
1310         r = bus_verify_polkit_async(
1311                         message,
1312                         CAP_SYS_ADMIN,
1313                         "org.freedesktop.login1.flush-devices",
1314                         NULL,
1315                         interactive,
1316                         UID_INVALID,
1317                         &m->polkit_registry,
1318                         error);
1319         if (r < 0)
1320                 return r;
1321         if (r == 0)
1322                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1323
1324         r = flush_devices(m);
1325         if (r < 0)
1326                 return r;
1327
1328         return sd_bus_reply_method_return(message, NULL);
1329 }
1330
1331 static int have_multiple_sessions(
1332                 Manager *m,
1333                 uid_t uid) {
1334
1335         Session *session;
1336         Iterator i;
1337
1338         assert(m);
1339
1340         /* Check for other users' sessions. Greeter sessions do not
1341          * count, and non-login sessions do not count either. */
1342         HASHMAP_FOREACH(session, m->sessions, i)
1343                 if (session->class == SESSION_USER &&
1344                     session->user->uid != uid)
1345                         return true;
1346
1347         return false;
1348 }
1349
1350 static int bus_manager_log_shutdown(
1351                 Manager *m,
1352                 InhibitWhat w,
1353                 HandleAction action) {
1354
1355         const char *p, *q;
1356
1357         assert(m);
1358
1359         if (w != INHIBIT_SHUTDOWN)
1360                 return 0;
1361
1362         switch (action) {
1363         case HANDLE_POWEROFF:
1364                 p = "MESSAGE=System is powering down.";
1365                 q = "SHUTDOWN=power-off";
1366                 break;
1367         case HANDLE_HALT:
1368                 p = "MESSAGE=System is halting.";
1369                 q = "SHUTDOWN=halt";
1370                 break;
1371         case HANDLE_REBOOT:
1372                 p = "MESSAGE=System is rebooting.";
1373                 q = "SHUTDOWN=reboot";
1374                 break;
1375         case HANDLE_KEXEC:
1376                 p = "MESSAGE=System is rebooting with kexec.";
1377                 q = "SHUTDOWN=kexec";
1378                 break;
1379         default:
1380                 p = "MESSAGE=System is shutting down.";
1381                 q = NULL;
1382         }
1383
1384         if (!isempty(m->wall_message))
1385                 p = strjoina(p, " (", m->wall_message, ")");
1386
1387         return log_struct(LOG_NOTICE,
1388                           LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1389                           p,
1390                           q,
1391                           NULL);
1392 }
1393
1394 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1395         Manager *m = userdata;
1396
1397         assert(e);
1398         assert(m);
1399
1400         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1401         return 0;
1402 }
1403
1404 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1405         int r;
1406
1407         assert(m);
1408
1409         if (until <= now(CLOCK_MONOTONIC))
1410                 return 0;
1411
1412         /* We want to ignore the lid switch for a while after each
1413          * suspend, and after boot-up. Hence let's install a timer for
1414          * this. As long as the event source exists we ignore the lid
1415          * switch. */
1416
1417         if (m->lid_switch_ignore_event_source) {
1418                 usec_t u;
1419
1420                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1421                 if (r < 0)
1422                         return r;
1423
1424                 if (until <= u)
1425                         return 0;
1426
1427                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1428         } else
1429                 r = sd_event_add_time(
1430                                 m->event,
1431                                 &m->lid_switch_ignore_event_source,
1432                                 CLOCK_MONOTONIC,
1433                                 until, 0,
1434                                 lid_switch_ignore_handler, m);
1435
1436         return r;
1437 }
1438
1439 static int execute_shutdown_or_sleep(
1440                 Manager *m,
1441                 InhibitWhat w,
1442                 HandleAction action,
1443                 sd_bus_error *error) {
1444
1445 /// elogind does not need these, we do it ourselves
1446 #if 0
1447         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1448         const char *p;
1449         char *c;
1450 #endif // 0
1451         int r;
1452
1453         assert(m);
1454         assert(w >= 0);
1455         assert(w < _INHIBIT_WHAT_MAX);
1456
1457         bus_manager_log_shutdown(m, w, action);
1458
1459 /// elogind does it directly without depending on systemd running the system
1460 #if 0
1461         r = sd_bus_call_method(
1462                         m->bus,
1463                         "org.freedesktop.systemd1",
1464                         "/org/freedesktop/systemd1",
1465                         "org.freedesktop.systemd1.Manager",
1466                         "StartUnit",
1467                         error,
1468                         &reply,
1469                         "ss", NULL, "replace-irreversibly");
1470 #else
1471         r = shutdown_or_sleep(m, action);
1472 #endif // 0
1473         if (r < 0)
1474                 return r;
1475
1476 /// elogind neither needs a dbus reply, nor supports systemd action jobs
1477 #if 0
1478         r = sd_bus_message_read(reply, "o", &p);
1479         if (r < 0)
1480                 return r;
1481
1482         c = strdup(p);
1483         if (!c)
1484                 return -ENOMEM;
1485
1486         m->action_unit = unit_name;
1487         free(m->action_job);
1488         m->action_job = c;
1489         m->action_what = w;
1490 #endif // 0
1491
1492         /* Make sure the lid switch is ignored for a while */
1493         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1494
1495         return 0;
1496 }
1497
1498 static int manager_inhibit_timeout_handler(
1499                         sd_event_source *s,
1500                         uint64_t usec,
1501                         void *userdata) {
1502
1503         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1504         Inhibitor *offending = NULL;
1505         Manager *manager = userdata;
1506         int r;
1507
1508         assert(manager);
1509         assert(manager->inhibit_timeout_source == s);
1510
1511         if (manager->action_what == 0)
1512                 return 0;
1513
1514         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1515                 _cleanup_free_ char *comm = NULL, *u = NULL;
1516
1517                 (void) get_process_comm(offending->pid, &comm);
1518                 u = uid_to_name(offending->uid);
1519
1520                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1521                            offending->uid, strna(u),
1522                            offending->pid, strna(comm));
1523         }
1524
1525         /* Actually do the operation */
1526         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
1527         if (r < 0) {
1528                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1529
1530                 manager->pending_action = HANDLE_IGNORE;
1531                 manager->action_what    = 0;
1532         }
1533
1534         return 0;
1535 }
1536
1537 static int delay_shutdown_or_sleep(
1538                 Manager *m,
1539                 InhibitWhat w,
1540                 HandleAction action) {
1541
1542         int r;
1543         usec_t timeout_val;
1544
1545         assert(m);
1546         assert(w >= 0);
1547         assert(w < _INHIBIT_WHAT_MAX);
1548
1549         timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1550
1551         if (m->inhibit_timeout_source) {
1552                 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1553                 if (r < 0)
1554                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1555
1556                 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1557                 if (r < 0)
1558                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1559         } else {
1560                 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1561                                       timeout_val, 0, manager_inhibit_timeout_handler, m);
1562                 if (r < 0)
1563                         return r;
1564         }
1565
1566         m->pending_action = action;
1567         m->action_what = w;
1568
1569         return 0;
1570 }
1571
1572 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1573
1574         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1575                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1576                 [INHIBIT_SLEEP] = "PrepareForSleep"
1577         };
1578
1579         int active = _active;
1580
1581         assert(m);
1582         assert(w >= 0);
1583         assert(w < _INHIBIT_WHAT_MAX);
1584         assert(signal_name[w]);
1585
1586         return sd_bus_emit_signal(m->bus,
1587                                   "/org/freedesktop/login1",
1588                                   "org.freedesktop.login1.Manager",
1589                                   signal_name[w],
1590                                   "b",
1591                                   active);
1592 }
1593
1594 int bus_manager_shutdown_or_sleep_now_or_later(
1595                 Manager *m,
1596                 HandleAction action,
1597                 InhibitWhat w,
1598                 sd_bus_error *error) {
1599
1600         bool delayed;
1601         int r;
1602
1603         assert(m);
1604         assert(w >= 0);
1605         assert(w <= _INHIBIT_WHAT_MAX);
1606
1607         /* Tell everybody to prepare for shutdown/sleep */
1608         send_prepare_for(m, w, true);
1609
1610         delayed =
1611                 m->inhibit_delay_max > 0 &&
1612                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1613
1614         if (delayed)
1615                 /* Shutdown is delayed, keep in mind what we
1616                  * want to do, and start a timeout */
1617                 r = delay_shutdown_or_sleep(m, w, action);
1618         else
1619                 /* Shutdown is not delayed, execute it
1620                  * immediately */
1621                 r = execute_shutdown_or_sleep(m, w, action, error);
1622
1623         return r;
1624 }
1625
1626 static int verify_shutdown_creds(
1627                 Manager *m,
1628                 sd_bus_message *message,
1629                 InhibitWhat w,
1630                 bool interactive,
1631                 const char *action,
1632                 const char *action_multiple_sessions,
1633                 const char *action_ignore_inhibit,
1634                 sd_bus_error *error) {
1635
1636         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1637         bool multiple_sessions, blocked;
1638         uid_t uid;
1639         int r;
1640
1641         assert(m);
1642         assert(message);
1643         assert(w >= 0);
1644         assert(w <= _INHIBIT_WHAT_MAX);
1645
1646         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1647         if (r < 0)
1648                 return r;
1649
1650         r = sd_bus_creds_get_euid(creds, &uid);
1651         if (r < 0)
1652                 return r;
1653
1654         r = have_multiple_sessions(m, uid);
1655         if (r < 0)
1656                 return r;
1657
1658         multiple_sessions = r > 0;
1659         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1660
1661         if (multiple_sessions && action_multiple_sessions) {
1662                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1663                 if (r < 0)
1664                         return r;
1665                 if (r == 0)
1666                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1667         }
1668
1669         if (blocked && action_ignore_inhibit) {
1670                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1671                 if (r < 0)
1672                         return r;
1673                 if (r == 0)
1674                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1675         }
1676
1677         if (!multiple_sessions && !blocked && action) {
1678                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1679                 if (r < 0)
1680                         return r;
1681                 if (r == 0)
1682                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1683         }
1684
1685         return 0;
1686 }
1687
1688 static int method_do_shutdown_or_sleep(
1689                 Manager *m,
1690                 sd_bus_message *message,
1691                 HandleAction sleep_action,
1692                 InhibitWhat w,
1693                 const char *action,
1694                 const char *action_multiple_sessions,
1695                 const char *action_ignore_inhibit,
1696                 const char *sleep_verb,
1697                 sd_bus_error *error) {
1698
1699         int interactive, r;
1700
1701         assert(m);
1702         assert(message);
1703         assert(w >= 0);
1704         assert(w <= _INHIBIT_WHAT_MAX);
1705
1706         r = sd_bus_message_read(message, "b", &interactive);
1707         if (r < 0)
1708                 return r;
1709
1710         /* Don't allow multiple jobs being executed at the same time */
1711         if (m->action_what)
1712                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1713
1714         if (sleep_verb) {
1715                 r = can_sleep(sleep_verb);
1716                 if (r < 0)
1717                         return r;
1718
1719                 if (r == 0)
1720                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1721         }
1722
1723         r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1724                                   action_ignore_inhibit, error);
1725         if (r != 0)
1726                 return r;
1727
1728         r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1729         if (r < 0)
1730                 return r;
1731
1732         return sd_bus_reply_method_return(message, NULL);
1733 }
1734
1735 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1736         Manager *m = userdata;
1737
1738         return method_do_shutdown_or_sleep(
1739                         m, message,
1740                         HANDLE_POWEROFF,
1741                         INHIBIT_SHUTDOWN,
1742                         "org.freedesktop.login1.power-off",
1743                         "org.freedesktop.login1.power-off-multiple-sessions",
1744                         "org.freedesktop.login1.power-off-ignore-inhibit",
1745                         NULL,
1746                         error);
1747 }
1748
1749 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1750         Manager *m = userdata;
1751
1752         return method_do_shutdown_or_sleep(
1753                         m, message,
1754                         HANDLE_REBOOT,
1755                         INHIBIT_SHUTDOWN,
1756                         "org.freedesktop.login1.reboot",
1757                         "org.freedesktop.login1.reboot-multiple-sessions",
1758                         "org.freedesktop.login1.reboot-ignore-inhibit",
1759                         NULL,
1760                         error);
1761 }
1762
1763 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1764         Manager *m = userdata;
1765
1766         return method_do_shutdown_or_sleep(
1767                         m, message,
1768                         HANDLE_SUSPEND,
1769                         INHIBIT_SLEEP,
1770                         "org.freedesktop.login1.suspend",
1771                         "org.freedesktop.login1.suspend-multiple-sessions",
1772                         "org.freedesktop.login1.suspend-ignore-inhibit",
1773                         "suspend",
1774                         error);
1775 }
1776
1777 static int nologin_timeout_handler(
1778                         sd_event_source *s,
1779                         uint64_t usec,
1780                         void *userdata) {
1781
1782         Manager *m = userdata;
1783         int r;
1784
1785         log_info("Creating /run/nologin, blocking further logins...");
1786
1787         r = write_string_file_atomic("/run/nologin", "System is going down.");
1788         if (r < 0)
1789                 log_error_errno(r, "Failed to create /run/nologin: %m");
1790         else
1791                 m->unlink_nologin = true;
1792
1793         return 0;
1794 }
1795
1796 static int update_schedule_file(Manager *m) {
1797         _cleanup_free_ char *temp_path = NULL;
1798         _cleanup_fclose_ FILE *f = NULL;
1799         int r;
1800
1801         assert(m);
1802
1803         r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1804         if (r < 0)
1805                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1806
1807         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1808         if (r < 0)
1809                 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1810
1811         (void) fchmod(fileno(f), 0644);
1812
1813         fprintf(f,
1814                 "USEC="USEC_FMT"\n"
1815                 "WARN_WALL=%i\n"
1816                 "MODE=%s\n",
1817                 m->scheduled_shutdown_timeout,
1818                 m->enable_wall_messages,
1819                 m->scheduled_shutdown_type);
1820
1821         if (!isempty(m->wall_message)) {
1822                 _cleanup_free_ char *t;
1823
1824                 t = cescape(m->wall_message);
1825                 if (!t) {
1826                         r = -ENOMEM;
1827                         goto fail;
1828                 }
1829
1830                 fprintf(f, "WALL_MESSAGE=%s\n", t);
1831         }
1832
1833         r = fflush_and_check(f);
1834         if (r < 0)
1835                 goto fail;
1836
1837         if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1838                 r = -errno;
1839                 goto fail;
1840         }
1841
1842         return 0;
1843
1844 fail:
1845                 (void) unlink(temp_path);
1846                 (void) unlink("/run/systemd/shutdown/scheduled");
1847
1848         return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1849 }
1850
1851 static int manager_scheduled_shutdown_handler(
1852                         sd_event_source *s,
1853                         uint64_t usec,
1854                         void *userdata) {
1855
1856         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1857         Manager *m = userdata;
1858         HandleAction action;
1859         int r;
1860
1861         assert(m);
1862
1863         if (isempty(m->scheduled_shutdown_type))
1864                 return 0;
1865
1866         if (streq(m->scheduled_shutdown_type, "halt"))
1867                 action = HANDLE_HALT;
1868         else if (streq(m->scheduled_shutdown_type, "poweroff"))
1869                 action = HANDLE_POWEROFF;
1870         else
1871                 action = HANDLE_REBOOT;
1872
1873         r = execute_shutdown_or_sleep(m, 0, action, &error);
1874         if (r < 0)
1875                 return log_error_errno(r, "Unable to execute transition to %s: %m", m->scheduled_shutdown_type);
1876
1877         return 0;
1878 }
1879
1880 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1881         Manager *m = userdata;
1882         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1883         const char *action_multiple_sessions = NULL;
1884         const char *action_ignore_inhibit = NULL;
1885         const char *action = NULL;
1886         uint64_t elapse;
1887         char *type;
1888         int r;
1889
1890         assert(m);
1891         assert(message);
1892
1893         r = sd_bus_message_read(message, "st", &type, &elapse);
1894         if (r < 0)
1895                 return r;
1896
1897         if (streq(type, "reboot")) {
1898                 action = "org.freedesktop.login1.reboot";
1899                 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
1900                 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
1901         } else if (streq(type, "halt")) {
1902                 action = "org.freedesktop.login1.halt";
1903                 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
1904                 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
1905         } else if (streq(type, "poweroff")) {
1906                 action = "org.freedesktop.login1.poweroff";
1907                 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
1908                 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
1909         } else
1910                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
1911
1912         r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
1913                                   action, action_multiple_sessions, action_ignore_inhibit, error);
1914         if (r != 0)
1915                 return r;
1916
1917         if (m->scheduled_shutdown_timeout_source) {
1918                 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
1919                 if (r < 0)
1920                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1921
1922                 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
1923                 if (r < 0)
1924                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1925         } else {
1926                 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
1927                                       CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
1928                 if (r < 0)
1929                         return log_error_errno(r, "sd_event_add_time() failed: %m");
1930         }
1931
1932         r = free_and_strdup(&m->scheduled_shutdown_type, type);
1933         if (r < 0) {
1934                 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1935                 return log_oom();
1936         }
1937
1938         if (m->nologin_timeout_source) {
1939                 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
1940                 if (r < 0)
1941                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1942
1943                 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
1944                 if (r < 0)
1945                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1946         } else {
1947                 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
1948                                       CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
1949                 if (r < 0)
1950                         return log_error_errno(r, "sd_event_add_time() failed: %m");
1951         }
1952
1953         m->scheduled_shutdown_timeout = elapse;
1954
1955         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
1956         if (r >= 0) {
1957                 const char *tty;
1958
1959                 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
1960                 (void) sd_bus_creds_get_tty(creds, &tty);
1961
1962                 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
1963                 if (r < 0) {
1964                         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1965                         return log_oom();
1966                 }
1967         }
1968
1969         r = manager_setup_wall_message_timer(m);
1970         if (r < 0)
1971                 return r;
1972
1973         if (!isempty(type)) {
1974                 r = update_schedule_file(m);
1975                 if (r < 0)
1976                         return r;
1977         } else
1978                 (void) unlink("/run/systemd/shutdown/scheduled");
1979
1980         return sd_bus_reply_method_return(message, NULL);
1981 }
1982
1983 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1984         Manager *m = userdata;
1985         bool cancelled;
1986
1987         assert(m);
1988         assert(message);
1989
1990         cancelled = m->scheduled_shutdown_type != NULL;
1991
1992         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1993         m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1994         m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1995         free(m->scheduled_shutdown_type);
1996         m->scheduled_shutdown_type = NULL;
1997         m->scheduled_shutdown_timeout = 0;
1998
1999         if (cancelled) {
2000                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2001                 const char *tty = NULL;
2002                 uid_t uid = 0;
2003                 int r;
2004
2005                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2006                 if (r >= 0) {
2007                         (void) sd_bus_creds_get_uid(creds, &uid);
2008                         (void) sd_bus_creds_get_tty(creds, &tty);
2009                 }
2010
2011                 utmp_wall("The system shutdown has been cancelled",
2012                           lookup_uid(uid), tty, logind_wall_tty_filter, m);
2013         }
2014
2015         return sd_bus_reply_method_return(message, "b", cancelled);
2016 }
2017
2018 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2019         Manager *m = userdata;
2020
2021         return method_do_shutdown_or_sleep(
2022                         m, message,
2023                         HANDLE_HIBERNATE,
2024                         INHIBIT_SLEEP,
2025                         "org.freedesktop.login1.hibernate",
2026                         "org.freedesktop.login1.hibernate-multiple-sessions",
2027                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2028                         "hibernate",
2029                         error);
2030 }
2031
2032 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2033         Manager *m = userdata;
2034
2035         return method_do_shutdown_or_sleep(
2036                         m, message,
2037                         HANDLE_HYBRID_SLEEP,
2038                         INHIBIT_SLEEP,
2039                         "org.freedesktop.login1.hibernate",
2040                         "org.freedesktop.login1.hibernate-multiple-sessions",
2041                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2042                         "hybrid-sleep",
2043                         error);
2044 }
2045
2046 static int method_can_shutdown_or_sleep(
2047                 Manager *m,
2048                 sd_bus_message *message,
2049                 InhibitWhat w,
2050                 const char *action,
2051                 const char *action_multiple_sessions,
2052                 const char *action_ignore_inhibit,
2053                 const char *sleep_verb,
2054                 sd_bus_error *error) {
2055
2056         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2057         bool multiple_sessions, challenge, blocked;
2058         const char *result = NULL;
2059         uid_t uid;
2060         int r;
2061
2062         assert(m);
2063         assert(message);
2064         assert(w >= 0);
2065         assert(w <= _INHIBIT_WHAT_MAX);
2066         assert(action);
2067         assert(action_multiple_sessions);
2068         assert(action_ignore_inhibit);
2069
2070         if (sleep_verb) {
2071                 r = can_sleep(sleep_verb);
2072                 if (r < 0)
2073                         return r;
2074                 if (r == 0)
2075                         return sd_bus_reply_method_return(message, "s", "na");
2076         }
2077
2078         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2079         if (r < 0)
2080                 return r;
2081
2082         r = sd_bus_creds_get_euid(creds, &uid);
2083         if (r < 0)
2084                 return r;
2085
2086         r = have_multiple_sessions(m, uid);
2087         if (r < 0)
2088                 return r;
2089
2090         multiple_sessions = r > 0;
2091         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2092
2093         if (multiple_sessions) {
2094                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2095                 if (r < 0)
2096                         return r;
2097
2098                 if (r > 0)
2099                         result = "yes";
2100                 else if (challenge)
2101                         result = "challenge";
2102                 else
2103                         result = "no";
2104         }
2105
2106         if (blocked) {
2107                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2108                 if (r < 0)
2109                         return r;
2110
2111                 if (r > 0 && !result)
2112                         result = "yes";
2113                 else if (challenge && (!result || streq(result, "yes")))
2114                         result = "challenge";
2115                 else
2116                         result = "no";
2117         }
2118
2119         if (!multiple_sessions && !blocked) {
2120                 /* If neither inhibit nor multiple sessions
2121                  * apply then just check the normal policy */
2122
2123                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2124                 if (r < 0)
2125                         return r;
2126
2127                 if (r > 0)
2128                         result = "yes";
2129                 else if (challenge)
2130                         result = "challenge";
2131                 else
2132                         result = "no";
2133         }
2134
2135         return sd_bus_reply_method_return(message, "s", result);
2136 }
2137
2138 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2139         Manager *m = userdata;
2140
2141         return method_can_shutdown_or_sleep(
2142                         m, message,
2143                         INHIBIT_SHUTDOWN,
2144                         "org.freedesktop.login1.power-off",
2145                         "org.freedesktop.login1.power-off-multiple-sessions",
2146                         "org.freedesktop.login1.power-off-ignore-inhibit",
2147                         NULL,
2148                         error);
2149 }
2150
2151 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2152         Manager *m = userdata;
2153
2154         return method_can_shutdown_or_sleep(
2155                         m, message,
2156                         INHIBIT_SHUTDOWN,
2157                         "org.freedesktop.login1.reboot",
2158                         "org.freedesktop.login1.reboot-multiple-sessions",
2159                         "org.freedesktop.login1.reboot-ignore-inhibit",
2160                         NULL,
2161                         error);
2162 }
2163
2164 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2165         Manager *m = userdata;
2166
2167         return method_can_shutdown_or_sleep(
2168                         m, message,
2169                         INHIBIT_SLEEP,
2170                         "org.freedesktop.login1.suspend",
2171                         "org.freedesktop.login1.suspend-multiple-sessions",
2172                         "org.freedesktop.login1.suspend-ignore-inhibit",
2173                         "suspend",
2174                         error);
2175 }
2176
2177 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2178         Manager *m = userdata;
2179
2180         return method_can_shutdown_or_sleep(
2181                         m, message,
2182                         INHIBIT_SLEEP,
2183                         "org.freedesktop.login1.hibernate",
2184                         "org.freedesktop.login1.hibernate-multiple-sessions",
2185                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2186                         "hibernate",
2187                         error);
2188 }
2189
2190 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2191         Manager *m = userdata;
2192
2193         return method_can_shutdown_or_sleep(
2194                         m, message,
2195                         INHIBIT_SLEEP,
2196                         "org.freedesktop.login1.hibernate",
2197                         "org.freedesktop.login1.hibernate-multiple-sessions",
2198                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2199                         "hybrid-sleep",
2200                         error);
2201 }
2202
2203 static int property_get_reboot_to_firmware_setup(
2204                 sd_bus *bus,
2205                 const char *path,
2206                 const char *interface,
2207                 const char *property,
2208                 sd_bus_message *reply,
2209                 void *userdata,
2210                 sd_bus_error *error) {
2211         int r;
2212
2213         assert(bus);
2214         assert(reply);
2215         assert(userdata);
2216
2217         r = efi_get_reboot_to_firmware();
2218         if (r < 0 && r != -EOPNOTSUPP)
2219                 return r;
2220
2221         return sd_bus_message_append(reply, "b", r > 0);
2222 }
2223
2224 static int method_set_reboot_to_firmware_setup(
2225                 sd_bus_message *message,
2226                 void *userdata,
2227                 sd_bus_error *error) {
2228
2229         int b, r;
2230         Manager *m = userdata;
2231
2232         assert(message);
2233         assert(m);
2234
2235         r = sd_bus_message_read(message, "b", &b);
2236         if (r < 0)
2237                 return r;
2238
2239         r = bus_verify_polkit_async(message,
2240                                     CAP_SYS_ADMIN,
2241                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
2242                                     NULL,
2243                                     false,
2244                                     UID_INVALID,
2245                                     &m->polkit_registry,
2246                                     error);
2247         if (r < 0)
2248                 return r;
2249         if (r == 0)
2250                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2251
2252         r = efi_set_reboot_to_firmware(b);
2253         if (r < 0)
2254                 return r;
2255
2256         return sd_bus_reply_method_return(message, NULL);
2257 }
2258
2259 static int method_can_reboot_to_firmware_setup(
2260                 sd_bus_message *message,
2261                 void *userdata,
2262                 sd_bus_error *error) {
2263
2264         int r;
2265         bool challenge;
2266         const char *result;
2267         Manager *m = userdata;
2268
2269         assert(message);
2270         assert(m);
2271
2272         r = efi_reboot_to_firmware_supported();
2273         if (r == -EOPNOTSUPP)
2274                 return sd_bus_reply_method_return(message, "s", "na");
2275         else if (r < 0)
2276                 return r;
2277
2278         r = bus_test_polkit(message,
2279                             CAP_SYS_ADMIN,
2280                             "org.freedesktop.login1.set-reboot-to-firmware-setup",
2281                             NULL,
2282                             UID_INVALID,
2283                             &challenge,
2284                             error);
2285         if (r < 0)
2286                 return r;
2287
2288         if (r > 0)
2289                 result = "yes";
2290         else if (challenge)
2291                 result = "challenge";
2292         else
2293                 result = "no";
2294
2295         return sd_bus_reply_method_return(message, "s", result);
2296 }
2297
2298 static int method_set_wall_message(
2299                 sd_bus_message *message,
2300                 void *userdata,
2301                 sd_bus_error *error) {
2302
2303         int r;
2304         Manager *m = userdata;
2305         char *wall_message;
2306         int enable_wall_messages;
2307
2308         assert(message);
2309         assert(m);
2310
2311         r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2312         if (r < 0)
2313                 return r;
2314
2315         r = bus_verify_polkit_async(message,
2316                                     CAP_SYS_ADMIN,
2317                                     "org.freedesktop.login1.set-wall-message",
2318                                     NULL,
2319                                     false,
2320                                     UID_INVALID,
2321                                     &m->polkit_registry,
2322                                     error);
2323         if (r < 0)
2324                 return r;
2325         if (r == 0)
2326                 return 1; /* Will call us back */
2327
2328         if (isempty(wall_message))
2329                 m->wall_message = mfree(m->wall_message);
2330         else {
2331                 r = free_and_strdup(&m->wall_message, wall_message);
2332                 if (r < 0)
2333                         return log_oom();
2334         }
2335
2336         m->enable_wall_messages = enable_wall_messages;
2337
2338         return sd_bus_reply_method_return(message, NULL);
2339 }
2340
2341 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2342         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2343         const char *who, *why, *what, *mode;
2344         _cleanup_free_ char *id = NULL;
2345         _cleanup_close_ int fifo_fd = -1;
2346         Manager *m = userdata;
2347         Inhibitor *i = NULL;
2348         InhibitMode mm;
2349         InhibitWhat w;
2350         pid_t pid;
2351         uid_t uid;
2352         int r;
2353
2354         assert(message);
2355         assert(m);
2356
2357         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2358         if (r < 0)
2359                 return r;
2360
2361         w = inhibit_what_from_string(what);
2362         if (w <= 0)
2363                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2364
2365         mm = inhibit_mode_from_string(mode);
2366         if (mm < 0)
2367                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2368
2369         /* Delay is only supported for shutdown/sleep */
2370         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2371                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2372
2373         /* Don't allow taking delay locks while we are already
2374          * executing the operation. We shouldn't create the impression
2375          * that the lock was successful if the machine is about to go
2376          * down/suspend any moment. */
2377         if (m->action_what & w)
2378                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2379
2380         r = bus_verify_polkit_async(
2381                         message,
2382                         CAP_SYS_BOOT,
2383                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2384                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
2385                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
2386                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
2387                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2388                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2389                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
2390                         NULL,
2391                         false,
2392                         UID_INVALID,
2393                         &m->polkit_registry,
2394                         error);
2395         if (r < 0)
2396                 return r;
2397         if (r == 0)
2398                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2399
2400         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2401         if (r < 0)
2402                 return r;
2403
2404         r = sd_bus_creds_get_euid(creds, &uid);
2405         if (r < 0)
2406                 return r;
2407
2408         r = sd_bus_creds_get_pid(creds, &pid);
2409         if (r < 0)
2410                 return r;
2411
2412         do {
2413                 id = mfree(id);
2414
2415                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2416                         return -ENOMEM;
2417
2418         } while (hashmap_get(m->inhibitors, id));
2419
2420         r = manager_add_inhibitor(m, id, &i);
2421         if (r < 0)
2422                 return r;
2423
2424         i->what = w;
2425         i->mode = mm;
2426         i->pid = pid;
2427         i->uid = uid;
2428         i->why = strdup(why);
2429         i->who = strdup(who);
2430
2431         if (!i->why || !i->who) {
2432                 r = -ENOMEM;
2433                 goto fail;
2434         }
2435
2436         fifo_fd = inhibitor_create_fifo(i);
2437         if (fifo_fd < 0) {
2438                 r = fifo_fd;
2439                 goto fail;
2440         }
2441
2442         inhibitor_start(i);
2443
2444         return sd_bus_reply_method_return(message, "h", fifo_fd);
2445
2446 fail:
2447         if (i)
2448                 inhibitor_free(i);
2449
2450         return r;
2451 }
2452
2453 const sd_bus_vtable manager_vtable[] = {
2454         SD_BUS_VTABLE_START(0),
2455
2456         SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2457         SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2458
2459 //        SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2460         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2461         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2462         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2463         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2464         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2465         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2466         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2467         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2468         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2469         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2470         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2471         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2472         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2473         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2474         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2475         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2476         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2477         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2478         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2479         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2480         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2481
2482         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2483         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2484         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2485         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2486         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2487         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2488         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2489         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2490         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2491         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2492         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2493         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2494         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2495         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2496         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2497         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2498         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2499         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2500         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2501         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2502         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2503         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2504         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2505         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2506         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2507         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2508         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2509         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2510         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2511         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2512         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2513         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2514         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2515         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2516         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2517         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2518         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2519         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2520         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2521         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2522         SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2523
2524         SD_BUS_SIGNAL("SessionNew", "so", 0),
2525         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2526         SD_BUS_SIGNAL("UserNew", "uo", 0),
2527         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2528         SD_BUS_SIGNAL("SeatNew", "so", 0),
2529         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2530         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2531         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2532
2533         SD_BUS_VTABLE_END
2534 };
2535
2536 /// UNNEEDED by elogind
2537 #if 0
2538 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2539         int r = 0;
2540
2541         assert(s);
2542         assert(unit);
2543
2544         if (!s->started)
2545                 return r;
2546
2547         if (streq(result, "done"))
2548                 r = session_send_create_reply(s, NULL);
2549         else {
2550                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2551
2552                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2553                 r = session_send_create_reply(s, &e);
2554         }
2555
2556         return r;
2557 }
2558
2559 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2560         const char *path, *result, *unit;
2561         Manager *m = userdata;
2562         Session *session;
2563         uint32_t id;
2564         User *user;
2565         int r;
2566
2567         assert(message);
2568         assert(m);
2569
2570         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2571         if (r < 0) {
2572                 bus_log_parse_error(r);
2573                 return 0;
2574         }
2575
2576         if (m->action_job && streq(m->action_job, path)) {
2577                 log_info("Operation finished.");
2578
2579                 /* Tell people that they now may take a lock again */
2580                 send_prepare_for(m, m->action_what, false);
2581
2582                 m->action_job = mfree(m->action_job);
2583                 m->action_unit = NULL;
2584                 m->action_what = 0;
2585                 return 0;
2586         }
2587
2588         session = hashmap_get(m->session_units, unit);
2589         if (session) {
2590
2591                 if (streq_ptr(path, session->scope_job))
2592                         session->scope_job = mfree(session->scope_job);
2593
2594                 session_jobs_reply(session, unit, result);
2595
2596                 session_save(session);
2597                 session_add_to_gc_queue(session);
2598         }
2599
2600         user = hashmap_get(m->user_units, unit);
2601         if (user) {
2602
2603                 if (streq_ptr(path, user->service_job))
2604                         user->service_job = mfree(user->service_job);
2605
2606                 if (streq_ptr(path, user->slice_job))
2607                         user->slice_job = mfree(user->slice_job);
2608
2609                 LIST_FOREACH(sessions_by_user, session, user->sessions)
2610                         session_jobs_reply(session, unit, result);
2611
2612                 user_save(user);
2613                 user_add_to_gc_queue(user);
2614         }
2615
2616         return 0;
2617 }
2618 #endif // 0
2619
2620 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2621         const char *path, *unit;
2622         Manager *m = userdata;
2623         Session *session;
2624         User *user;
2625         int r;
2626
2627         assert(message);
2628         assert(m);
2629
2630         r = sd_bus_message_read(message, "so", &unit, &path);
2631         if (r < 0) {
2632                 bus_log_parse_error(r);
2633                 return 0;
2634         }
2635
2636         session = hashmap_get(m->session_units, unit);
2637         if (session)
2638                 session_add_to_gc_queue(session);
2639
2640         user = hashmap_get(m->user_units, unit);
2641         if (user)
2642                 user_add_to_gc_queue(user);
2643
2644         return 0;
2645 }
2646
2647 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2648         _cleanup_free_ char *unit = NULL;
2649         Manager *m = userdata;
2650         const char *path;
2651         Session *session;
2652         User *user;
2653         int r;
2654
2655         assert(message);
2656         assert(m);
2657
2658         path = sd_bus_message_get_path(message);
2659         if (!path)
2660                 return 0;
2661
2662         r = unit_name_from_dbus_path(path, &unit);
2663         if (r == -EINVAL) /* not a unit */
2664                 return 0;
2665         if (r < 0) {
2666                 log_oom();
2667                 return 0;
2668         }
2669
2670         session = hashmap_get(m->session_units, unit);
2671         if (session)
2672                 session_add_to_gc_queue(session);
2673
2674         user = hashmap_get(m->user_units, unit);
2675         if (user)
2676                 user_add_to_gc_queue(user);
2677
2678         return 0;
2679 }
2680
2681 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2682         Manager *m = userdata;
2683         Session *session;
2684         Iterator i;
2685         int b, r;
2686
2687         assert(message);
2688         assert(m);
2689
2690         r = sd_bus_message_read(message, "b", &b);
2691         if (r < 0) {
2692                 bus_log_parse_error(r);
2693                 return 0;
2694         }
2695
2696         if (b)
2697                 return 0;
2698
2699         /* systemd finished reloading, let's recheck all our sessions */
2700         log_debug("System manager has been reloaded, rechecking sessions...");
2701
2702         HASHMAP_FOREACH(session, m->sessions, i)
2703                 session_add_to_gc_queue(session);
2704
2705         return 0;
2706 }
2707
2708 int manager_send_changed(Manager *manager, const char *property, ...) {
2709         char **l;
2710
2711         assert(manager);
2712
2713         l = strv_from_stdarg_alloca(property);
2714
2715         return sd_bus_emit_properties_changed_strv(
2716                         manager->bus,
2717                         "/org/freedesktop/login1",
2718                         "org.freedesktop.login1.Manager",
2719                         l);
2720 }
2721
2722 /// UNNEEDED by elogind
2723 #if 0
2724 int manager_start_scope(
2725                 Manager *manager,
2726                 const char *scope,
2727                 pid_t pid,
2728                 const char *slice,
2729                 const char *description,
2730                 const char *after, const char *after2,
2731                 sd_bus_error *error,
2732                 char **job) {
2733
2734         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2735         int r;
2736
2737         assert(manager);
2738         assert(scope);
2739         assert(pid > 1);
2740
2741         r = sd_bus_message_new_method_call(
2742                         manager->bus,
2743                         &m,
2744                         "org.freedesktop.systemd1",
2745                         "/org/freedesktop/systemd1",
2746                         "org.freedesktop.systemd1.Manager",
2747                         "StartTransientUnit");
2748         if (r < 0)
2749                 return r;
2750
2751         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2752         if (r < 0)
2753                 return r;
2754
2755         r = sd_bus_message_open_container(m, 'a', "(sv)");
2756         if (r < 0)
2757                 return r;
2758
2759         if (!isempty(slice)) {
2760                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2761                 if (r < 0)
2762                         return r;
2763         }
2764
2765         if (!isempty(description)) {
2766                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2767                 if (r < 0)
2768                         return r;
2769         }
2770
2771         if (!isempty(after)) {
2772                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2773                 if (r < 0)
2774                         return r;
2775         }
2776
2777         if (!isempty(after2)) {
2778                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2779                 if (r < 0)
2780                         return r;
2781         }
2782
2783         /* cgroup empty notification is not available in containers
2784          * currently. To make this less problematic, let's shorten the
2785          * stop timeout for sessions, so that we don't wait
2786          * forever. */
2787
2788         /* Make sure that the session shells are terminated with
2789          * SIGHUP since bash and friends tend to ignore SIGTERM */
2790         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2791         if (r < 0)
2792                 return r;
2793
2794         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2795         if (r < 0)
2796                 return r;
2797
2798         r = sd_bus_message_close_container(m);
2799         if (r < 0)
2800                 return r;
2801
2802         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2803         if (r < 0)
2804                 return r;
2805
2806         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2807         if (r < 0)
2808                 return r;
2809
2810         if (job) {
2811                 const char *j;
2812                 char *copy;
2813
2814                 r = sd_bus_message_read(reply, "o", &j);
2815                 if (r < 0)
2816                         return r;
2817
2818                 copy = strdup(j);
2819                 if (!copy)
2820                         return -ENOMEM;
2821
2822                 *job = copy;
2823         }
2824
2825         return 1;
2826 }
2827
2828 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2829         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2830         int r;
2831
2832         assert(manager);
2833         assert(unit);
2834
2835         r = sd_bus_call_method(
2836                         manager->bus,
2837                         "org.freedesktop.systemd1",
2838                         "/org/freedesktop/systemd1",
2839                         "org.freedesktop.systemd1.Manager",
2840                         "StartUnit",
2841                         error,
2842                         &reply,
2843                         "ss", unit, "fail");
2844         if (r < 0)
2845                 return r;
2846
2847         if (job) {
2848                 const char *j;
2849                 char *copy;
2850
2851                 r = sd_bus_message_read(reply, "o", &j);
2852                 if (r < 0)
2853                         return r;
2854
2855                 copy = strdup(j);
2856                 if (!copy)
2857                         return -ENOMEM;
2858
2859                 *job = copy;
2860         }
2861
2862         return 1;
2863 }
2864
2865 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2866         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2867         int r;
2868
2869         assert(manager);
2870         assert(unit);
2871
2872         r = sd_bus_call_method(
2873                         manager->bus,
2874                         "org.freedesktop.systemd1",
2875                         "/org/freedesktop/systemd1",
2876                         "org.freedesktop.systemd1.Manager",
2877                         "StopUnit",
2878                         error,
2879                         &reply,
2880                         "ss", unit, "fail");
2881         if (r < 0) {
2882                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2883                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2884
2885                         if (job)
2886                                 *job = NULL;
2887
2888                         sd_bus_error_free(error);
2889                         return 0;
2890                 }
2891
2892                 return r;
2893         }
2894
2895         if (job) {
2896                 const char *j;
2897                 char *copy;
2898
2899                 r = sd_bus_message_read(reply, "o", &j);
2900                 if (r < 0)
2901                         return r;
2902
2903                 copy = strdup(j);
2904                 if (!copy)
2905                         return -ENOMEM;
2906
2907                 *job = copy;
2908         }
2909
2910         return 1;
2911 }
2912
2913 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2914         _cleanup_free_ char *path = NULL;
2915         int r;
2916
2917         assert(manager);
2918         assert(scope);
2919
2920         path = unit_dbus_path_from_name(scope);
2921         if (!path)
2922                 return -ENOMEM;
2923
2924         r = sd_bus_call_method(
2925                         manager->bus,
2926                         "org.freedesktop.systemd1",
2927                         path,
2928                         "org.freedesktop.systemd1.Scope",
2929                         "Abandon",
2930                         error,
2931                         NULL,
2932                         NULL);
2933         if (r < 0) {
2934                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2935                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2936                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2937                         sd_bus_error_free(error);
2938                         return 0;
2939                 }
2940
2941                 return r;
2942         }
2943
2944         return 1;
2945 }
2946
2947 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2948         assert(manager);
2949         assert(unit);
2950
2951         return sd_bus_call_method(
2952                         manager->bus,
2953                         "org.freedesktop.systemd1",
2954                         "/org/freedesktop/systemd1",
2955                         "org.freedesktop.systemd1.Manager",
2956                         "KillUnit",
2957                         error,
2958                         NULL,
2959                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2960 }
2961
2962 int manager_unit_is_active(Manager *manager, const char *unit) {
2963         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2964         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2965         _cleanup_free_ char *path = NULL;
2966         const char *state;
2967         int r;
2968
2969         assert(manager);
2970         assert(unit);
2971
2972         path = unit_dbus_path_from_name(unit);
2973         if (!path)
2974                 return -ENOMEM;
2975
2976         r = sd_bus_get_property(
2977                         manager->bus,
2978                         "org.freedesktop.systemd1",
2979                         path,
2980                         "org.freedesktop.systemd1.Unit",
2981                         "ActiveState",
2982                         &error,
2983                         &reply,
2984                         "s");
2985         if (r < 0) {
2986                 /* systemd might have droppped off momentarily, let's
2987                  * not make this an error */
2988                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2989                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2990                         return true;
2991
2992                 /* If the unit is already unloaded then it's not
2993                  * active */
2994                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2995                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2996                         return false;
2997
2998                 return r;
2999         }
3000
3001         r = sd_bus_message_read(reply, "s", &state);
3002         if (r < 0)
3003                 return -EINVAL;
3004
3005         return !streq(state, "inactive") && !streq(state, "failed");
3006 }
3007
3008 int manager_job_is_active(Manager *manager, const char *path) {
3009         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3010         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3011         int r;
3012
3013         assert(manager);
3014         assert(path);
3015
3016         r = sd_bus_get_property(
3017                         manager->bus,
3018                         "org.freedesktop.systemd1",
3019                         path,
3020                         "org.freedesktop.systemd1.Job",
3021                         "State",
3022                         &error,
3023                         &reply,
3024                         "s");
3025         if (r < 0) {
3026                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3027                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3028                         return true;
3029
3030                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3031                         return false;
3032
3033                 return r;
3034         }
3035
3036         /* We don't actually care about the state really. The fact
3037          * that we could read the job state is enough for us */
3038
3039         return true;
3040 }
3041 #endif //