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