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