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