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