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