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