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