chiark / gitweb /
logind: add HandleLidSwitchDocked= option to logind.conf + documentation
[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(
1033                         message,
1034                         CAP_SYS_ADMIN,
1035                         "org.freedesktop.login1.set-user-linger",
1036                         interactive,
1037                         &m->polkit_registry,
1038                         error);
1039         if (r < 0)
1040                 return r;
1041         if (r == 0)
1042                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1043
1044         mkdir_p_label("/var/lib/systemd", 0755);
1045
1046         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1047         if (r < 0)
1048                 return r;
1049
1050         cc = cescape(pw->pw_name);
1051         if (!cc)
1052                 return -ENOMEM;
1053
1054         path = strappenda("/var/lib/systemd/linger/", cc);
1055         if (b) {
1056                 User *u;
1057
1058                 r = touch(path);
1059                 if (r < 0)
1060                         return r;
1061
1062                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1063                         user_start(u);
1064
1065         } else {
1066                 User *u;
1067
1068                 r = unlink(path);
1069                 if (r < 0 && errno != ENOENT)
1070                         return -errno;
1071
1072                 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1073                 if (u)
1074                         user_add_to_gc_queue(u);
1075         }
1076
1077         return sd_bus_reply_method_return(message, NULL);
1078 }
1079
1080 static int trigger_device(Manager *m, struct udev_device *d) {
1081         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1082         struct udev_list_entry *first, *item;
1083         int r;
1084
1085         assert(m);
1086
1087         e = udev_enumerate_new(m->udev);
1088         if (!e)
1089                 return -ENOMEM;
1090
1091         if (d) {
1092                 r = udev_enumerate_add_match_parent(e, d);
1093                 if (r < 0)
1094                         return r;
1095         }
1096
1097         r = udev_enumerate_scan_devices(e);
1098         if (r < 0)
1099                 return r;
1100
1101         first = udev_enumerate_get_list_entry(e);
1102         udev_list_entry_foreach(item, first) {
1103                 _cleanup_free_ char *t = NULL;
1104                 const char *p;
1105
1106                 p = udev_list_entry_get_name(item);
1107
1108                 t = strappend(p, "/uevent");
1109                 if (!t)
1110                         return -ENOMEM;
1111
1112                 write_string_file(t, "change");
1113         }
1114
1115         return 0;
1116 }
1117
1118 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1119         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1120         _cleanup_free_ char *rule = NULL, *file = NULL;
1121         const char *id_for_seat;
1122         int r;
1123
1124         assert(m);
1125         assert(seat);
1126         assert(sysfs);
1127
1128         d = udev_device_new_from_syspath(m->udev, sysfs);
1129         if (!d)
1130                 return -ENODEV;
1131
1132         if (!udev_device_has_tag(d, "seat"))
1133                 return -ENODEV;
1134
1135         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1136         if (!id_for_seat)
1137                 return -ENODEV;
1138
1139         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1140                 return -ENOMEM;
1141
1142         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1143                 return -ENOMEM;
1144
1145         mkdir_p_label("/etc/udev/rules.d", 0755);
1146         label_init("/etc");
1147         r = write_string_file_atomic_label(file, rule);
1148         if (r < 0)
1149                 return r;
1150
1151         return trigger_device(m, d);
1152 }
1153
1154 static int flush_devices(Manager *m) {
1155         _cleanup_closedir_ DIR *d;
1156
1157         assert(m);
1158
1159         d = opendir("/etc/udev/rules.d");
1160         if (!d) {
1161                 if (errno != ENOENT)
1162                         log_warning("Failed to open /etc/udev/rules.d: %m");
1163         } else {
1164                 struct dirent *de;
1165
1166                 while ((de = readdir(d))) {
1167
1168                         if (!dirent_is_file(de))
1169                                 continue;
1170
1171                         if (!startswith(de->d_name, "72-seat-"))
1172                                 continue;
1173
1174                         if (!endswith(de->d_name, ".rules"))
1175                                 continue;
1176
1177                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1178                                 log_warning("Failed to unlink %s: %m", de->d_name);
1179                 }
1180         }
1181
1182         return trigger_device(m, NULL);
1183 }
1184
1185 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1186         const char *sysfs, *seat;
1187         Manager *m = userdata;
1188         int interactive, r;
1189
1190         assert(bus);
1191         assert(message);
1192         assert(m);
1193
1194         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1195         if (r < 0)
1196                 return r;
1197
1198         if (!path_startswith(sysfs, "/sys"))
1199                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1200
1201         if (!seat_name_is_valid(seat))
1202                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1203
1204         r = bus_verify_polkit_async(
1205                         message,
1206                         CAP_SYS_ADMIN,
1207                         "org.freedesktop.login1.attach-device",
1208                         interactive,
1209                         &m->polkit_registry,
1210                         error);
1211         if (r < 0)
1212                 return r;
1213         if (r == 0)
1214                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1215
1216         r = attach_device(m, seat, sysfs);
1217         if (r < 0)
1218                 return r;
1219
1220         return sd_bus_reply_method_return(message, NULL);
1221 }
1222
1223 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1224         Manager *m = userdata;
1225         int interactive, r;
1226
1227         assert(bus);
1228         assert(message);
1229         assert(m);
1230
1231         r = sd_bus_message_read(message, "b", &interactive);
1232         if (r < 0)
1233                 return r;
1234
1235         r = bus_verify_polkit_async(
1236                         message,
1237                         CAP_SYS_ADMIN,
1238                         "org.freedesktop.login1.flush-devices",
1239                         interactive,
1240                         &m->polkit_registry,
1241                         error);
1242         if (r < 0)
1243                 return r;
1244         if (r == 0)
1245                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1246
1247         r = flush_devices(m);
1248         if (r < 0)
1249                 return r;
1250
1251         return sd_bus_reply_method_return(message, NULL);
1252 }
1253
1254 static int have_multiple_sessions(
1255                 Manager *m,
1256                 uid_t uid) {
1257
1258         Session *session;
1259         Iterator i;
1260
1261         assert(m);
1262
1263         /* Check for other users' sessions. Greeter sessions do not
1264          * count, and non-login sessions do not count either. */
1265         HASHMAP_FOREACH(session, m->sessions, i)
1266                 if (session->class == SESSION_USER &&
1267                     session->user->uid != uid)
1268                         return true;
1269
1270         return false;
1271 }
1272
1273 static int bus_manager_log_shutdown(
1274                 Manager *m,
1275                 InhibitWhat w,
1276                 const char *unit_name) {
1277
1278         const char *p, *q;
1279
1280         assert(m);
1281         assert(unit_name);
1282
1283         if (w != INHIBIT_SHUTDOWN)
1284                 return 0;
1285
1286         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1287                 p = "MESSAGE=System is powering down.";
1288                 q = "SHUTDOWN=power-off";
1289         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1290                 p = "MESSAGE=System is halting.";
1291                 q = "SHUTDOWN=halt";
1292         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1293                 p = "MESSAGE=System is rebooting.";
1294                 q = "SHUTDOWN=reboot";
1295         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1296                 p = "MESSAGE=System is rebooting with kexec.";
1297                 q = "SHUTDOWN=kexec";
1298         } else {
1299                 p = "MESSAGE=System is shutting down.";
1300                 q = NULL;
1301         }
1302
1303         return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1304                           p,
1305                           q, NULL);
1306 }
1307
1308 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1309         Manager *m = userdata;
1310
1311         assert(e);
1312         assert(m);
1313
1314         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1315         return 0;
1316 }
1317
1318 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1319         int r;
1320
1321         assert(m);
1322
1323         if (until <= now(CLOCK_MONOTONIC))
1324                 return 0;
1325
1326         /* We want to ignore the lid switch for a while after each
1327          * suspend, and after boot-up. Hence let's install a timer for
1328          * this. As long as the event source exists we ignore the lid
1329          * switch. */
1330
1331         if (m->lid_switch_ignore_event_source) {
1332                 usec_t u;
1333
1334                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1335                 if (r < 0)
1336                         return r;
1337
1338                 if (until <= u)
1339                         return 0;
1340
1341                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1342         } else
1343                 r = sd_event_add_time(
1344                                 m->event,
1345                                 &m->lid_switch_ignore_event_source,
1346                                 CLOCK_MONOTONIC,
1347                                 until, 0,
1348                                 lid_switch_ignore_handler, m);
1349
1350         return r;
1351 }
1352
1353 static int execute_shutdown_or_sleep(
1354                 Manager *m,
1355                 InhibitWhat w,
1356                 const char *unit_name,
1357                 sd_bus_error *error) {
1358
1359         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1360         const char *p;
1361         char *c;
1362         int r;
1363
1364         assert(m);
1365         assert(w >= 0);
1366         assert(w < _INHIBIT_WHAT_MAX);
1367         assert(unit_name);
1368
1369         bus_manager_log_shutdown(m, w, unit_name);
1370
1371         r = sd_bus_call_method(
1372                         m->bus,
1373                         "org.freedesktop.systemd1",
1374                         "/org/freedesktop/systemd1",
1375                         "org.freedesktop.systemd1.Manager",
1376                         "StartUnit",
1377                         error,
1378                         &reply,
1379                         "ss", unit_name, "replace-irreversibly");
1380         if (r < 0)
1381                 return r;
1382
1383         r = sd_bus_message_read(reply, "o", &p);
1384         if (r < 0)
1385                 return r;
1386
1387         c = strdup(p);
1388         if (!c)
1389                 return -ENOMEM;
1390
1391         m->action_unit = unit_name;
1392         free(m->action_job);
1393         m->action_job = c;
1394         m->action_what = w;
1395
1396         /* Make sure the lid switch is ignored for a while */
1397         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
1398
1399         return 0;
1400 }
1401
1402 static int delay_shutdown_or_sleep(
1403                 Manager *m,
1404                 InhibitWhat w,
1405                 const char *unit_name) {
1406
1407         assert(m);
1408         assert(w >= 0);
1409         assert(w < _INHIBIT_WHAT_MAX);
1410         assert(unit_name);
1411
1412         m->action_timestamp = now(CLOCK_MONOTONIC);
1413         m->action_unit = unit_name;
1414         m->action_what = w;
1415
1416         return 0;
1417 }
1418
1419 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1420
1421         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1422                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1423                 [INHIBIT_SLEEP] = "PrepareForSleep"
1424         };
1425
1426         int active = _active;
1427
1428         assert(m);
1429         assert(w >= 0);
1430         assert(w < _INHIBIT_WHAT_MAX);
1431         assert(signal_name[w]);
1432
1433         return sd_bus_emit_signal(m->bus,
1434                                   "/org/freedesktop/login1",
1435                                   "org.freedesktop.login1.Manager",
1436                                   signal_name[w],
1437                                   "b",
1438                                   active);
1439 }
1440
1441 int bus_manager_shutdown_or_sleep_now_or_later(
1442                 Manager *m,
1443                 const char *unit_name,
1444                 InhibitWhat w,
1445                 sd_bus_error *error) {
1446
1447         bool delayed;
1448         int r;
1449
1450         assert(m);
1451         assert(unit_name);
1452         assert(w >= 0);
1453         assert(w <= _INHIBIT_WHAT_MAX);
1454         assert(!m->action_job);
1455
1456         /* Tell everybody to prepare for shutdown/sleep */
1457         send_prepare_for(m, w, true);
1458
1459         delayed =
1460                 m->inhibit_delay_max > 0 &&
1461                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1462
1463         if (delayed)
1464                 /* Shutdown is delayed, keep in mind what we
1465                  * want to do, and start a timeout */
1466                 r = delay_shutdown_or_sleep(m, w, unit_name);
1467         else
1468                 /* Shutdown is not delayed, execute it
1469                  * immediately */
1470                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1471
1472         return r;
1473 }
1474
1475 static int method_do_shutdown_or_sleep(
1476                 Manager *m,
1477                 sd_bus_message *message,
1478                 const char *unit_name,
1479                 InhibitWhat w,
1480                 const char *action,
1481                 const char *action_multiple_sessions,
1482                 const char *action_ignore_inhibit,
1483                 const char *sleep_verb,
1484                 sd_bus_message_handler_t method,
1485                 sd_bus_error *error) {
1486
1487         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1488         bool multiple_sessions, blocked;
1489         int interactive, r;
1490         uid_t uid;
1491
1492         assert(m);
1493         assert(message);
1494         assert(unit_name);
1495         assert(w >= 0);
1496         assert(w <= _INHIBIT_WHAT_MAX);
1497         assert(action);
1498         assert(action_multiple_sessions);
1499         assert(action_ignore_inhibit);
1500         assert(method);
1501
1502         r = sd_bus_message_read(message, "b", &interactive);
1503         if (r < 0)
1504                 return r;
1505
1506         /* Don't allow multiple jobs being executed at the same time */
1507         if (m->action_what)
1508                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1509
1510         if (sleep_verb) {
1511                 r = can_sleep(sleep_verb);
1512                 if (r < 0)
1513                         return r;
1514
1515                 if (r == 0)
1516                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1517         }
1518
1519         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1520         if (r < 0)
1521                 return r;
1522
1523         r = sd_bus_creds_get_uid(creds, &uid);
1524         if (r < 0)
1525                 return r;
1526
1527         r = have_multiple_sessions(m, uid);
1528         if (r < 0)
1529                 return r;
1530
1531         multiple_sessions = r > 0;
1532         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1533
1534         if (multiple_sessions) {
1535                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
1536                 if (r < 0)
1537                         return r;
1538                 if (r == 0)
1539                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1540         }
1541
1542         if (blocked) {
1543                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
1544                 if (r < 0)
1545                         return r;
1546                 if (r == 0)
1547                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1548         }
1549
1550         if (!multiple_sessions && !blocked) {
1551                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
1552                 if (r < 0)
1553                         return r;
1554                 if (r == 0)
1555                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1556         }
1557
1558         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1559         if (r < 0)
1560                 return r;
1561
1562         return sd_bus_reply_method_return(message, NULL);
1563 }
1564
1565 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1566         Manager *m = userdata;
1567
1568         return method_do_shutdown_or_sleep(
1569                         m, message,
1570                         SPECIAL_POWEROFF_TARGET,
1571                         INHIBIT_SHUTDOWN,
1572                         "org.freedesktop.login1.power-off",
1573                         "org.freedesktop.login1.power-off-multiple-sessions",
1574                         "org.freedesktop.login1.power-off-ignore-inhibit",
1575                         NULL,
1576                         method_poweroff,
1577                         error);
1578 }
1579
1580 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1581         Manager *m = userdata;
1582
1583         return method_do_shutdown_or_sleep(
1584                         m, message,
1585                         SPECIAL_REBOOT_TARGET,
1586                         INHIBIT_SHUTDOWN,
1587                         "org.freedesktop.login1.reboot",
1588                         "org.freedesktop.login1.reboot-multiple-sessions",
1589                         "org.freedesktop.login1.reboot-ignore-inhibit",
1590                         NULL,
1591                         method_reboot,
1592                         error);
1593 }
1594
1595 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1596         Manager *m = userdata;
1597
1598         return method_do_shutdown_or_sleep(
1599                         m, message,
1600                         SPECIAL_SUSPEND_TARGET,
1601                         INHIBIT_SLEEP,
1602                         "org.freedesktop.login1.suspend",
1603                         "org.freedesktop.login1.suspend-multiple-sessions",
1604                         "org.freedesktop.login1.suspend-ignore-inhibit",
1605                         "suspend",
1606                         method_suspend,
1607                         error);
1608 }
1609
1610 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1611         Manager *m = userdata;
1612
1613         return method_do_shutdown_or_sleep(
1614                         m, message,
1615                         SPECIAL_HIBERNATE_TARGET,
1616                         INHIBIT_SLEEP,
1617                         "org.freedesktop.login1.hibernate",
1618                         "org.freedesktop.login1.hibernate-multiple-sessions",
1619                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1620                         "hibernate",
1621                         method_hibernate,
1622                         error);
1623 }
1624
1625 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1626         Manager *m = userdata;
1627
1628         return method_do_shutdown_or_sleep(
1629                         m, message,
1630                         SPECIAL_HYBRID_SLEEP_TARGET,
1631                         INHIBIT_SLEEP,
1632                         "org.freedesktop.login1.hibernate",
1633                         "org.freedesktop.login1.hibernate-multiple-sessions",
1634                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1635                         "hybrid-sleep",
1636                         method_hybrid_sleep,
1637                         error);
1638 }
1639
1640 static int method_can_shutdown_or_sleep(
1641                 Manager *m,
1642                 sd_bus_message *message,
1643                 InhibitWhat w,
1644                 const char *action,
1645                 const char *action_multiple_sessions,
1646                 const char *action_ignore_inhibit,
1647                 const char *sleep_verb,
1648                 sd_bus_error *error) {
1649
1650         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1651         bool multiple_sessions, challenge, blocked;
1652         const char *result = NULL;
1653         uid_t uid;
1654         int r;
1655
1656         assert(m);
1657         assert(message);
1658         assert(w >= 0);
1659         assert(w <= _INHIBIT_WHAT_MAX);
1660         assert(action);
1661         assert(action_multiple_sessions);
1662         assert(action_ignore_inhibit);
1663
1664         if (sleep_verb) {
1665                 r = can_sleep(sleep_verb);
1666                 if (r < 0)
1667                         return r;
1668                 if (r == 0)
1669                         return sd_bus_reply_method_return(message, "s", "na");
1670         }
1671
1672         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1673         if (r < 0)
1674                 return r;
1675
1676         r = sd_bus_creds_get_uid(creds, &uid);
1677         if (r < 0)
1678                 return r;
1679
1680         r = have_multiple_sessions(m, uid);
1681         if (r < 0)
1682                 return r;
1683
1684         multiple_sessions = r > 0;
1685         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1686
1687         if (multiple_sessions) {
1688                 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
1689                 if (r < 0)
1690                         return r;
1691
1692                 if (r > 0)
1693                         result = "yes";
1694                 else if (challenge)
1695                         result = "challenge";
1696                 else
1697                         result = "no";
1698         }
1699
1700         if (blocked) {
1701                 r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
1702                 if (r < 0)
1703                         return r;
1704
1705                 if (r > 0 && !result)
1706                         result = "yes";
1707                 else if (challenge && (!result || streq(result, "yes")))
1708                         result = "challenge";
1709                 else
1710                         result = "no";
1711         }
1712
1713         if (!multiple_sessions && !blocked) {
1714                 /* If neither inhibit nor multiple sessions
1715                  * apply then just check the normal policy */
1716
1717                 r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error);
1718                 if (r < 0)
1719                         return r;
1720
1721                 if (r > 0)
1722                         result = "yes";
1723                 else if (challenge)
1724                         result = "challenge";
1725                 else
1726                         result = "no";
1727         }
1728
1729         return sd_bus_reply_method_return(message, "s", result);
1730 }
1731
1732 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1733         Manager *m = userdata;
1734
1735         return method_can_shutdown_or_sleep(
1736                         m, message,
1737                         INHIBIT_SHUTDOWN,
1738                         "org.freedesktop.login1.power-off",
1739                         "org.freedesktop.login1.power-off-multiple-sessions",
1740                         "org.freedesktop.login1.power-off-ignore-inhibit",
1741                         NULL,
1742                         error);
1743 }
1744
1745 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1746         Manager *m = userdata;
1747
1748         return method_can_shutdown_or_sleep(
1749                         m, message,
1750                         INHIBIT_SHUTDOWN,
1751                         "org.freedesktop.login1.reboot",
1752                         "org.freedesktop.login1.reboot-multiple-sessions",
1753                         "org.freedesktop.login1.reboot-ignore-inhibit",
1754                         NULL,
1755                         error);
1756 }
1757
1758 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1759         Manager *m = userdata;
1760
1761         return method_can_shutdown_or_sleep(
1762                         m, message,
1763                         INHIBIT_SLEEP,
1764                         "org.freedesktop.login1.suspend",
1765                         "org.freedesktop.login1.suspend-multiple-sessions",
1766                         "org.freedesktop.login1.suspend-ignore-inhibit",
1767                         "suspend",
1768                         error);
1769 }
1770
1771 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1772         Manager *m = userdata;
1773
1774         return method_can_shutdown_or_sleep(
1775                         m, message,
1776                         INHIBIT_SLEEP,
1777                         "org.freedesktop.login1.hibernate",
1778                         "org.freedesktop.login1.hibernate-multiple-sessions",
1779                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1780                         "hibernate",
1781                         error);
1782 }
1783
1784 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1785         Manager *m = userdata;
1786
1787         return method_can_shutdown_or_sleep(
1788                         m, message,
1789                         INHIBIT_SLEEP,
1790                         "org.freedesktop.login1.hibernate",
1791                         "org.freedesktop.login1.hibernate-multiple-sessions",
1792                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1793                         "hybrid-sleep",
1794                         error);
1795 }
1796
1797 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1798         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1799         const char *who, *why, *what, *mode;
1800         _cleanup_free_ char *id = NULL;
1801         _cleanup_close_ int fifo_fd = -1;
1802         Manager *m = userdata;
1803         Inhibitor *i = NULL;
1804         InhibitMode mm;
1805         InhibitWhat w;
1806         pid_t pid;
1807         uid_t uid;
1808         int r;
1809
1810         assert(bus);
1811         assert(message);
1812         assert(m);
1813
1814         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1815         if (r < 0)
1816                 return r;
1817
1818         w = inhibit_what_from_string(what);
1819         if (w <= 0)
1820                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1821
1822         mm = inhibit_mode_from_string(mode);
1823         if (mm < 0)
1824                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1825
1826         /* Delay is only supported for shutdown/sleep */
1827         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1828                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1829
1830         /* Don't allow taking delay locks while we are already
1831          * executing the operation. We shouldn't create the impression
1832          * that the lock was successful if the machine is about to go
1833          * down/suspend any moment. */
1834         if (m->action_what & w)
1835                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1836
1837         r = bus_verify_polkit_async(message, CAP_SYS_BOOT,
1838                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1839                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
1840                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
1841                                     w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
1842                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1843                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1844                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
1845                                     false, &m->polkit_registry, error);
1846         if (r < 0)
1847                 return r;
1848         if (r == 0)
1849                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1850
1851         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1852         if (r < 0)
1853                 return r;
1854
1855         r = sd_bus_creds_get_uid(creds, &uid);
1856         if (r < 0)
1857                 return r;
1858
1859         r = sd_bus_creds_get_pid(creds, &pid);
1860         if (r < 0)
1861                 return r;
1862
1863         do {
1864                 free(id);
1865                 id = NULL;
1866
1867                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1868                         return -ENOMEM;
1869
1870         } while (hashmap_get(m->inhibitors, id));
1871
1872         r = manager_add_inhibitor(m, id, &i);
1873         if (r < 0)
1874                 return r;
1875
1876         i->what = w;
1877         i->mode = mm;
1878         i->pid = pid;
1879         i->uid = uid;
1880         i->why = strdup(why);
1881         i->who = strdup(who);
1882
1883         if (!i->why || !i->who) {
1884                 r = -ENOMEM;
1885                 goto fail;
1886         }
1887
1888         fifo_fd = inhibitor_create_fifo(i);
1889         if (fifo_fd < 0) {
1890                 r = fifo_fd;
1891                 goto fail;
1892         }
1893
1894         inhibitor_start(i);
1895
1896         return sd_bus_reply_method_return(message, "h", fifo_fd);
1897
1898 fail:
1899         if (i)
1900                 inhibitor_free(i);
1901
1902         return r;
1903 }
1904
1905 const sd_bus_vtable manager_vtable[] = {
1906         SD_BUS_VTABLE_START(0),
1907
1908         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1909         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1910         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1911         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1912         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1913         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1914         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1915         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1916         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1917         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1918         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1919         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1920         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1921         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1922         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
1923         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1924         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1925         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1926         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1927
1928         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1929         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1930         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1931         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1932         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1933         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1934         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1935         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1936         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1937         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1938         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1939         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1940         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1941         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1942         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1943         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1944         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1945         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1946         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1947         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1948         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1949         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1950         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1951         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1952         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1953         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1954         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1955         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1956         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1957         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1958         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1959         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1960         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1961         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1962         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1963         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1964
1965         SD_BUS_SIGNAL("SessionNew", "so", 0),
1966         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1967         SD_BUS_SIGNAL("UserNew", "uo", 0),
1968         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1969         SD_BUS_SIGNAL("SeatNew", "so", 0),
1970         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1971         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1972         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1973
1974         SD_BUS_VTABLE_END
1975 };
1976
1977 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1978         int r = 0;
1979
1980         assert(s);
1981         assert(unit);
1982
1983         if (!s->started)
1984                 return r;
1985
1986         if (streq(result, "done"))
1987                 r = session_send_create_reply(s, NULL);
1988         else {
1989                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1990
1991                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1992                 r = session_send_create_reply(s, &e);
1993         }
1994
1995         return r;
1996 }
1997
1998 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1999         const char *path, *result, *unit;
2000         Manager *m = userdata;
2001         Session *session;
2002         uint32_t id;
2003         User *user;
2004         int r;
2005
2006         assert(bus);
2007         assert(message);
2008         assert(m);
2009
2010         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2011         if (r < 0) {
2012                 bus_log_parse_error(r);
2013                 return r;
2014         }
2015
2016         if (m->action_job && streq(m->action_job, path)) {
2017                 log_info("Operation finished.");
2018
2019                 /* Tell people that they now may take a lock again */
2020                 send_prepare_for(m, m->action_what, false);
2021
2022                 free(m->action_job);
2023                 m->action_job = NULL;
2024                 m->action_unit = NULL;
2025                 m->action_what = 0;
2026                 return 0;
2027         }
2028
2029         session = hashmap_get(m->session_units, unit);
2030         if (session) {
2031
2032                 if (streq_ptr(path, session->scope_job)) {
2033                         free(session->scope_job);
2034                         session->scope_job = NULL;
2035                 }
2036
2037                 session_jobs_reply(session, unit, result);
2038
2039                 session_save(session);
2040                 session_add_to_gc_queue(session);
2041         }
2042
2043         user = hashmap_get(m->user_units, unit);
2044         if (user) {
2045
2046                 if (streq_ptr(path, user->service_job)) {
2047                         free(user->service_job);
2048                         user->service_job = NULL;
2049                 }
2050
2051                 if (streq_ptr(path, user->slice_job)) {
2052                         free(user->slice_job);
2053                         user->slice_job = NULL;
2054                 }
2055
2056                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2057                         session_jobs_reply(session, unit, result);
2058                 }
2059
2060                 user_save(user);
2061                 user_add_to_gc_queue(user);
2062         }
2063
2064         return 0;
2065 }
2066
2067 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2068         const char *path, *unit;
2069         Manager *m = userdata;
2070         Session *session;
2071         User *user;
2072         int r;
2073
2074         assert(bus);
2075         assert(message);
2076         assert(m);
2077
2078         r = sd_bus_message_read(message, "so", &unit, &path);
2079         if (r < 0) {
2080                 bus_log_parse_error(r);
2081                 return r;
2082         }
2083
2084         session = hashmap_get(m->session_units, unit);
2085         if (session)
2086                 session_add_to_gc_queue(session);
2087
2088         user = hashmap_get(m->user_units, unit);
2089         if (user)
2090                 user_add_to_gc_queue(user);
2091
2092         return 0;
2093 }
2094
2095 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2096         _cleanup_free_ char *unit = NULL;
2097         Manager *m = userdata;
2098         const char *path;
2099         Session *session;
2100         User *user;
2101         int r;
2102
2103         assert(bus);
2104         assert(message);
2105         assert(m);
2106
2107         path = sd_bus_message_get_path(message);
2108         if (!path)
2109                 return 0;
2110
2111         r = unit_name_from_dbus_path(path, &unit);
2112         if (r < 0)
2113                 /* quietly ignore non-units paths */
2114                 return r == -EINVAL ? 0 : r;
2115
2116         session = hashmap_get(m->session_units, unit);
2117         if (session)
2118                 session_add_to_gc_queue(session);
2119
2120         user = hashmap_get(m->user_units, unit);
2121         if (user)
2122                 user_add_to_gc_queue(user);
2123
2124         return 0;
2125 }
2126
2127 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2128         Manager *m = userdata;
2129         Session *session;
2130         Iterator i;
2131         int b, r;
2132
2133         assert(bus);
2134
2135         r = sd_bus_message_read(message, "b", &b);
2136         if (r < 0) {
2137                 bus_log_parse_error(r);
2138                 return r;
2139         }
2140
2141         if (b)
2142                 return 0;
2143
2144         /* systemd finished reloading, let's recheck all our sessions */
2145         log_debug("System manager has been reloaded, rechecking sessions...");
2146
2147         HASHMAP_FOREACH(session, m->sessions, i)
2148                 session_add_to_gc_queue(session);
2149
2150         return 0;
2151 }
2152
2153 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2154         const char *name, *old, *new;
2155         Manager *m = userdata;
2156         Session *session;
2157         Iterator i;
2158         int r;
2159
2160
2161         char *key;
2162
2163         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2164         if (r < 0) {
2165                 bus_log_parse_error(r);
2166                 return r;
2167         }
2168
2169         if (isempty(old) || !isempty(new))
2170                 return 0;
2171
2172         key = set_remove(m->busnames, (char*) old);
2173         if (!key)
2174                 return 0;
2175
2176         /* Drop all controllers owned by this name */
2177
2178         free(key);
2179
2180         HASHMAP_FOREACH(session, m->sessions, i)
2181                 if (session_is_controller(session, old))
2182                         session_drop_controller(session);
2183
2184         return 0;
2185 }
2186
2187 int manager_send_changed(Manager *manager, const char *property, ...) {
2188         char **l;
2189
2190         assert(manager);
2191
2192         l = strv_from_stdarg_alloca(property);
2193
2194         return sd_bus_emit_properties_changed_strv(
2195                         manager->bus,
2196                         "/org/freedesktop/login1",
2197                         "org.freedesktop.login1.Manager",
2198                         l);
2199 }
2200
2201 int manager_dispatch_delayed(Manager *manager) {
2202         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2203         Inhibitor *offending = NULL;
2204         int r;
2205
2206         assert(manager);
2207
2208         if (manager->action_what == 0 || manager->action_job)
2209                 return 0;
2210
2211         /* Continue delay? */
2212         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2213                 _cleanup_free_ char *comm = NULL, *u = NULL;
2214
2215                 get_process_comm(offending->pid, &comm);
2216                 u = uid_to_name(offending->uid);
2217
2218                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2219                         return 0;
2220
2221                 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2222                          offending->uid, strna(u),
2223                          offending->pid, strna(comm));
2224         }
2225
2226         /* Actually do the operation */
2227         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2228         if (r < 0) {
2229                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2230
2231                 manager->action_unit = NULL;
2232                 manager->action_what = 0;
2233                 return r;
2234         }
2235
2236         return 1;
2237 }
2238
2239 int manager_start_scope(
2240                 Manager *manager,
2241                 const char *scope,
2242                 pid_t pid,
2243                 const char *slice,
2244                 const char *description,
2245                 const char *after, const char *after2,
2246                 sd_bus_error *error,
2247                 char **job) {
2248
2249         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2250         int r;
2251
2252         assert(manager);
2253         assert(scope);
2254         assert(pid > 1);
2255
2256         r = sd_bus_message_new_method_call(
2257                         manager->bus,
2258                         &m,
2259                         "org.freedesktop.systemd1",
2260                         "/org/freedesktop/systemd1",
2261                         "org.freedesktop.systemd1.Manager",
2262                         "StartTransientUnit");
2263         if (r < 0)
2264                 return r;
2265
2266         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2267         if (r < 0)
2268                 return r;
2269
2270         r = sd_bus_message_open_container(m, 'a', "(sv)");
2271         if (r < 0)
2272                 return r;
2273
2274         if (!isempty(slice)) {
2275                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2276                 if (r < 0)
2277                         return r;
2278         }
2279
2280         if (!isempty(description)) {
2281                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2282                 if (r < 0)
2283                         return r;
2284         }
2285
2286         if (!isempty(after)) {
2287                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2288                 if (r < 0)
2289                         return r;
2290         }
2291
2292         if (!isempty(after2)) {
2293                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2294                 if (r < 0)
2295                         return r;
2296         }
2297
2298         /* cgroup empty notification is not available in containers
2299          * currently. To make this less problematic, let's shorten the
2300          * stop timeout for sessions, so that we don't wait
2301          * forever. */
2302
2303         /* Make sure that the session shells are terminated with
2304          * SIGHUP since bash and friends tend to ignore SIGTERM */
2305         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2306         if (r < 0)
2307                 return r;
2308
2309         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2310         if (r < 0)
2311                 return r;
2312
2313         r = sd_bus_message_close_container(m);
2314         if (r < 0)
2315                 return r;
2316
2317         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2318         if (r < 0)
2319                 return r;
2320
2321         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2322         if (r < 0)
2323                 return r;
2324
2325         if (job) {
2326                 const char *j;
2327                 char *copy;
2328
2329                 r = sd_bus_message_read(reply, "o", &j);
2330                 if (r < 0)
2331                         return r;
2332
2333                 copy = strdup(j);
2334                 if (!copy)
2335                         return -ENOMEM;
2336
2337                 *job = copy;
2338         }
2339
2340         return 1;
2341 }
2342
2343 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2344         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2345         int r;
2346
2347         assert(manager);
2348         assert(unit);
2349
2350         r = sd_bus_call_method(
2351                         manager->bus,
2352                         "org.freedesktop.systemd1",
2353                         "/org/freedesktop/systemd1",
2354                         "org.freedesktop.systemd1.Manager",
2355                         "StartUnit",
2356                         error,
2357                         &reply,
2358                         "ss", unit, "fail");
2359         if (r < 0)
2360                 return r;
2361
2362         if (job) {
2363                 const char *j;
2364                 char *copy;
2365
2366                 r = sd_bus_message_read(reply, "o", &j);
2367                 if (r < 0)
2368                         return r;
2369
2370                 copy = strdup(j);
2371                 if (!copy)
2372                         return -ENOMEM;
2373
2374                 *job = copy;
2375         }
2376
2377         return 1;
2378 }
2379
2380 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2381         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2382         int r;
2383
2384         assert(manager);
2385         assert(unit);
2386
2387         r = sd_bus_call_method(
2388                         manager->bus,
2389                         "org.freedesktop.systemd1",
2390                         "/org/freedesktop/systemd1",
2391                         "org.freedesktop.systemd1.Manager",
2392                         "StopUnit",
2393                         error,
2394                         &reply,
2395                         "ss", unit, "fail");
2396         if (r < 0) {
2397                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2398                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2399
2400                         if (job)
2401                                 *job = NULL;
2402
2403                         sd_bus_error_free(error);
2404                         return 0;
2405                 }
2406
2407                 return r;
2408         }
2409
2410         if (job) {
2411                 const char *j;
2412                 char *copy;
2413
2414                 r = sd_bus_message_read(reply, "o", &j);
2415                 if (r < 0)
2416                         return r;
2417
2418                 copy = strdup(j);
2419                 if (!copy)
2420                         return -ENOMEM;
2421
2422                 *job = copy;
2423         }
2424
2425         return 1;
2426 }
2427
2428 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2429         _cleanup_free_ char *path = NULL;
2430         int r;
2431
2432         assert(manager);
2433         assert(scope);
2434
2435         path = unit_dbus_path_from_name(scope);
2436         if (!path)
2437                 return -ENOMEM;
2438
2439         r = sd_bus_call_method(
2440                         manager->bus,
2441                         "org.freedesktop.systemd1",
2442                         path,
2443                         "org.freedesktop.systemd1.Scope",
2444                         "Abandon",
2445                         error,
2446                         NULL,
2447                         NULL);
2448         if (r < 0) {
2449                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2450                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2451                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2452                         sd_bus_error_free(error);
2453                         return 0;
2454                 }
2455
2456                 return r;
2457         }
2458
2459         return 1;
2460 }
2461
2462 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2463         assert(manager);
2464         assert(unit);
2465
2466         return sd_bus_call_method(
2467                         manager->bus,
2468                         "org.freedesktop.systemd1",
2469                         "/org/freedesktop/systemd1",
2470                         "org.freedesktop.systemd1.Manager",
2471                         "KillUnit",
2472                         error,
2473                         NULL,
2474                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2475 }
2476
2477 int manager_unit_is_active(Manager *manager, const char *unit) {
2478         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2479         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2480         _cleanup_free_ char *path = NULL;
2481         const char *state;
2482         int r;
2483
2484         assert(manager);
2485         assert(unit);
2486
2487         path = unit_dbus_path_from_name(unit);
2488         if (!path)
2489                 return -ENOMEM;
2490
2491         r = sd_bus_get_property(
2492                         manager->bus,
2493                         "org.freedesktop.systemd1",
2494                         path,
2495                         "org.freedesktop.systemd1.Unit",
2496                         "ActiveState",
2497                         &error,
2498                         &reply,
2499                         "s");
2500         if (r < 0) {
2501                 /* systemd might have droppped off momentarily, let's
2502                  * not make this an error */
2503                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2504                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2505                         return true;
2506
2507                 /* If the unit is already unloaded then it's not
2508                  * active */
2509                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2510                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2511                         return false;
2512
2513                 return r;
2514         }
2515
2516         r = sd_bus_message_read(reply, "s", &state);
2517         if (r < 0)
2518                 return -EINVAL;
2519
2520         return !streq(state, "inactive") && !streq(state, "failed");
2521 }
2522
2523 int manager_job_is_active(Manager *manager, const char *path) {
2524         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2525         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2526         int r;
2527
2528         assert(manager);
2529         assert(path);
2530
2531         r = sd_bus_get_property(
2532                         manager->bus,
2533                         "org.freedesktop.systemd1",
2534                         path,
2535                         "org.freedesktop.systemd1.Job",
2536                         "State",
2537                         &error,
2538                         &reply,
2539                         "s");
2540         if (r < 0) {
2541                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2542                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2543                         return true;
2544
2545                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2546                         return false;
2547
2548                 return r;
2549         }
2550
2551         /* We don't actually care about the state really. The fact
2552          * that we could read the job state is enough for us */
2553
2554         return true;
2555 }