chiark / gitweb /
logind: bring polkit policy for hibernate in line with suspend/poweroff/reboot
[elogind.git] / src / login / logind-dbus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <pwd.h>
26 #include <sys/capability.h>
27
28 #include "sd-id128.h"
29 #include "sd-messages.h"
30 #include "strv.h"
31 #include "mkdir.h"
32 #include "path-util.h"
33 #include "special.h"
34 #include "sleep-config.h"
35 #include "fileio-label.h"
36 #include "label.h"
37 #include "utf8.h"
38 #include "unit-name.h"
39 #include "virt.h"
40 #include "audit.h"
41 #include "bus-util.h"
42 #include "bus-error.h"
43 #include "logind.h"
44 #include "bus-errors.h"
45 #include "udev-util.h"
46
47 static int property_get_idle_hint(
48                 sd_bus *bus,
49                 const char *path,
50                 const char *interface,
51                 const char *property,
52                 sd_bus_message *reply,
53                 void *userdata,
54                 sd_bus_error *error) {
55
56         Manager *m = userdata;
57
58         assert(bus);
59         assert(reply);
60         assert(m);
61
62         return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
63 }
64
65 static int property_get_idle_since_hint(
66                 sd_bus *bus,
67                 const char *path,
68                 const char *interface,
69                 const char *property,
70                 sd_bus_message *reply,
71                 void *userdata,
72                 sd_bus_error *error) {
73
74         Manager *m = userdata;
75         dual_timestamp t;
76
77         assert(bus);
78         assert(reply);
79         assert(m);
80
81         manager_get_idle_hint(m, &t);
82
83         return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
84 }
85
86 static int property_get_inhibited(
87                 sd_bus *bus,
88                 const char *path,
89                 const char *interface,
90                 const char *property,
91                 sd_bus_message *reply,
92                 void *userdata,
93                 sd_bus_error *error) {
94
95         Manager *m = userdata;
96         InhibitWhat w;
97
98         assert(bus);
99         assert(reply);
100         assert(m);
101
102         w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
103
104         return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
105 }
106
107 static int property_get_preparing(
108                 sd_bus *bus,
109                 const char *path,
110                 const char *interface,
111                 const char *property,
112                 sd_bus_message *reply,
113                 void *userdata,
114                 sd_bus_error *error) {
115
116         Manager *m = userdata;
117         bool b;
118
119         assert(bus);
120         assert(reply);
121         assert(m);
122
123         if (streq(property, "PreparingForShutdown"))
124                 b = !!(m->action_what & INHIBIT_SHUTDOWN);
125         else
126                 b = !!(m->action_what & INHIBIT_SLEEP);
127
128         return sd_bus_message_append(reply, "b", b);
129 }
130
131 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
132
133 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
134         _cleanup_free_ char *p = NULL;
135         Manager *m = userdata;
136         const char *name;
137         Session *session;
138         int r;
139
140         assert(bus);
141         assert(message);
142         assert(m);
143
144         r = sd_bus_message_read(message, "s", &name);
145         if (r < 0)
146                 return r;
147
148         session = hashmap_get(m->sessions, name);
149         if (!session)
150                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
151
152         p = session_bus_path(session);
153         if (!p)
154                 return -ENOMEM;
155
156         return sd_bus_reply_method_return(message, "o", p);
157 }
158
159 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
160         _cleanup_free_ char *p = NULL;
161         Session *session = NULL;
162         Manager *m = userdata;
163         pid_t pid;
164         int r;
165
166         assert(bus);
167         assert(message);
168         assert(m);
169
170         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
171
172         r = sd_bus_message_read(message, "u", &pid);
173         if (r < 0)
174                 return r;
175
176         if (pid == 0) {
177                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
178
179                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
180                 if (r < 0)
181                         return r;
182
183                 r = sd_bus_creds_get_pid(creds, &pid);
184                 if (r < 0)
185                         return r;
186         }
187
188         r = manager_get_session_by_pid(m, pid, &session);
189         if (r < 0)
190                 return r;
191         if (!session)
192                 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
193
194         p = session_bus_path(session);
195         if (!p)
196                 return -ENOMEM;
197
198         return sd_bus_reply_method_return(message, "o", p);
199 }
200
201 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
202         _cleanup_free_ char *p = NULL;
203         Manager *m = userdata;
204         uint32_t uid;
205         User *user;
206         int r;
207
208         assert(bus);
209         assert(message);
210         assert(m);
211
212         r = sd_bus_message_read(message, "u", &uid);
213         if (r < 0)
214                 return r;
215
216         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
217         if (!user)
218                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
219
220         p = user_bus_path(user);
221         if (!p)
222                 return -ENOMEM;
223
224         return sd_bus_reply_method_return(message, "o", p);
225 }
226
227 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
228         _cleanup_free_ char *p = NULL;
229         Manager *m = userdata;
230         User *user = NULL;
231         pid_t pid;
232         int r;
233
234         assert(bus);
235         assert(message);
236         assert(m);
237
238         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
239
240         r = sd_bus_message_read(message, "u", &pid);
241         if (r < 0)
242                 return r;
243
244         if (pid == 0) {
245                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
246
247                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
248                 if (r < 0)
249                         return r;
250
251                 r = sd_bus_creds_get_pid(creds, &pid);
252                 if (r < 0)
253                         return r;
254         }
255
256         r = manager_get_user_by_pid(m, pid, &user);
257         if (r < 0)
258                 return r;
259         if (!user)
260                 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
261
262         p = user_bus_path(user);
263         if (!p)
264                 return -ENOMEM;
265
266         return sd_bus_reply_method_return(message, "o", p);
267 }
268
269 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
270         _cleanup_free_ char *p = NULL;
271         Manager *m = userdata;
272         const char *name;
273         Seat *seat;
274         int r;
275
276         assert(bus);
277         assert(message);
278         assert(m);
279
280         r = sd_bus_message_read(message, "s", &name);
281         if (r < 0)
282                 return r;
283
284         seat = hashmap_get(m->seats, name);
285         if (!seat)
286                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
287
288         p = seat_bus_path(seat);
289         if (!p)
290                 return -ENOMEM;
291
292         return sd_bus_reply_method_return(message, "o", p);
293 }
294
295 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
296         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
297         Manager *m = userdata;
298         Session *session;
299         Iterator i;
300         int r;
301
302         assert(bus);
303         assert(message);
304         assert(m);
305
306         r = sd_bus_message_new_method_return(message, &reply);
307         if (r < 0)
308                 return r;
309
310         r = sd_bus_message_open_container(reply, 'a', "(susso)");
311         if (r < 0)
312                 return r;
313
314         HASHMAP_FOREACH(session, m->sessions, i) {
315                 _cleanup_free_ char *p = NULL;
316
317                 p = session_bus_path(session);
318                 if (!p)
319                         return -ENOMEM;
320
321                 r = sd_bus_message_append(reply, "(susso)",
322                                           session->id,
323                                           (uint32_t) session->user->uid,
324                                           session->user->name,
325                                           session->seat ? session->seat->id : "",
326                                           p);
327                 if (r < 0)
328                         return r;
329         }
330
331         r = sd_bus_message_close_container(reply);
332         if (r < 0)
333                 return r;
334
335         return sd_bus_send(bus, reply, NULL);
336 }
337
338 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
339         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
340         Manager *m = userdata;
341         User *user;
342         Iterator i;
343         int r;
344
345         assert(bus);
346         assert(message);
347         assert(m);
348
349         r = sd_bus_message_new_method_return(message, &reply);
350         if (r < 0)
351                 return r;
352
353         r = sd_bus_message_open_container(reply, 'a', "(uso)");
354         if (r < 0)
355                 return r;
356
357         HASHMAP_FOREACH(user, m->users, i) {
358                 _cleanup_free_ char *p = NULL;
359
360                 p = user_bus_path(user);
361                 if (!p)
362                         return -ENOMEM;
363
364                 r = sd_bus_message_append(reply, "(uso)",
365                                           (uint32_t) user->uid,
366                                           user->name,
367                                           p);
368                 if (r < 0)
369                         return r;
370         }
371
372         r = sd_bus_message_close_container(reply);
373         if (r < 0)
374                 return r;
375
376         return sd_bus_send(bus, reply, NULL);
377 }
378
379 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
380         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
381         Manager *m = userdata;
382         Seat *seat;
383         Iterator i;
384         int r;
385
386         assert(bus);
387         assert(message);
388         assert(m);
389
390         r = sd_bus_message_new_method_return(message, &reply);
391         if (r < 0)
392                 return r;
393
394         r = sd_bus_message_open_container(reply, 'a', "(so)");
395         if (r < 0)
396                 return r;
397
398         HASHMAP_FOREACH(seat, m->seats, i) {
399                 _cleanup_free_ char *p = NULL;
400
401                 p = seat_bus_path(seat);
402                 if (!p)
403                         return -ENOMEM;
404
405                 r = sd_bus_message_append(reply, "(so)", seat->id, p);
406                 if (r < 0)
407                         return r;
408         }
409
410         r = sd_bus_message_close_container(reply);
411         if (r < 0)
412                 return r;
413
414         return sd_bus_send(bus, reply, NULL);
415 }
416
417 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
418         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
419         Manager *m = userdata;
420         Inhibitor *inhibitor;
421         Iterator i;
422         int r;
423
424         r = sd_bus_message_new_method_return(message, &reply);
425         if (r < 0)
426                 return r;
427
428         r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
429         if (r < 0)
430                 return r;
431
432         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
433
434                 r = sd_bus_message_append(reply, "(ssssuu)",
435                                           strempty(inhibit_what_to_string(inhibitor->what)),
436                                           strempty(inhibitor->who),
437                                           strempty(inhibitor->why),
438                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
439                                           (uint32_t) inhibitor->uid,
440                                           (uint32_t) inhibitor->pid);
441                 if (r < 0)
442                         return r;
443         }
444
445         r = sd_bus_message_close_container(reply);
446         if (r < 0)
447                 return r;
448
449         return sd_bus_send(bus, reply, NULL);
450 }
451
452 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453         const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
454         uint32_t uid, leader, audit_id = 0;
455         _cleanup_free_ char *id = NULL;
456         Session *session = NULL;
457         Manager *m = userdata;
458         User *user = NULL;
459         Seat *seat = NULL;
460         int remote;
461         uint32_t vtnr = 0;
462         SessionType t;
463         SessionClass c;
464         int r;
465
466         assert(bus);
467         assert(message);
468         assert(m);
469
470         r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
471         if (r < 0)
472                 return r;
473
474         if (leader == 1)
475                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
476
477         if (isempty(type))
478                 t = _SESSION_TYPE_INVALID;
479         else {
480                 t = session_type_from_string(type);
481                 if (t < 0)
482                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
483         }
484
485         if (isempty(class))
486                 c = _SESSION_CLASS_INVALID;
487         else {
488                 c = session_class_from_string(class);
489                 if (c < 0)
490                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
491         }
492
493         if (isempty(desktop))
494                 desktop = NULL;
495         else {
496                 if (!string_is_safe(desktop))
497                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
498         }
499
500         if (isempty(cseat))
501                 seat = NULL;
502         else {
503                 seat = hashmap_get(m->seats, cseat);
504                 if (!seat)
505                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
506         }
507
508         if (tty_is_vc(tty)) {
509                 int v;
510
511                 if (!seat)
512                         seat = m->seat0;
513                 else if (seat != m->seat0)
514                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
515
516                 v = vtnr_from_tty(tty);
517                 if (v <= 0)
518                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
519
520                 if (!vtnr)
521                         vtnr = (uint32_t) v;
522                 else if (vtnr != (uint32_t) v)
523                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
524
525         } else if (tty_is_console(tty)) {
526
527                 if (!seat)
528                         seat = m->seat0;
529                 else if (seat != m->seat0)
530                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
531
532                 if (vtnr != 0)
533                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
534         }
535
536         if (seat) {
537                 if (seat_has_vts(seat)) {
538                         if (!vtnr || vtnr > 63)
539                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
540                 } else {
541                         if (vtnr != 0)
542                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
543                 }
544         }
545
546         r = sd_bus_message_enter_container(message, 'a', "(sv)");
547         if (r < 0)
548                 return r;
549
550         if (t == _SESSION_TYPE_INVALID) {
551                 if (!isempty(display))
552                         t = SESSION_X11;
553                 else if (!isempty(tty))
554                         t = SESSION_TTY;
555                 else
556                         t = SESSION_UNSPECIFIED;
557         }
558
559         if (c == _SESSION_CLASS_INVALID) {
560                 if (t == SESSION_UNSPECIFIED)
561                         c = SESSION_BACKGROUND;
562                 else
563                         c = SESSION_USER;
564         }
565
566         if (leader <= 0) {
567                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
568
569                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
570                 if (r < 0)
571                         return r;
572
573                 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
574
575                 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
576                 if (r < 0)
577                         return r;
578         }
579
580         manager_get_session_by_pid(m, leader, &session);
581         if (session) {
582                 _cleanup_free_ char *path = NULL;
583                 _cleanup_close_ int fifo_fd = -1;
584
585                 /* Session already exists, client is probably
586                  * something like "su" which changes uid but is still
587                  * the same session */
588
589                 fifo_fd = session_create_fifo(session);
590                 if (fifo_fd < 0)
591                         return fifo_fd;
592
593                 path = session_bus_path(session);
594                 if (!path)
595                         return -ENOMEM;
596
597                 log_debug("Sending reply about an existing session: "
598                           "id=%s object_path=%s uid=%u runtime_path=%s "
599                           "session_fd=%d seat=%s vtnr=%u",
600                           session->id,
601                           path,
602                           (uint32_t) session->user->uid,
603                           session->user->runtime_path,
604                           fifo_fd,
605                           session->seat ? session->seat->id : "",
606                           (uint32_t) session->vtnr);
607
608                 return sd_bus_reply_method_return(
609                                 message, "soshusub",
610                                 session->id,
611                                 path,
612                                 session->user->runtime_path,
613                                 fifo_fd,
614                                 (uint32_t) session->user->uid,
615                                 session->seat ? session->seat->id : "",
616                                 (uint32_t) session->vtnr,
617                                 true);
618         }
619
620         audit_session_from_pid(leader, &audit_id);
621         if (audit_id > 0) {
622                 /* Keep our session IDs and the audit session IDs in sync */
623
624                 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
625                         return -ENOMEM;
626
627                 /* Wut? There's already a session by this name and we
628                  * didn't find it above? Weird, then let's not trust
629                  * the audit data and let's better register a new
630                  * ID */
631                 if (hashmap_get(m->sessions, id)) {
632                         log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
633                         audit_id = 0;
634
635                         free(id);
636                         id = NULL;
637                 }
638         }
639
640         if (!id) {
641                 do {
642                         free(id);
643                         id = NULL;
644
645                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
646                                 return -ENOMEM;
647
648                 } while (hashmap_get(m->sessions, id));
649         }
650
651         r = manager_add_user_by_uid(m, uid, &user);
652         if (r < 0)
653                 goto fail;
654
655         r = manager_add_session(m, id, &session);
656         if (r < 0)
657                 goto fail;
658
659         session_set_user(session, user);
660
661         session->leader = leader;
662         session->audit_id = audit_id;
663         session->type = t;
664         session->class = c;
665         session->remote = remote;
666         session->vtnr = vtnr;
667
668         if (!isempty(tty)) {
669                 session->tty = strdup(tty);
670                 if (!session->tty) {
671                         r = -ENOMEM;
672                         goto fail;
673                 }
674         }
675
676         if (!isempty(display)) {
677                 session->display = strdup(display);
678                 if (!session->display) {
679                         r = -ENOMEM;
680                         goto fail;
681                 }
682         }
683
684         if (!isempty(remote_user)) {
685                 session->remote_user = strdup(remote_user);
686                 if (!session->remote_user) {
687                         r = -ENOMEM;
688                         goto fail;
689                 }
690         }
691
692         if (!isempty(remote_host)) {
693                 session->remote_host = strdup(remote_host);
694                 if (!session->remote_host) {
695                         r = -ENOMEM;
696                         goto fail;
697                 }
698         }
699
700         if (!isempty(service)) {
701                 session->service = strdup(service);
702                 if (!session->service) {
703                         r = -ENOMEM;
704                         goto fail;
705                 }
706         }
707
708         if (!isempty(desktop)) {
709                 session->desktop = strdup(desktop);
710                 if (!session->desktop) {
711                         r = -ENOMEM;
712                         goto fail;
713                 }
714         }
715
716         if (seat) {
717                 r = seat_attach_session(seat, session);
718                 if (r < 0)
719                         goto fail;
720         }
721
722         r = session_start(session);
723         if (r < 0)
724                 goto fail;
725
726         session->create_message = sd_bus_message_ref(message);
727
728         /* Now, let's wait until the slice unit and stuff got
729          * created. We send the reply back from
730          * session_send_create_reply().*/
731
732         return 1;
733
734 fail:
735         if (session)
736                 session_add_to_gc_queue(session);
737
738         if (user)
739                 user_add_to_gc_queue(user);
740
741         return r;
742 }
743
744 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
745         Manager *m = userdata;
746         Session *session;
747         const char *name;
748         int r;
749
750         assert(bus);
751         assert(message);
752         assert(m);
753
754         r = sd_bus_message_read(message, "s", &name);
755         if (r < 0)
756                 return r;
757
758         session = hashmap_get(m->sessions, name);
759         if (!session)
760                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
761
762         session_release(session);
763
764         return sd_bus_reply_method_return(message, NULL);
765 }
766
767 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
768         Manager *m = userdata;
769         Session *session;
770         const char *name;
771         int r;
772
773         assert(bus);
774         assert(message);
775         assert(m);
776
777         r = sd_bus_message_read(message, "s", &name);
778         if (r < 0)
779                 return r;
780
781         session = hashmap_get(m->sessions, name);
782         if (!session)
783                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
784
785         r = session_activate(session);
786         if (r < 0)
787                 return r;
788
789         return sd_bus_reply_method_return(message, NULL);
790 }
791
792 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
793         const char *session_name, *seat_name;
794         Manager *m = userdata;
795         Session *session;
796         Seat *seat;
797         int r;
798
799         assert(bus);
800         assert(message);
801         assert(m);
802
803         /* Same as ActivateSession() but refuses to work if
804          * the seat doesn't match */
805
806         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
807         if (r < 0)
808                 return r;
809
810         session = hashmap_get(m->sessions, session_name);
811         if (!session)
812                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
813
814         seat = hashmap_get(m->seats, seat_name);
815         if (!seat)
816                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
817
818         if (session->seat != seat)
819                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
820
821         r = session_activate(session);
822         if (r < 0)
823                 return r;
824
825         return sd_bus_reply_method_return(message, NULL);
826 }
827
828 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
829         Manager *m = userdata;
830         Session *session;
831         const char *name;
832         int r;
833
834         assert(bus);
835         assert(message);
836         assert(m);
837
838         r = sd_bus_message_read(message, "s", &name);
839         if (r < 0)
840                 return r;
841
842         session = hashmap_get(m->sessions, name);
843         if (!session)
844                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
845
846         r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
847         if (r < 0)
848                 return r;
849
850         return sd_bus_reply_method_return(message, NULL);
851 }
852
853 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
854         Manager *m = userdata;
855         int r;
856
857         assert(bus);
858         assert(message);
859         assert(m);
860
861         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
862         if (r < 0)
863                 return r;
864
865         return sd_bus_reply_method_return(message, NULL);
866 }
867
868 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
869         const char *name, *swho;
870         Manager *m = userdata;
871         Session *session;
872         int32_t signo;
873         KillWho who;
874         int r;
875
876         assert(bus);
877         assert(message);
878         assert(m);
879
880         r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
881         if (r < 0)
882                 return r;
883
884         if (isempty(swho))
885                 who = KILL_ALL;
886         else {
887                 who = kill_who_from_string(swho);
888                 if (who < 0)
889                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
890         }
891
892         if (signo <= 0 || signo >= _NSIG)
893                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
894
895         session = hashmap_get(m->sessions, name);
896         if (!session)
897                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
898
899         r = session_kill(session, who, signo);
900         if (r < 0)
901                 return r;
902
903         return sd_bus_reply_method_return(message, NULL);
904 }
905
906 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
907         Manager *m = userdata;
908         uint32_t uid;
909         int32_t signo;
910         User *user;
911         int r;
912
913         assert(bus);
914         assert(message);
915         assert(m);
916
917         r = sd_bus_message_read(message, "ui", &uid, &signo);
918         if (r < 0)
919                 return r;
920
921         if (signo <= 0 || signo >= _NSIG)
922                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
923
924         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
925         if (!user)
926                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
927
928         r = user_kill(user, signo);
929         if (r < 0)
930                 return r;
931
932         return sd_bus_reply_method_return(message, NULL);
933 }
934
935 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
936         Manager *m = userdata;
937         const char *name;
938         Session *session;
939         int r;
940
941         assert(bus);
942         assert(message);
943         assert(m);
944
945         r = sd_bus_message_read(message, "s", &name);
946         if (r < 0)
947                 return r;
948
949         session = hashmap_get(m->sessions, name);
950         if (!session)
951                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
952
953         r = session_stop(session, true);
954         if (r < 0)
955                 return r;
956
957         return sd_bus_reply_method_return(message, NULL);
958 }
959
960 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
961         Manager *m = userdata;
962         uint32_t uid;
963         User *user;
964         int r;
965
966         assert(bus);
967         assert(message);
968         assert(m);
969
970         r = sd_bus_message_read(message, "u", &uid);
971         if (r < 0)
972                 return r;
973
974         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
975         if (!user)
976                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
977
978         r = user_stop(user, true);
979         if (r < 0)
980                 return r;
981
982         return sd_bus_reply_method_return(message, NULL);
983 }
984
985 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
986         Manager *m = userdata;
987         const char *name;
988         Seat *seat;
989         int r;
990
991         assert(bus);
992         assert(message);
993         assert(m);
994
995         r = sd_bus_message_read(message, "s", &name);
996         if (r < 0)
997                 return r;
998
999         seat = hashmap_get(m->seats, name);
1000         if (!seat)
1001                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
1002
1003         r = seat_stop_sessions(seat, true);
1004         if (r < 0)
1005                 return r;
1006
1007         return sd_bus_reply_method_return(message, NULL);
1008 }
1009
1010 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1011         _cleanup_free_ char *cc = NULL;
1012         Manager *m = userdata;
1013         int b, r;
1014         struct passwd *pw;
1015         const char *path;
1016         uint32_t uid;
1017         int interactive;
1018
1019         assert(bus);
1020         assert(message);
1021         assert(m);
1022
1023         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1024         if (r < 0)
1025                 return r;
1026
1027         errno = 0;
1028         pw = getpwuid(uid);
1029         if (!pw)
1030                 return errno ? -errno : -ENOENT;
1031
1032         r = bus_verify_polkit_async(bus,
1033                                     &m->polkit_registry,
1034                                     message,
1035                                     "org.freedesktop.login1.set-user-linger",
1036                                     interactive,
1037                                     error,
1038                                     method_set_user_linger, m);
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(bus,
1205                                     &m->polkit_registry,
1206                                     message,
1207                                     "org.freedesktop.login1.attach-device",
1208                                     interactive,
1209                                     error,
1210                                     method_attach_device, m);
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(bus,
1236                                     &m->polkit_registry,
1237                                     message,
1238                                     "org.freedesktop.login1.flush-devices",
1239                                     interactive,
1240                                     error,
1241                                     method_flush_devices, m);
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(m->bus, &m->polkit_registry, message,
1536                                             action_multiple_sessions, interactive, error, method, m);
1537                 if (r < 0)
1538                         return r;
1539                 if (r == 0)
1540                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1541         }
1542
1543         if (blocked) {
1544                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1545                                             action_ignore_inhibit, interactive, error, method, m);
1546                 if (r < 0)
1547                         return r;
1548                 if (r == 0)
1549                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1550         }
1551
1552         if (!multiple_sessions && !blocked) {
1553                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1554                                             action, interactive, error, method, m);
1555                 if (r < 0)
1556                         return r;
1557                 if (r == 0)
1558                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1559         }
1560
1561         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1562         if (r < 0)
1563                 return r;
1564
1565         return sd_bus_reply_method_return(message, NULL);
1566 }
1567
1568 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1569         Manager *m = userdata;
1570
1571         return method_do_shutdown_or_sleep(
1572                         m, message,
1573                         SPECIAL_POWEROFF_TARGET,
1574                         INHIBIT_SHUTDOWN,
1575                         "org.freedesktop.login1.power-off",
1576                         "org.freedesktop.login1.power-off-multiple-sessions",
1577                         "org.freedesktop.login1.power-off-ignore-inhibit",
1578                         NULL,
1579                         method_poweroff,
1580                         error);
1581 }
1582
1583 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1584         Manager *m = userdata;
1585
1586         return method_do_shutdown_or_sleep(
1587                         m, message,
1588                         SPECIAL_REBOOT_TARGET,
1589                         INHIBIT_SHUTDOWN,
1590                         "org.freedesktop.login1.reboot",
1591                         "org.freedesktop.login1.reboot-multiple-sessions",
1592                         "org.freedesktop.login1.reboot-ignore-inhibit",
1593                         NULL,
1594                         method_reboot,
1595                         error);
1596 }
1597
1598 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1599         Manager *m = userdata;
1600
1601         return method_do_shutdown_or_sleep(
1602                         m, message,
1603                         SPECIAL_SUSPEND_TARGET,
1604                         INHIBIT_SLEEP,
1605                         "org.freedesktop.login1.suspend",
1606                         "org.freedesktop.login1.suspend-multiple-sessions",
1607                         "org.freedesktop.login1.suspend-ignore-inhibit",
1608                         "suspend",
1609                         method_suspend,
1610                         error);
1611 }
1612
1613 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1614         Manager *m = userdata;
1615
1616         return method_do_shutdown_or_sleep(
1617                         m, message,
1618                         SPECIAL_HIBERNATE_TARGET,
1619                         INHIBIT_SLEEP,
1620                         "org.freedesktop.login1.hibernate",
1621                         "org.freedesktop.login1.hibernate-multiple-sessions",
1622                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1623                         "hibernate",
1624                         method_hibernate,
1625                         error);
1626 }
1627
1628 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1629         Manager *m = userdata;
1630
1631         return method_do_shutdown_or_sleep(
1632                         m, message,
1633                         SPECIAL_HYBRID_SLEEP_TARGET,
1634                         INHIBIT_SLEEP,
1635                         "org.freedesktop.login1.hibernate",
1636                         "org.freedesktop.login1.hibernate-multiple-sessions",
1637                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1638                         "hybrid-sleep",
1639                         method_hybrid_sleep,
1640                         error);
1641 }
1642
1643 static int method_can_shutdown_or_sleep(
1644                 Manager *m,
1645                 sd_bus_message *message,
1646                 InhibitWhat w,
1647                 const char *action,
1648                 const char *action_multiple_sessions,
1649                 const char *action_ignore_inhibit,
1650                 const char *sleep_verb,
1651                 sd_bus_error *error) {
1652
1653         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1654         bool multiple_sessions, challenge, blocked;
1655         const char *result = NULL;
1656         uid_t uid;
1657         int r;
1658
1659         assert(m);
1660         assert(message);
1661         assert(w >= 0);
1662         assert(w <= _INHIBIT_WHAT_MAX);
1663         assert(action);
1664         assert(action_multiple_sessions);
1665         assert(action_ignore_inhibit);
1666
1667         if (sleep_verb) {
1668                 r = can_sleep(sleep_verb);
1669                 if (r < 0)
1670                         return r;
1671                 if (r == 0)
1672                         return sd_bus_reply_method_return(message, "s", "na");
1673         }
1674
1675         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1676         if (r < 0)
1677                 return r;
1678
1679         r = sd_bus_creds_get_uid(creds, &uid);
1680         if (r < 0)
1681                 return r;
1682
1683         r = have_multiple_sessions(m, uid);
1684         if (r < 0)
1685                 return r;
1686
1687         multiple_sessions = r > 0;
1688         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1689
1690         if (multiple_sessions) {
1691                 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1692                 if (r < 0)
1693                         return r;
1694
1695                 if (r > 0)
1696                         result = "yes";
1697                 else if (challenge)
1698                         result = "challenge";
1699                 else
1700                         result = "no";
1701         }
1702
1703         if (blocked) {
1704                 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1705                 if (r < 0)
1706                         return r;
1707
1708                 if (r > 0 && !result)
1709                         result = "yes";
1710                 else if (challenge && (!result || streq(result, "yes")))
1711                         result = "challenge";
1712                 else
1713                         result = "no";
1714         }
1715
1716         if (!multiple_sessions && !blocked) {
1717                 /* If neither inhibit nor multiple sessions
1718                  * apply then just check the normal policy */
1719
1720                 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1721                 if (r < 0)
1722                         return r;
1723
1724                 if (r > 0)
1725                         result = "yes";
1726                 else if (challenge)
1727                         result = "challenge";
1728                 else
1729                         result = "no";
1730         }
1731
1732         return sd_bus_reply_method_return(message, "s", result);
1733 }
1734
1735 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1736         Manager *m = userdata;
1737
1738         return method_can_shutdown_or_sleep(
1739                         m, message,
1740                         INHIBIT_SHUTDOWN,
1741                         "org.freedesktop.login1.power-off",
1742                         "org.freedesktop.login1.power-off-multiple-sessions",
1743                         "org.freedesktop.login1.power-off-ignore-inhibit",
1744                         NULL,
1745                         error);
1746 }
1747
1748 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1749         Manager *m = userdata;
1750
1751         return method_can_shutdown_or_sleep(
1752                         m, message,
1753                         INHIBIT_SHUTDOWN,
1754                         "org.freedesktop.login1.reboot",
1755                         "org.freedesktop.login1.reboot-multiple-sessions",
1756                         "org.freedesktop.login1.reboot-ignore-inhibit",
1757                         NULL,
1758                         error);
1759 }
1760
1761 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1762         Manager *m = userdata;
1763
1764         return method_can_shutdown_or_sleep(
1765                         m, message,
1766                         INHIBIT_SLEEP,
1767                         "org.freedesktop.login1.suspend",
1768                         "org.freedesktop.login1.suspend-multiple-sessions",
1769                         "org.freedesktop.login1.suspend-ignore-inhibit",
1770                         "suspend",
1771                         error);
1772 }
1773
1774 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1775         Manager *m = userdata;
1776
1777         return method_can_shutdown_or_sleep(
1778                         m, message,
1779                         INHIBIT_SLEEP,
1780                         "org.freedesktop.login1.hibernate",
1781                         "org.freedesktop.login1.hibernate-multiple-sessions",
1782                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1783                         "hibernate",
1784                         error);
1785 }
1786
1787 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1788         Manager *m = userdata;
1789
1790         return method_can_shutdown_or_sleep(
1791                         m, message,
1792                         INHIBIT_SLEEP,
1793                         "org.freedesktop.login1.hibernate",
1794                         "org.freedesktop.login1.hibernate-multiple-sessions",
1795                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1796                         "hybrid-sleep",
1797                         error);
1798 }
1799
1800 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1801         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1802         const char *who, *why, *what, *mode;
1803         _cleanup_free_ char *id = NULL;
1804         _cleanup_close_ int fifo_fd = -1;
1805         Manager *m = userdata;
1806         Inhibitor *i = NULL;
1807         InhibitMode mm;
1808         InhibitWhat w;
1809         pid_t pid;
1810         uid_t uid;
1811         int r;
1812
1813         assert(bus);
1814         assert(message);
1815         assert(m);
1816
1817         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1818         if (r < 0)
1819                 return r;
1820
1821         w = inhibit_what_from_string(what);
1822         if (w <= 0)
1823                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1824
1825         mm = inhibit_mode_from_string(mode);
1826         if (mm < 0)
1827                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1828
1829         /* Delay is only supported for shutdown/sleep */
1830         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1831                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1832
1833         /* Don't allow taking delay locks while we are already
1834          * executing the operation. We shouldn't create the impression
1835          * that the lock was successful if the machine is about to go
1836          * down/suspend any moment. */
1837         if (m->action_what & w)
1838                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1839
1840         r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1841                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1842                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
1843                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
1844                                     w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
1845                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1846                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1847                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
1848                                     false, error, method_inhibit, m);
1849         if (r < 0)
1850                 return r;
1851         if (r == 0)
1852                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1853
1854         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1855         if (r < 0)
1856                 return r;
1857
1858         r = sd_bus_creds_get_uid(creds, &uid);
1859         if (r < 0)
1860                 return r;
1861
1862         r = sd_bus_creds_get_pid(creds, &pid);
1863         if (r < 0)
1864                 return r;
1865
1866         do {
1867                 free(id);
1868                 id = NULL;
1869
1870                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1871                         return -ENOMEM;
1872
1873         } while (hashmap_get(m->inhibitors, id));
1874
1875         r = manager_add_inhibitor(m, id, &i);
1876         if (r < 0)
1877                 return r;
1878
1879         i->what = w;
1880         i->mode = mm;
1881         i->pid = pid;
1882         i->uid = uid;
1883         i->why = strdup(why);
1884         i->who = strdup(who);
1885
1886         if (!i->why || !i->who) {
1887                 r = -ENOMEM;
1888                 goto fail;
1889         }
1890
1891         fifo_fd = inhibitor_create_fifo(i);
1892         if (fifo_fd < 0) {
1893                 r = fifo_fd;
1894                 goto fail;
1895         }
1896
1897         inhibitor_start(i);
1898
1899         return sd_bus_reply_method_return(message, "h", fifo_fd);
1900
1901 fail:
1902         if (i)
1903                 inhibitor_free(i);
1904
1905         return r;
1906 }
1907
1908 const sd_bus_vtable manager_vtable[] = {
1909         SD_BUS_VTABLE_START(0),
1910
1911         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1912         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1913         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1914         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1915         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1916         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1917         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1918         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1919         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1920         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1921         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1922         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1923         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1924         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1925         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1926         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1927         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1928         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1929
1930         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1931         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1932         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1933         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1934         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1935         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1936         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1937         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1938         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1939         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1940         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1941         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1942         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1943         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1944         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1945         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1946         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1947         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1948         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1949         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1950         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1951         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1952         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1953         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1954         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1955         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1956         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1957         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1958         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1959         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1960         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1961         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1962         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1963         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1964         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1965         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1966
1967         SD_BUS_SIGNAL("SessionNew", "so", 0),
1968         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1969         SD_BUS_SIGNAL("UserNew", "uo", 0),
1970         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1971         SD_BUS_SIGNAL("SeatNew", "so", 0),
1972         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1973         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1974         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1975
1976         SD_BUS_VTABLE_END
1977 };
1978
1979 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1980         int r = 0;
1981
1982         assert(s);
1983         assert(unit);
1984
1985         if (!s->started)
1986                 return r;
1987
1988         if (streq(result, "done"))
1989                 r = session_send_create_reply(s, NULL);
1990         else {
1991                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1992
1993                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1994                 r = session_send_create_reply(s, &e);
1995         }
1996
1997         return r;
1998 }
1999
2000 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2001         const char *path, *result, *unit;
2002         Manager *m = userdata;
2003         Session *session;
2004         uint32_t id;
2005         User *user;
2006         int r;
2007
2008         assert(bus);
2009         assert(message);
2010         assert(m);
2011
2012         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2013         if (r < 0) {
2014                 bus_log_parse_error(r);
2015                 return r;
2016         }
2017
2018         if (m->action_job && streq(m->action_job, path)) {
2019                 log_info("Operation finished.");
2020
2021                 /* Tell people that they now may take a lock again */
2022                 send_prepare_for(m, m->action_what, false);
2023
2024                 free(m->action_job);
2025                 m->action_job = NULL;
2026                 m->action_unit = NULL;
2027                 m->action_what = 0;
2028                 return 0;
2029         }
2030
2031         session = hashmap_get(m->session_units, unit);
2032         if (session) {
2033
2034                 if (streq_ptr(path, session->scope_job)) {
2035                         free(session->scope_job);
2036                         session->scope_job = NULL;
2037                 }
2038
2039                 session_jobs_reply(session, unit, result);
2040
2041                 session_save(session);
2042                 session_add_to_gc_queue(session);
2043         }
2044
2045         user = hashmap_get(m->user_units, unit);
2046         if (user) {
2047
2048                 if (streq_ptr(path, user->service_job)) {
2049                         free(user->service_job);
2050                         user->service_job = NULL;
2051                 }
2052
2053                 if (streq_ptr(path, user->slice_job)) {
2054                         free(user->slice_job);
2055                         user->slice_job = NULL;
2056                 }
2057
2058                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2059                         session_jobs_reply(session, unit, result);
2060                 }
2061
2062                 user_save(user);
2063                 user_add_to_gc_queue(user);
2064         }
2065
2066         return 0;
2067 }
2068
2069 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2070         const char *path, *unit;
2071         Manager *m = userdata;
2072         Session *session;
2073         User *user;
2074         int r;
2075
2076         assert(bus);
2077         assert(message);
2078         assert(m);
2079
2080         r = sd_bus_message_read(message, "so", &unit, &path);
2081         if (r < 0) {
2082                 bus_log_parse_error(r);
2083                 return r;
2084         }
2085
2086         session = hashmap_get(m->session_units, unit);
2087         if (session)
2088                 session_add_to_gc_queue(session);
2089
2090         user = hashmap_get(m->user_units, unit);
2091         if (user)
2092                 user_add_to_gc_queue(user);
2093
2094         return 0;
2095 }
2096
2097 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2098         _cleanup_free_ char *unit = NULL;
2099         Manager *m = userdata;
2100         const char *path;
2101         Session *session;
2102         User *user;
2103         int r;
2104
2105         assert(bus);
2106         assert(message);
2107         assert(m);
2108
2109         path = sd_bus_message_get_path(message);
2110         if (!path)
2111                 return 0;
2112
2113         r = unit_name_from_dbus_path(path, &unit);
2114         if (r < 0)
2115                 /* quietly ignore non-units paths */
2116                 return r == -EINVAL ? 0 : r;
2117
2118         session = hashmap_get(m->session_units, unit);
2119         if (session)
2120                 session_add_to_gc_queue(session);
2121
2122         user = hashmap_get(m->user_units, unit);
2123         if (user)
2124                 user_add_to_gc_queue(user);
2125
2126         return 0;
2127 }
2128
2129 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2130         Manager *m = userdata;
2131         Session *session;
2132         Iterator i;
2133         int b, r;
2134
2135         assert(bus);
2136
2137         r = sd_bus_message_read(message, "b", &b);
2138         if (r < 0) {
2139                 bus_log_parse_error(r);
2140                 return r;
2141         }
2142
2143         if (b)
2144                 return 0;
2145
2146         /* systemd finished reloading, let's recheck all our sessions */
2147         log_debug("System manager has been reloaded, rechecking sessions...");
2148
2149         HASHMAP_FOREACH(session, m->sessions, i)
2150                 session_add_to_gc_queue(session);
2151
2152         return 0;
2153 }
2154
2155 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2156         const char *name, *old, *new;
2157         Manager *m = userdata;
2158         Session *session;
2159         Iterator i;
2160         int r;
2161
2162
2163         char *key;
2164
2165         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2166         if (r < 0) {
2167                 bus_log_parse_error(r);
2168                 return r;
2169         }
2170
2171         if (isempty(old) || !isempty(new))
2172                 return 0;
2173
2174         key = set_remove(m->busnames, (char*) old);
2175         if (!key)
2176                 return 0;
2177
2178         /* Drop all controllers owned by this name */
2179
2180         free(key);
2181
2182         HASHMAP_FOREACH(session, m->sessions, i)
2183                 if (session_is_controller(session, old))
2184                         session_drop_controller(session);
2185
2186         return 0;
2187 }
2188
2189 int manager_send_changed(Manager *manager, const char *property, ...) {
2190         char **l;
2191
2192         assert(manager);
2193
2194         l = strv_from_stdarg_alloca(property);
2195
2196         return sd_bus_emit_properties_changed_strv(
2197                         manager->bus,
2198                         "/org/freedesktop/login1",
2199                         "org.freedesktop.login1.Manager",
2200                         l);
2201 }
2202
2203 int manager_dispatch_delayed(Manager *manager) {
2204         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2205         Inhibitor *offending = NULL;
2206         int r;
2207
2208         assert(manager);
2209
2210         if (manager->action_what == 0 || manager->action_job)
2211                 return 0;
2212
2213         /* Continue delay? */
2214         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2215                 _cleanup_free_ char *comm = NULL, *u = NULL;
2216
2217                 get_process_comm(offending->pid, &comm);
2218                 u = uid_to_name(offending->uid);
2219
2220                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2221                         return 0;
2222
2223                 log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
2224                          offending->uid, strna(u),
2225                          offending->pid, strna(comm));
2226         }
2227
2228         /* Actually do the operation */
2229         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2230         if (r < 0) {
2231                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2232
2233                 manager->action_unit = NULL;
2234                 manager->action_what = 0;
2235                 return r;
2236         }
2237
2238         return 1;
2239 }
2240
2241 int manager_start_scope(
2242                 Manager *manager,
2243                 const char *scope,
2244                 pid_t pid,
2245                 const char *slice,
2246                 const char *description,
2247                 const char *after, const char *after2,
2248                 sd_bus_error *error,
2249                 char **job) {
2250
2251         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2252         int r;
2253
2254         assert(manager);
2255         assert(scope);
2256         assert(pid > 1);
2257
2258         r = sd_bus_message_new_method_call(
2259                         manager->bus,
2260                         &m,
2261                         "org.freedesktop.systemd1",
2262                         "/org/freedesktop/systemd1",
2263                         "org.freedesktop.systemd1.Manager",
2264                         "StartTransientUnit");
2265         if (r < 0)
2266                 return r;
2267
2268         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2269         if (r < 0)
2270                 return r;
2271
2272         r = sd_bus_message_open_container(m, 'a', "(sv)");
2273         if (r < 0)
2274                 return r;
2275
2276         if (!isempty(slice)) {
2277                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2278                 if (r < 0)
2279                         return r;
2280         }
2281
2282         if (!isempty(description)) {
2283                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2284                 if (r < 0)
2285                         return r;
2286         }
2287
2288         if (!isempty(after)) {
2289                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2290                 if (r < 0)
2291                         return r;
2292         }
2293
2294         if (!isempty(after2)) {
2295                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2296                 if (r < 0)
2297                         return r;
2298         }
2299
2300         /* cgroup empty notification is not available in containers
2301          * currently. To make this less problematic, let's shorten the
2302          * stop timeout for sessions, so that we don't wait
2303          * forever. */
2304
2305         /* Make sure that the session shells are terminated with
2306          * SIGHUP since bash and friends tend to ignore SIGTERM */
2307         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2308         if (r < 0)
2309                 return r;
2310
2311         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2312         if (r < 0)
2313                 return r;
2314
2315         r = sd_bus_message_close_container(m);
2316         if (r < 0)
2317                 return r;
2318
2319         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2320         if (r < 0)
2321                 return r;
2322
2323         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2324         if (r < 0)
2325                 return r;
2326
2327         if (job) {
2328                 const char *j;
2329                 char *copy;
2330
2331                 r = sd_bus_message_read(reply, "o", &j);
2332                 if (r < 0)
2333                         return r;
2334
2335                 copy = strdup(j);
2336                 if (!copy)
2337                         return -ENOMEM;
2338
2339                 *job = copy;
2340         }
2341
2342         return 1;
2343 }
2344
2345 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2346         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2347         int r;
2348
2349         assert(manager);
2350         assert(unit);
2351
2352         r = sd_bus_call_method(
2353                         manager->bus,
2354                         "org.freedesktop.systemd1",
2355                         "/org/freedesktop/systemd1",
2356                         "org.freedesktop.systemd1.Manager",
2357                         "StartUnit",
2358                         error,
2359                         &reply,
2360                         "ss", unit, "fail");
2361         if (r < 0)
2362                 return r;
2363
2364         if (job) {
2365                 const char *j;
2366                 char *copy;
2367
2368                 r = sd_bus_message_read(reply, "o", &j);
2369                 if (r < 0)
2370                         return r;
2371
2372                 copy = strdup(j);
2373                 if (!copy)
2374                         return -ENOMEM;
2375
2376                 *job = copy;
2377         }
2378
2379         return 1;
2380 }
2381
2382 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2383         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2384         int r;
2385
2386         assert(manager);
2387         assert(unit);
2388
2389         r = sd_bus_call_method(
2390                         manager->bus,
2391                         "org.freedesktop.systemd1",
2392                         "/org/freedesktop/systemd1",
2393                         "org.freedesktop.systemd1.Manager",
2394                         "StopUnit",
2395                         error,
2396                         &reply,
2397                         "ss", unit, "fail");
2398         if (r < 0) {
2399                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2400                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2401
2402                         if (job)
2403                                 *job = NULL;
2404
2405                         sd_bus_error_free(error);
2406                         return 0;
2407                 }
2408
2409                 return r;
2410         }
2411
2412         if (job) {
2413                 const char *j;
2414                 char *copy;
2415
2416                 r = sd_bus_message_read(reply, "o", &j);
2417                 if (r < 0)
2418                         return r;
2419
2420                 copy = strdup(j);
2421                 if (!copy)
2422                         return -ENOMEM;
2423
2424                 *job = copy;
2425         }
2426
2427         return 1;
2428 }
2429
2430 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2431         _cleanup_free_ char *path = NULL;
2432         int r;
2433
2434         assert(manager);
2435         assert(scope);
2436
2437         path = unit_dbus_path_from_name(scope);
2438         if (!path)
2439                 return -ENOMEM;
2440
2441         r = sd_bus_call_method(
2442                         manager->bus,
2443                         "org.freedesktop.systemd1",
2444                         path,
2445                         "org.freedesktop.systemd1.Scope",
2446                         "Abandon",
2447                         error,
2448                         NULL,
2449                         NULL);
2450         if (r < 0) {
2451                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2452                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2453                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2454                         sd_bus_error_free(error);
2455                         return 0;
2456                 }
2457
2458                 return r;
2459         }
2460
2461         return 1;
2462 }
2463
2464 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2465         assert(manager);
2466         assert(unit);
2467
2468         return sd_bus_call_method(
2469                         manager->bus,
2470                         "org.freedesktop.systemd1",
2471                         "/org/freedesktop/systemd1",
2472                         "org.freedesktop.systemd1.Manager",
2473                         "KillUnit",
2474                         error,
2475                         NULL,
2476                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2477 }
2478
2479 int manager_unit_is_active(Manager *manager, const char *unit) {
2480         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2481         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2482         _cleanup_free_ char *path = NULL;
2483         const char *state;
2484         int r;
2485
2486         assert(manager);
2487         assert(unit);
2488
2489         path = unit_dbus_path_from_name(unit);
2490         if (!path)
2491                 return -ENOMEM;
2492
2493         r = sd_bus_get_property(
2494                         manager->bus,
2495                         "org.freedesktop.systemd1",
2496                         path,
2497                         "org.freedesktop.systemd1.Unit",
2498                         "ActiveState",
2499                         &error,
2500                         &reply,
2501                         "s");
2502         if (r < 0) {
2503                 /* systemd might have droppped off momentarily, let's
2504                  * not make this an error */
2505                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2506                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2507                         return true;
2508
2509                 /* If the unit is already unloaded then it's not
2510                  * active */
2511                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2512                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2513                         return false;
2514
2515                 return r;
2516         }
2517
2518         r = sd_bus_message_read(reply, "s", &state);
2519         if (r < 0)
2520                 return -EINVAL;
2521
2522         return !streq(state, "inactive") && !streq(state, "failed");
2523 }
2524
2525 int manager_job_is_active(Manager *manager, const char *path) {
2526         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2527         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2528         int r;
2529
2530         assert(manager);
2531         assert(path);
2532
2533         r = sd_bus_get_property(
2534                         manager->bus,
2535                         "org.freedesktop.systemd1",
2536                         path,
2537                         "org.freedesktop.systemd1.Job",
2538                         "State",
2539                         &error,
2540                         &reply,
2541                         "s");
2542         if (r < 0) {
2543                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2544                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2545                         return true;
2546
2547                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2548                         return false;
2549
2550                 return r;
2551         }
2552
2553         /* We don't actually care about the state really. The fact
2554          * that we could read the job state is enough for us */
2555
2556         return true;
2557 }