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