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