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