chiark / gitweb /
logind: introduce LockedHint and SetLockedHint (#3238)
[elogind.git] / src / login / logind-dbus.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2011 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <pwd.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "sd-messages.h"
26
27 #include "alloc-util.h"
28 #include "audit-util.h"
29 #include "bus-common-errors.h"
30 #include "bus-error.h"
31 #include "bus-util.h"
32 #include "dirent-util.h"
33 //#include "efivars.h"
34 #include "escape.h"
35 #include "fd-util.h"
36 #include "fileio-label.h"
37 #include "formats-util.h"
38 #include "fs-util.h"
39 #include "logind.h"
40 #include "mkdir.h"
41 #include "path-util.h"
42 #include "process-util.h"
43 #include "selinux-util.h"
44 //#include "sleep-config.h"
45 //#include "special.h"
46 #include "strv.h"
47 #include "terminal-util.h"
48 #include "udev-util.h"
49 #include "unit-name.h"
50 #include "user-util.h"
51 //#include "utmp-wtmp.h"
52
53 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
54         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
55         Session *session;
56         int r;
57
58         assert(m);
59         assert(message);
60         assert(ret);
61
62         if (isempty(name)) {
63                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
64                 if (r < 0)
65                         return r;
66
67                 r = sd_bus_creds_get_session(creds, &name);
68                 if (r < 0)
69                         return r;
70         }
71
72         session = hashmap_get(m->sessions, name);
73         if (!session)
74                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
75
76         *ret = session;
77         return 0;
78 }
79
80 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
81         User *user;
82         int r;
83
84         assert(m);
85         assert(message);
86         assert(ret);
87
88         if (uid == UID_INVALID) {
89                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
90
91                 /* Note that we get the owner UID of the session, not the actual client UID here! */
92                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
93                 if (r < 0)
94                         return r;
95
96                 r = sd_bus_creds_get_owner_uid(creds, &uid);
97                 if (r < 0)
98                         return r;
99         }
100
101         user = hashmap_get(m->users, UID_TO_PTR(uid));
102         if (!user)
103                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
104
105         *ret = user;
106         return 0;
107 }
108
109 int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
110         Seat *seat;
111         int r;
112
113         assert(m);
114         assert(message);
115         assert(ret);
116
117         if (isempty(name)) {
118                 Session *session;
119
120                 r = manager_get_session_from_creds(m, message, NULL, error, &session);
121                 if (r < 0)
122                         return r;
123
124                 seat = session->seat;
125                 if (!seat)
126                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
127         } else {
128                 seat = hashmap_get(m->seats, name);
129                 if (!seat)
130                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
131         }
132
133         *ret = seat;
134         return 0;
135 }
136
137 static int property_get_idle_hint(
138                 sd_bus *bus,
139                 const char *path,
140                 const char *interface,
141                 const char *property,
142                 sd_bus_message *reply,
143                 void *userdata,
144                 sd_bus_error *error) {
145
146         Manager *m = userdata;
147
148         assert(bus);
149         assert(reply);
150         assert(m);
151
152         return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
153 }
154
155 static int property_get_idle_since_hint(
156                 sd_bus *bus,
157                 const char *path,
158                 const char *interface,
159                 const char *property,
160                 sd_bus_message *reply,
161                 void *userdata,
162                 sd_bus_error *error) {
163
164         Manager *m = userdata;
165         dual_timestamp t = DUAL_TIMESTAMP_NULL;
166
167         assert(bus);
168         assert(reply);
169         assert(m);
170
171         manager_get_idle_hint(m, &t);
172
173         return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
174 }
175
176 static int property_get_inhibited(
177                 sd_bus *bus,
178                 const char *path,
179                 const char *interface,
180                 const char *property,
181                 sd_bus_message *reply,
182                 void *userdata,
183                 sd_bus_error *error) {
184
185         Manager *m = userdata;
186         InhibitWhat w;
187
188         assert(bus);
189         assert(reply);
190         assert(m);
191
192         w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
193
194         return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
195 }
196
197 static int property_get_preparing(
198                 sd_bus *bus,
199                 const char *path,
200                 const char *interface,
201                 const char *property,
202                 sd_bus_message *reply,
203                 void *userdata,
204                 sd_bus_error *error) {
205
206         Manager *m = userdata;
207         bool b;
208
209         assert(bus);
210         assert(reply);
211         assert(m);
212
213         if (streq(property, "PreparingForShutdown"))
214                 b = !!(m->action_what & INHIBIT_SHUTDOWN);
215         else
216                 b = !!(m->action_what & INHIBIT_SLEEP);
217
218         return sd_bus_message_append(reply, "b", b);
219 }
220
221 static int property_get_scheduled_shutdown(
222                 sd_bus *bus,
223                 const char *path,
224                 const char *interface,
225                 const char *property,
226                 sd_bus_message *reply,
227                 void *userdata,
228                 sd_bus_error *error) {
229
230         Manager *m = userdata;
231         int r;
232
233         assert(bus);
234         assert(reply);
235         assert(m);
236
237         r = sd_bus_message_open_container(reply, 'r', "st");
238         if (r < 0)
239                 return r;
240
241         r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
242         if (r < 0)
243                 return r;
244
245         return sd_bus_message_close_container(reply);
246 }
247
248 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
249
250 static int property_get_docked(
251                 sd_bus *bus,
252                 const char *path,
253                 const char *interface,
254                 const char *property,
255                 sd_bus_message *reply,
256                 void *userdata,
257                 sd_bus_error *error) {
258
259         Manager *m = userdata;
260
261         assert(bus);
262         assert(reply);
263         assert(m);
264
265         return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
266 }
267
268 static int property_get_current_sessions(
269                 sd_bus *bus,
270                 const char *path,
271                 const char *interface,
272                 const char *property,
273                 sd_bus_message *reply,
274                 void *userdata,
275                 sd_bus_error *error) {
276
277         Manager *m = userdata;
278
279         assert(bus);
280         assert(reply);
281         assert(m);
282
283         return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions));
284 }
285
286 static int property_get_current_inhibitors(
287                 sd_bus *bus,
288                 const char *path,
289                 const char *interface,
290                 const char *property,
291                 sd_bus_message *reply,
292                 void *userdata,
293                 sd_bus_error *error) {
294
295         Manager *m = userdata;
296
297         assert(bus);
298         assert(reply);
299         assert(m);
300
301         return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors));
302 }
303
304 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
305         _cleanup_free_ char *p = NULL;
306         Manager *m = userdata;
307         const char *name;
308         Session *session;
309         int r;
310
311         assert(message);
312         assert(m);
313
314         r = sd_bus_message_read(message, "s", &name);
315         if (r < 0)
316                 return r;
317
318         r = manager_get_session_from_creds(m, message, name, error, &session);
319         if (r < 0)
320                 return r;
321
322         p = session_bus_path(session);
323         if (!p)
324                 return -ENOMEM;
325
326         return sd_bus_reply_method_return(message, "o", p);
327 }
328
329 static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
330         _cleanup_free_ char *p = NULL;
331         Session *session = NULL;
332         Manager *m = userdata;
333         pid_t pid;
334         int r;
335
336         assert(message);
337         assert(m);
338
339         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
340
341         r = sd_bus_message_read(message, "u", &pid);
342         if (r < 0)
343                 return r;
344         if (pid < 0)
345                 return -EINVAL;
346
347         if (pid == 0) {
348                 r = manager_get_session_from_creds(m, message, NULL, error, &session);
349                 if (r < 0)
350                         return r;
351         } else {
352                 r = manager_get_session_by_pid(m, pid, &session);
353                 if (r < 0)
354                         return r;
355
356                 if (!session)
357                         return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
358         }
359
360         p = session_bus_path(session);
361         if (!p)
362                 return -ENOMEM;
363
364         return sd_bus_reply_method_return(message, "o", p);
365 }
366
367 static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
368         _cleanup_free_ char *p = NULL;
369         Manager *m = userdata;
370         uint32_t uid;
371         User *user;
372         int r;
373
374         assert(message);
375         assert(m);
376
377         r = sd_bus_message_read(message, "u", &uid);
378         if (r < 0)
379                 return r;
380
381         r = manager_get_user_from_creds(m, message, uid, error, &user);
382         if (r < 0)
383                 return r;
384
385         p = user_bus_path(user);
386         if (!p)
387                 return -ENOMEM;
388
389         return sd_bus_reply_method_return(message, "o", p);
390 }
391
392 static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
393         _cleanup_free_ char *p = NULL;
394         Manager *m = userdata;
395         User *user = NULL;
396         pid_t pid;
397         int r;
398
399         assert(message);
400         assert(m);
401
402         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
403
404         r = sd_bus_message_read(message, "u", &pid);
405         if (r < 0)
406                 return r;
407         if (pid < 0)
408                 return -EINVAL;
409
410         if (pid == 0) {
411                 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
412                 if (r < 0)
413                         return r;
414         } else {
415                 r = manager_get_user_by_pid(m, pid, &user);
416                 if (r < 0)
417                         return r;
418                 if (!user)
419                         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);
420         }
421
422         p = user_bus_path(user);
423         if (!p)
424                 return -ENOMEM;
425
426         return sd_bus_reply_method_return(message, "o", p);
427 }
428
429 static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
430         _cleanup_free_ char *p = NULL;
431         Manager *m = userdata;
432         const char *name;
433         Seat *seat;
434         int r;
435
436         assert(message);
437         assert(m);
438
439         r = sd_bus_message_read(message, "s", &name);
440         if (r < 0)
441                 return r;
442
443         r = manager_get_seat_from_creds(m, message, name, error, &seat);
444         if (r < 0)
445                 return r;
446
447         p = seat_bus_path(seat);
448         if (!p)
449                 return -ENOMEM;
450
451         return sd_bus_reply_method_return(message, "o", p);
452 }
453
454 static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
455         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
456         Manager *m = userdata;
457         Session *session;
458         Iterator i;
459         int r;
460
461         assert(message);
462         assert(m);
463
464         r = sd_bus_message_new_method_return(message, &reply);
465         if (r < 0)
466                 return r;
467
468         r = sd_bus_message_open_container(reply, 'a', "(susso)");
469         if (r < 0)
470                 return r;
471
472         HASHMAP_FOREACH(session, m->sessions, i) {
473                 _cleanup_free_ char *p = NULL;
474
475                 p = session_bus_path(session);
476                 if (!p)
477                         return -ENOMEM;
478
479                 r = sd_bus_message_append(reply, "(susso)",
480                                           session->id,
481                                           (uint32_t) session->user->uid,
482                                           session->user->name,
483                                           session->seat ? session->seat->id : "",
484                                           p);
485                 if (r < 0)
486                         return r;
487         }
488
489         r = sd_bus_message_close_container(reply);
490         if (r < 0)
491                 return r;
492
493         return sd_bus_send(NULL, reply, NULL);
494 }
495
496 static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
497         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
498         Manager *m = userdata;
499         User *user;
500         Iterator i;
501         int r;
502
503         assert(message);
504         assert(m);
505
506         r = sd_bus_message_new_method_return(message, &reply);
507         if (r < 0)
508                 return r;
509
510         r = sd_bus_message_open_container(reply, 'a', "(uso)");
511         if (r < 0)
512                 return r;
513
514         HASHMAP_FOREACH(user, m->users, i) {
515                 _cleanup_free_ char *p = NULL;
516
517                 p = user_bus_path(user);
518                 if (!p)
519                         return -ENOMEM;
520
521                 r = sd_bus_message_append(reply, "(uso)",
522                                           (uint32_t) user->uid,
523                                           user->name,
524                                           p);
525                 if (r < 0)
526                         return r;
527         }
528
529         r = sd_bus_message_close_container(reply);
530         if (r < 0)
531                 return r;
532
533         return sd_bus_send(NULL, reply, NULL);
534 }
535
536 static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
537         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
538         Manager *m = userdata;
539         Seat *seat;
540         Iterator i;
541         int r;
542
543         assert(message);
544         assert(m);
545
546         r = sd_bus_message_new_method_return(message, &reply);
547         if (r < 0)
548                 return r;
549
550         r = sd_bus_message_open_container(reply, 'a', "(so)");
551         if (r < 0)
552                 return r;
553
554         HASHMAP_FOREACH(seat, m->seats, i) {
555                 _cleanup_free_ char *p = NULL;
556
557                 p = seat_bus_path(seat);
558                 if (!p)
559                         return -ENOMEM;
560
561                 r = sd_bus_message_append(reply, "(so)", seat->id, p);
562                 if (r < 0)
563                         return r;
564         }
565
566         r = sd_bus_message_close_container(reply);
567         if (r < 0)
568                 return r;
569
570         return sd_bus_send(NULL, reply, NULL);
571 }
572
573 static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
574         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
575         Manager *m = userdata;
576         Inhibitor *inhibitor;
577         Iterator i;
578         int r;
579
580         assert(message);
581         assert(m);
582
583         r = sd_bus_message_new_method_return(message, &reply);
584         if (r < 0)
585                 return r;
586
587         r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
588         if (r < 0)
589                 return r;
590
591         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
592
593                 r = sd_bus_message_append(reply, "(ssssuu)",
594                                           strempty(inhibit_what_to_string(inhibitor->what)),
595                                           strempty(inhibitor->who),
596                                           strempty(inhibitor->why),
597                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
598                                           (uint32_t) inhibitor->uid,
599                                           (uint32_t) inhibitor->pid);
600                 if (r < 0)
601                         return r;
602         }
603
604         r = sd_bus_message_close_container(reply);
605         if (r < 0)
606                 return r;
607
608         return sd_bus_send(NULL, reply, NULL);
609 }
610
611 static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
612         const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
613         uint32_t audit_id = 0;
614         _cleanup_free_ char *id = NULL;
615         Session *session = NULL;
616         Manager *m = userdata;
617         User *user = NULL;
618         Seat *seat = NULL;
619         pid_t leader;
620         uid_t uid;
621         int remote;
622         uint32_t vtnr = 0;
623         SessionType t;
624         SessionClass c;
625         int r;
626
627         assert(message);
628         assert(m);
629
630         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
631         assert_cc(sizeof(uid_t) == sizeof(uint32_t));
632
633         r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
634         if (r < 0)
635                 return r;
636
637         if (!uid_is_valid(uid))
638                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID");
639         if (leader < 0 || leader == 1)
640                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
641
642         if (isempty(type))
643                 t = _SESSION_TYPE_INVALID;
644         else {
645                 t = session_type_from_string(type);
646                 if (t < 0)
647                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
648         }
649
650         if (isempty(class))
651                 c = _SESSION_CLASS_INVALID;
652         else {
653                 c = session_class_from_string(class);
654                 if (c < 0)
655                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
656         }
657
658         if (isempty(desktop))
659                 desktop = NULL;
660         else {
661                 if (!string_is_safe(desktop))
662                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
663         }
664
665         if (isempty(cseat))
666                 seat = NULL;
667         else {
668                 seat = hashmap_get(m->seats, cseat);
669                 if (!seat)
670                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
671         }
672
673         if (tty_is_vc(tty)) {
674                 int v;
675
676                 if (!seat)
677                         seat = m->seat0;
678                 else if (seat != m->seat0)
679                         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);
680
681                 v = vtnr_from_tty(tty);
682                 if (v <= 0)
683                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
684
685                 if (!vtnr)
686                         vtnr = (uint32_t) v;
687                 else if (vtnr != (uint32_t) v)
688                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
689
690         } else if (tty_is_console(tty)) {
691
692                 if (!seat)
693                         seat = m->seat0;
694                 else if (seat != m->seat0)
695                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
696
697                 if (vtnr != 0)
698                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
699         }
700
701         if (seat) {
702                 if (seat_has_vts(seat)) {
703                         if (!vtnr || vtnr > 63)
704                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
705                 } else {
706                         if (vtnr != 0)
707                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
708                 }
709         }
710
711         r = sd_bus_message_enter_container(message, 'a', "(sv)");
712         if (r < 0)
713                 return r;
714
715         if (t == _SESSION_TYPE_INVALID) {
716                 if (!isempty(display))
717                         t = SESSION_X11;
718                 else if (!isempty(tty))
719                         t = SESSION_TTY;
720                 else
721                         t = SESSION_UNSPECIFIED;
722         }
723
724         if (c == _SESSION_CLASS_INVALID) {
725                 if (t == SESSION_UNSPECIFIED)
726                         c = SESSION_BACKGROUND;
727                 else
728                         c = SESSION_USER;
729         }
730
731         if (leader == 0) {
732                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
733
734                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
735                 if (r < 0)
736                         return r;
737
738                 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
739                 if (r < 0)
740                         return r;
741         }
742
743         r = manager_get_session_by_pid(m, leader, NULL);
744         if (r > 0)
745                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
746
747         /*
748          * Old gdm and lightdm start the user-session on the same VT as
749          * the greeter session. But they destroy the greeter session
750          * after the user-session and want the user-session to take
751          * over the VT. We need to support this for
752          * backwards-compatibility, so make sure we allow new sessions
753          * on a VT that a greeter is running on. Furthermore, to allow
754          * re-logins, we have to allow a greeter to take over a used VT for
755          * the exact same reasons.
756          */
757         if (c != SESSION_GREETER &&
758             vtnr > 0 &&
759             vtnr < m->seat0->position_count &&
760             m->seat0->positions[vtnr] &&
761             m->seat0->positions[vtnr]->class != SESSION_GREETER)
762                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
763
764         if (hashmap_size(m->sessions) >= m->sessions_max)
765                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.", m->sessions_max);
766
767         audit_session_from_pid(leader, &audit_id);
768         if (audit_id > 0) {
769                 /* Keep our session IDs and the audit session IDs in sync */
770
771                 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
772                         return -ENOMEM;
773
774                 /* Wut? There's already a session by this name and we
775                  * didn't find it above? Weird, then let's not trust
776                  * the audit data and let's better register a new
777                  * ID */
778                 if (hashmap_get(m->sessions, id)) {
779                         log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
780                         audit_id = 0;
781
782                         id = mfree(id);
783                 }
784         }
785
786         if (!id) {
787                 do {
788                         id = mfree(id);
789
790                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
791                                 return -ENOMEM;
792
793                 } while (hashmap_get(m->sessions, id));
794         }
795
796         r = manager_add_user_by_uid(m, uid, &user);
797         if (r < 0)
798                 goto fail;
799
800         r = manager_add_session(m, id, &session);
801         if (r < 0)
802                 goto fail;
803
804         session_set_user(session, user);
805
806         session->leader = leader;
807         session->audit_id = audit_id;
808         session->type = t;
809         session->class = c;
810         session->remote = remote;
811         session->vtnr = vtnr;
812
813         if (!isempty(tty)) {
814                 session->tty = strdup(tty);
815                 if (!session->tty) {
816                         r = -ENOMEM;
817                         goto fail;
818                 }
819         }
820
821         if (!isempty(display)) {
822                 session->display = strdup(display);
823                 if (!session->display) {
824                         r = -ENOMEM;
825                         goto fail;
826                 }
827         }
828
829         if (!isempty(remote_user)) {
830                 session->remote_user = strdup(remote_user);
831                 if (!session->remote_user) {
832                         r = -ENOMEM;
833                         goto fail;
834                 }
835         }
836
837         if (!isempty(remote_host)) {
838                 session->remote_host = strdup(remote_host);
839                 if (!session->remote_host) {
840                         r = -ENOMEM;
841                         goto fail;
842                 }
843         }
844
845         if (!isempty(service)) {
846                 session->service = strdup(service);
847                 if (!session->service) {
848                         r = -ENOMEM;
849                         goto fail;
850                 }
851         }
852
853         if (!isempty(desktop)) {
854                 session->desktop = strdup(desktop);
855                 if (!session->desktop) {
856                         r = -ENOMEM;
857                         goto fail;
858                 }
859         }
860
861         if (seat) {
862                 r = seat_attach_session(seat, session);
863                 if (r < 0)
864                         goto fail;
865         }
866
867         r = session_start(session);
868         if (r < 0)
869                 goto fail;
870
871         session->create_message = sd_bus_message_ref(message);
872
873         /* Here upstream systemd starts cgroups and the user systemd,
874            and arranges to reply asynchronously.  We reply
875            directly.  */
876
877         r = session_send_create_reply(session, NULL);
878         if (r < 0)
879                 goto fail;
880
881         return 1;
882
883 fail:
884         if (session)
885                 session_add_to_gc_queue(session);
886
887         if (user)
888                 user_add_to_gc_queue(user);
889
890         return r;
891 }
892
893 static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
894         Manager *m = userdata;
895         Session *session;
896         const char *name;
897         int r;
898
899         assert(message);
900         assert(m);
901
902         r = sd_bus_message_read(message, "s", &name);
903         if (r < 0)
904                 return r;
905
906         r = manager_get_session_from_creds(m, message, name, error, &session);
907         if (r < 0)
908                 return r;
909
910         r = session_release(session);
911         if (r < 0)
912                 return r;
913
914         session_add_to_gc_queue(session);
915
916         return sd_bus_reply_method_return(message, NULL);
917 }
918
919 static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
920         Manager *m = userdata;
921         Session *session;
922         const char *name;
923         int r;
924
925         assert(message);
926         assert(m);
927
928         r = sd_bus_message_read(message, "s", &name);
929         if (r < 0)
930                 return r;
931
932         r = manager_get_session_from_creds(m, message, name, error, &session);
933         if (r < 0)
934                 return r;
935
936         return bus_session_method_activate(message, session, error);
937 }
938
939 static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
940         const char *session_name, *seat_name;
941         Manager *m = userdata;
942         Session *session;
943         Seat *seat;
944         int r;
945
946         assert(message);
947         assert(m);
948
949         /* Same as ActivateSession() but refuses to work if
950          * the seat doesn't match */
951
952         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
953         if (r < 0)
954                 return r;
955
956         r = manager_get_session_from_creds(m, message, session_name, error, &session);
957         if (r < 0)
958                 return r;
959
960         r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
961         if (r < 0)
962                 return r;
963
964         if (session->seat != seat)
965                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
966
967         r = session_activate(session);
968         if (r < 0)
969                 return r;
970
971         return sd_bus_reply_method_return(message, NULL);
972 }
973
974 static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
975         Manager *m = userdata;
976         Session *session;
977         const char *name;
978         int r;
979
980         assert(message);
981         assert(m);
982
983         r = sd_bus_message_read(message, "s", &name);
984         if (r < 0)
985                 return r;
986
987         r = manager_get_session_from_creds(m, message, name, error, &session);
988         if (r < 0)
989                 return r;
990
991         return bus_session_method_lock(message, session, error);
992 }
993
994 static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
995         Manager *m = userdata;
996         int r;
997
998         assert(message);
999         assert(m);
1000
1001         r = bus_verify_polkit_async(
1002                         message,
1003                         CAP_SYS_ADMIN,
1004                         "org.freedesktop.login1.lock-sessions",
1005                         NULL,
1006                         false,
1007                         UID_INVALID,
1008                         &m->polkit_registry,
1009                         error);
1010         if (r < 0)
1011                 return r;
1012         if (r == 0)
1013                 return 1; /* Will call us back */
1014
1015         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
1016         if (r < 0)
1017                 return r;
1018
1019         return sd_bus_reply_method_return(message, NULL);
1020 }
1021
1022 static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1023         const char *name;
1024         Manager *m = userdata;
1025         Session *session;
1026         int r;
1027
1028         assert(message);
1029         assert(m);
1030
1031         r = sd_bus_message_read(message, "s", &name);
1032         if (r < 0)
1033                 return r;
1034
1035         r = manager_get_session_from_creds(m, message, name, error, &session);
1036         if (r < 0)
1037                 return r;
1038
1039         return bus_session_method_kill(message, session, error);
1040 }
1041
1042 static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1043         Manager *m = userdata;
1044         uint32_t uid;
1045         User *user;
1046         int r;
1047
1048         assert(message);
1049         assert(m);
1050
1051         r = sd_bus_message_read(message, "u", &uid);
1052         if (r < 0)
1053                 return r;
1054
1055         r = manager_get_user_from_creds(m, message, uid, error, &user);
1056         if (r < 0)
1057                 return r;
1058
1059         return bus_user_method_kill(message, user, error);
1060 }
1061
1062 static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1063         Manager *m = userdata;
1064         const char *name;
1065         Session *session;
1066         int r;
1067
1068         assert(message);
1069         assert(m);
1070
1071         r = sd_bus_message_read(message, "s", &name);
1072         if (r < 0)
1073                 return r;
1074
1075         r = manager_get_session_from_creds(m, message, name, error, &session);
1076         if (r < 0)
1077                 return r;
1078
1079         return bus_session_method_terminate(message, session, error);
1080 }
1081
1082 static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1083         Manager *m = userdata;
1084         uint32_t uid;
1085         User *user;
1086         int r;
1087
1088         assert(message);
1089         assert(m);
1090
1091         r = sd_bus_message_read(message, "u", &uid);
1092         if (r < 0)
1093                 return r;
1094
1095         r = manager_get_user_from_creds(m, message, uid, error, &user);
1096         if (r < 0)
1097                 return r;
1098
1099         return bus_user_method_terminate(message, user, error);
1100 }
1101
1102 static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1103         Manager *m = userdata;
1104         const char *name;
1105         Seat *seat;
1106         int r;
1107
1108         assert(message);
1109         assert(m);
1110
1111         r = sd_bus_message_read(message, "s", &name);
1112         if (r < 0)
1113                 return r;
1114
1115         r = manager_get_seat_from_creds(m, message, name, error, &seat);
1116         if (r < 0)
1117                 return r;
1118
1119         return bus_seat_method_terminate(message, seat, error);
1120 }
1121
1122 static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1123         _cleanup_free_ char *cc = NULL;
1124         Manager *m = userdata;
1125         int r, b, interactive;
1126         struct passwd *pw;
1127         const char *path;
1128         uint32_t uid;
1129         bool self = false;
1130
1131         assert(message);
1132         assert(m);
1133
1134         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1135         if (r < 0)
1136                 return r;
1137
1138         if (uid == UID_INVALID) {
1139                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1140
1141                 /* Note that we get the owner UID of the session, not the actual client UID here! */
1142                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
1143                 if (r < 0)
1144                         return r;
1145
1146                 r = sd_bus_creds_get_owner_uid(creds, &uid);
1147                 if (r < 0)
1148                         return r;
1149
1150                 self = true;
1151
1152         } else if (!uid_is_valid(uid))
1153                 return -EINVAL;
1154
1155         errno = 0;
1156         pw = getpwuid(uid);
1157         if (!pw)
1158                 return errno > 0 ? -errno : -ENOENT;
1159
1160         r = bus_verify_polkit_async(
1161                         message,
1162                         CAP_SYS_ADMIN,
1163                         self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger",
1164                         NULL,
1165                         interactive,
1166                         UID_INVALID,
1167                         &m->polkit_registry,
1168                         error);
1169         if (r < 0)
1170                 return r;
1171         if (r == 0)
1172                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1173
1174         mkdir_p_label("/var/lib/systemd", 0755);
1175
1176         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1177         if (r < 0)
1178                 return r;
1179
1180         cc = cescape(pw->pw_name);
1181         if (!cc)
1182                 return -ENOMEM;
1183
1184         path = strjoina("/var/lib/systemd/linger/", cc);
1185         if (b) {
1186                 User *u;
1187
1188                 r = touch(path);
1189                 if (r < 0)
1190                         return r;
1191
1192                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1193                         user_start(u);
1194
1195         } else {
1196                 User *u;
1197
1198                 r = unlink(path);
1199                 if (r < 0 && errno != ENOENT)
1200                         return -errno;
1201
1202                 u = hashmap_get(m->users, UID_TO_PTR(uid));
1203                 if (u)
1204                         user_add_to_gc_queue(u);
1205         }
1206
1207         return sd_bus_reply_method_return(message, NULL);
1208 }
1209
1210 static int trigger_device(Manager *m, struct udev_device *d) {
1211         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1212         struct udev_list_entry *first, *item;
1213         int r;
1214
1215         assert(m);
1216
1217         e = udev_enumerate_new(m->udev);
1218         if (!e)
1219                 return -ENOMEM;
1220
1221         if (d) {
1222                 r = udev_enumerate_add_match_parent(e, d);
1223                 if (r < 0)
1224                         return r;
1225         }
1226
1227         r = udev_enumerate_scan_devices(e);
1228         if (r < 0)
1229                 return r;
1230
1231         first = udev_enumerate_get_list_entry(e);
1232         udev_list_entry_foreach(item, first) {
1233                 _cleanup_free_ char *t = NULL;
1234                 const char *p;
1235
1236                 p = udev_list_entry_get_name(item);
1237
1238                 t = strappend(p, "/uevent");
1239                 if (!t)
1240                         return -ENOMEM;
1241
1242                 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
1243         }
1244
1245         return 0;
1246 }
1247
1248 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1249         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1250         _cleanup_free_ char *rule = NULL, *file = NULL;
1251         const char *id_for_seat;
1252         int r;
1253
1254         assert(m);
1255         assert(seat);
1256         assert(sysfs);
1257
1258         d = udev_device_new_from_syspath(m->udev, sysfs);
1259         if (!d)
1260                 return -ENODEV;
1261
1262         if (!udev_device_has_tag(d, "seat"))
1263                 return -ENODEV;
1264
1265         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1266         if (!id_for_seat)
1267                 return -ENODEV;
1268
1269         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1270                 return -ENOMEM;
1271
1272         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1273                 return -ENOMEM;
1274
1275         mkdir_p_label("/etc/udev/rules.d", 0755);
1276         r = write_string_file_atomic_label(file, rule);
1277         if (r < 0)
1278                 return r;
1279
1280         return trigger_device(m, d);
1281 }
1282
1283 static int flush_devices(Manager *m) {
1284         _cleanup_closedir_ DIR *d;
1285
1286         assert(m);
1287
1288         d = opendir("/etc/udev/rules.d");
1289         if (!d) {
1290                 if (errno != ENOENT)
1291                         log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
1292         } else {
1293                 struct dirent *de;
1294
1295                 while ((de = readdir(d))) {
1296
1297                         if (!dirent_is_file(de))
1298                                 continue;
1299
1300                         if (!startswith(de->d_name, "72-seat-"))
1301                                 continue;
1302
1303                         if (!endswith(de->d_name, ".rules"))
1304                                 continue;
1305
1306                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1307                                 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
1308                 }
1309         }
1310
1311         return trigger_device(m, NULL);
1312 }
1313
1314 static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1315         const char *sysfs, *seat;
1316         Manager *m = userdata;
1317         int interactive, r;
1318
1319         assert(message);
1320         assert(m);
1321
1322         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1323         if (r < 0)
1324                 return r;
1325
1326         if (!path_startswith(sysfs, "/sys"))
1327                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1328
1329         if (!seat_name_is_valid(seat))
1330                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1331
1332         r = bus_verify_polkit_async(
1333                         message,
1334                         CAP_SYS_ADMIN,
1335                         "org.freedesktop.login1.attach-device",
1336                         NULL,
1337                         interactive,
1338                         UID_INVALID,
1339                         &m->polkit_registry,
1340                         error);
1341         if (r < 0)
1342                 return r;
1343         if (r == 0)
1344                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1345
1346         r = attach_device(m, seat, sysfs);
1347         if (r < 0)
1348                 return r;
1349
1350         return sd_bus_reply_method_return(message, NULL);
1351 }
1352
1353 static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1354         Manager *m = userdata;
1355         int interactive, r;
1356
1357         assert(message);
1358         assert(m);
1359
1360         r = sd_bus_message_read(message, "b", &interactive);
1361         if (r < 0)
1362                 return r;
1363
1364         r = bus_verify_polkit_async(
1365                         message,
1366                         CAP_SYS_ADMIN,
1367                         "org.freedesktop.login1.flush-devices",
1368                         NULL,
1369                         interactive,
1370                         UID_INVALID,
1371                         &m->polkit_registry,
1372                         error);
1373         if (r < 0)
1374                 return r;
1375         if (r == 0)
1376                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1377
1378         r = flush_devices(m);
1379         if (r < 0)
1380                 return r;
1381
1382         return sd_bus_reply_method_return(message, NULL);
1383 }
1384
1385 static int have_multiple_sessions(
1386                 Manager *m,
1387                 uid_t uid) {
1388
1389         Session *session;
1390         Iterator i;
1391
1392         assert(m);
1393
1394         /* Check for other users' sessions. Greeter sessions do not
1395          * count, and non-login sessions do not count either. */
1396         HASHMAP_FOREACH(session, m->sessions, i)
1397                 if (session->class == SESSION_USER &&
1398                     session->user->uid != uid)
1399                         return true;
1400
1401         return false;
1402 }
1403
1404 static int bus_manager_log_shutdown(
1405                 Manager *m,
1406                 InhibitWhat w,
1407 #if 0 /// elogind does not support systemd units
1408                 const char *unit_name) {
1409
1410         const char *p, *q;
1411
1412         assert(m);
1413         assert(unit_name);
1414
1415         if (w != INHIBIT_SHUTDOWN)
1416                 return 0;
1417
1418         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1419                 p = "MESSAGE=System is powering down";
1420                 q = "SHUTDOWN=power-off";
1421         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1422                 p = "MESSAGE=System is halting";
1423                 q = "SHUTDOWN=halt";
1424         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1425                 p = "MESSAGE=System is rebooting";
1426                 q = "SHUTDOWN=reboot";
1427         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1428                 p = "MESSAGE=System is rebooting with kexec";
1429                 q = "SHUTDOWN=kexec";
1430         } else {
1431                 p = "MESSAGE=System is shutting down";
1432                 q = NULL;
1433         }
1434 #else
1435                  HandleAction action) {
1436
1437          const char *p, *q;
1438
1439          assert(m);
1440
1441          if (w != INHIBIT_SHUTDOWN)
1442                  return 0;
1443
1444          switch (action) {
1445          case HANDLE_POWEROFF:
1446                  p = "MESSAGE=System is powering down.";
1447                  q = "SHUTDOWN=power-off";
1448                  break;
1449          case HANDLE_HALT:
1450                  p = "MESSAGE=System is halting.";
1451                  q = "SHUTDOWN=halt";
1452                  break;
1453          case HANDLE_REBOOT:
1454                  p = "MESSAGE=System is rebooting.";
1455                  q = "SHUTDOWN=reboot";
1456                  break;
1457          case HANDLE_KEXEC:
1458                  p = "MESSAGE=System is rebooting with kexec.";
1459                  q = "SHUTDOWN=kexec";
1460                  break;
1461          default:
1462                  p = "MESSAGE=System is shutting down.";
1463                  q = NULL;
1464          }
1465 #endif // 0
1466         if (isempty(m->wall_message))
1467                 p = strjoina(p, ".");
1468         else
1469                 p = strjoina(p, " (", m->wall_message, ").");
1470
1471         return log_struct(LOG_NOTICE,
1472                           LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1473                           p,
1474                           q,
1475                           NULL);
1476 }
1477
1478 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
1479         Manager *m = userdata;
1480
1481         assert(e);
1482         assert(m);
1483
1484         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
1485         return 0;
1486 }
1487
1488 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
1489         int r;
1490
1491         assert(m);
1492
1493         if (until <= now(CLOCK_MONOTONIC))
1494                 return 0;
1495
1496         /* We want to ignore the lid switch for a while after each
1497          * suspend, and after boot-up. Hence let's install a timer for
1498          * this. As long as the event source exists we ignore the lid
1499          * switch. */
1500
1501         if (m->lid_switch_ignore_event_source) {
1502                 usec_t u;
1503
1504                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
1505                 if (r < 0)
1506                         return r;
1507
1508                 if (until <= u)
1509                         return 0;
1510
1511                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
1512         } else
1513                 r = sd_event_add_time(
1514                                 m->event,
1515                                 &m->lid_switch_ignore_event_source,
1516                                 CLOCK_MONOTONIC,
1517                                 until, 0,
1518                                 lid_switch_ignore_handler, m);
1519
1520         return r;
1521 }
1522
1523 static void reset_scheduled_shutdown(Manager *m) {
1524         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
1525         m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
1526         m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
1527         m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
1528         m->scheduled_shutdown_timeout = 0;
1529         m->shutdown_dry_run = false;
1530
1531         if (m->unlink_nologin) {
1532                 (void) unlink("/run/nologin");
1533                 m->unlink_nologin = false;
1534         }
1535 }
1536
1537 static int execute_shutdown_or_sleep(
1538                 Manager *m,
1539                 InhibitWhat w,
1540                 HandleAction action,
1541                 sd_bus_error *error) {
1542
1543 #if 0 /// elogind does not need these, we do it ourselves
1544         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1545         char *c = NULL;
1546         const char *p;
1547 #endif // 0
1548         int r;
1549
1550         assert(m);
1551         assert(w >= 0);
1552         assert(w < _INHIBIT_WHAT_MAX);
1553
1554         bus_manager_log_shutdown(m, w, action);
1555
1556 #if 0 /// elogind does it directly without depending on systemd running the system
1557         if (m->shutdown_dry_run) {
1558                 log_info("Running in dry run, suppressing action.");
1559                 reset_scheduled_shutdown(m);
1560         } else {
1561         r = sd_bus_call_method(
1562                         m->bus,
1563                         "org.freedesktop.systemd1",
1564                         "/org/freedesktop/systemd1",
1565                         "org.freedesktop.systemd1.Manager",
1566                         "StartUnit",
1567                         error,
1568                         &reply,
1569                         "ss", unit_name, "replace-irreversibly");
1570 #else
1571         r = shutdown_or_sleep(m, action);
1572
1573         /* no more pending actions, whether this failed or not */
1574         m->pending_action = HANDLE_IGNORE;
1575         m->action_what    = 0;
1576 #endif // 0
1577         if (r < 0)
1578                 return r;
1579
1580 #if 0 /// elogind neither needs a dbus reply, nor supports systemd action jobs
1581         r = sd_bus_message_read(reply, "o", &p);
1582         if (r < 0)
1583                 return r;
1584
1585         c = strdup(p);
1586         if (!c)
1587                 return -ENOMEM;
1588         }
1589
1590         m->action_unit = unit_name;
1591         free(m->action_job);
1592         m->action_job = c;
1593         m->action_what = w;
1594 #endif // 0
1595
1596         /* Make sure the lid switch is ignored for a while */
1597         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
1598
1599         return 0;
1600 }
1601
1602 int manager_dispatch_delayed(Manager *manager, bool timeout) {
1603
1604         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1605         Inhibitor *offending = NULL;
1606         int r;
1607
1608         assert(manager);
1609
1610         if ( (0 == manager->action_what) || (HANDLE_IGNORE == manager->pending_action) )
1611                 return 0;
1612
1613         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
1614                 _cleanup_free_ char *comm = NULL, *u = NULL;
1615
1616                 if (!timeout)
1617                         return 0;
1618
1619                 (void) get_process_comm(offending->pid, &comm);
1620                 u = uid_to_name(offending->uid);
1621
1622                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
1623                            offending->uid, strna(u),
1624                            offending->pid, strna(comm));
1625         }
1626
1627         /* Actually do the operation */
1628         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->pending_action, &error);
1629         if (r < 0) {
1630                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
1631
1632                 manager->pending_action = HANDLE_IGNORE;
1633                 manager->action_what    = 0;
1634                 return r;
1635         }
1636
1637         return 1;
1638 }
1639
1640 static int manager_inhibit_timeout_handler(
1641                         sd_event_source *s,
1642                         uint64_t usec,
1643                         void *userdata) {
1644
1645         Manager *manager = userdata;
1646         int r;
1647
1648         assert(manager);
1649         assert(manager->inhibit_timeout_source == s);
1650
1651         r = manager_dispatch_delayed(manager, true);
1652         return (r < 0) ? r : 0;
1653 }
1654
1655 static int delay_shutdown_or_sleep(
1656                 Manager *m,
1657                 InhibitWhat w,
1658                 HandleAction action) {
1659
1660         int r;
1661         usec_t timeout_val;
1662
1663         assert(m);
1664         assert(w >= 0);
1665         assert(w < _INHIBIT_WHAT_MAX);
1666
1667         timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
1668
1669         if (m->inhibit_timeout_source) {
1670                 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
1671                 if (r < 0)
1672                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
1673
1674                 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
1675                 if (r < 0)
1676                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
1677         } else {
1678                 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
1679                                       timeout_val, 0, manager_inhibit_timeout_handler, m);
1680                 if (r < 0)
1681                         return r;
1682         }
1683
1684         m->pending_action = action;
1685         m->action_what = w;
1686
1687         return 0;
1688 }
1689
1690 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1691
1692         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1693                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1694                 [INHIBIT_SLEEP] = "PrepareForSleep"
1695         };
1696
1697         int active = _active;
1698
1699         assert(m);
1700         assert(w >= 0);
1701         assert(w < _INHIBIT_WHAT_MAX);
1702         assert(signal_name[w]);
1703
1704         return sd_bus_emit_signal(m->bus,
1705                                   "/org/freedesktop/login1",
1706                                   "org.freedesktop.login1.Manager",
1707                                   signal_name[w],
1708                                   "b",
1709                                   active);
1710 }
1711
1712 int bus_manager_shutdown_or_sleep_now_or_later(
1713                 Manager *m,
1714                 HandleAction action,
1715                 InhibitWhat w,
1716                 sd_bus_error *error) {
1717
1718         bool delayed;
1719         int r;
1720
1721         assert(m);
1722         assert(w >= 0);
1723         assert(w <= _INHIBIT_WHAT_MAX);
1724
1725         /* Tell everybody to prepare for shutdown/sleep */
1726         send_prepare_for(m, w, true);
1727
1728         delayed =
1729                 m->inhibit_delay_max > 0 &&
1730                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1731
1732         if (delayed)
1733                 /* Shutdown is delayed, keep in mind what we
1734                  * want to do, and start a timeout */
1735                 r = delay_shutdown_or_sleep(m, w, action);
1736         else
1737                 /* Shutdown is not delayed, execute it
1738                  * immediately */
1739                 r = execute_shutdown_or_sleep(m, w, action, error);
1740
1741         return r;
1742 }
1743
1744 static int verify_shutdown_creds(
1745                 Manager *m,
1746                 sd_bus_message *message,
1747                 InhibitWhat w,
1748                 bool interactive,
1749                 const char *action,
1750                 const char *action_multiple_sessions,
1751                 const char *action_ignore_inhibit,
1752                 sd_bus_error *error) {
1753
1754         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1755         bool multiple_sessions, blocked;
1756         uid_t uid;
1757         int r;
1758
1759         assert(m);
1760         assert(message);
1761         assert(w >= 0);
1762         assert(w <= _INHIBIT_WHAT_MAX);
1763
1764         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1765         if (r < 0)
1766                 return r;
1767
1768         r = sd_bus_creds_get_euid(creds, &uid);
1769         if (r < 0)
1770                 return r;
1771
1772         r = have_multiple_sessions(m, uid);
1773         if (r < 0)
1774                 return r;
1775
1776         multiple_sessions = r > 0;
1777         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1778
1779         if (multiple_sessions && action_multiple_sessions) {
1780                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1781                 if (r < 0)
1782                         return r;
1783                 if (r == 0)
1784                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1785         }
1786
1787         if (blocked && action_ignore_inhibit) {
1788                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1789                 if (r < 0)
1790                         return r;
1791                 if (r == 0)
1792                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1793         }
1794
1795         if (!multiple_sessions && !blocked && action) {
1796                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
1797                 if (r < 0)
1798                         return r;
1799                 if (r == 0)
1800                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1801         }
1802
1803         return 0;
1804 }
1805
1806 static int method_do_shutdown_or_sleep(
1807                 Manager *m,
1808                 sd_bus_message *message,
1809                 HandleAction sleep_action,
1810                 InhibitWhat w,
1811                 const char *action,
1812                 const char *action_multiple_sessions,
1813                 const char *action_ignore_inhibit,
1814                 const char *sleep_verb,
1815                 sd_bus_error *error) {
1816
1817         int interactive, r;
1818
1819         assert(m);
1820         assert(message);
1821         assert(w >= 0);
1822         assert(w <= _INHIBIT_WHAT_MAX);
1823
1824         r = sd_bus_message_read(message, "b", &interactive);
1825         if (r < 0)
1826                 return r;
1827
1828         /* Don't allow multiple jobs being executed at the same time */
1829         if (m->action_what)
1830                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1831
1832         if (sleep_verb) {
1833                 r = can_sleep(m, sleep_verb);
1834                 if (r < 0)
1835                         return r;
1836
1837                 if (r == 0)
1838                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1839         }
1840
1841         r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
1842                                   action_ignore_inhibit, error);
1843         if (r != 0)
1844                 return r;
1845
1846         r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
1847         if (r < 0)
1848                 return r;
1849
1850         return sd_bus_reply_method_return(message, NULL);
1851 }
1852
1853 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1854         Manager *m = userdata;
1855
1856         return method_do_shutdown_or_sleep(
1857                         m, message,
1858                         HANDLE_POWEROFF,
1859                         INHIBIT_SHUTDOWN,
1860                         "org.freedesktop.login1.power-off",
1861                         "org.freedesktop.login1.power-off-multiple-sessions",
1862                         "org.freedesktop.login1.power-off-ignore-inhibit",
1863                         NULL,
1864                         error);
1865 }
1866
1867 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1868         Manager *m = userdata;
1869
1870         return method_do_shutdown_or_sleep(
1871                         m, message,
1872                         HANDLE_REBOOT,
1873                         INHIBIT_SHUTDOWN,
1874                         "org.freedesktop.login1.reboot",
1875                         "org.freedesktop.login1.reboot-multiple-sessions",
1876                         "org.freedesktop.login1.reboot-ignore-inhibit",
1877                         NULL,
1878                         error);
1879 }
1880
1881 static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1882         Manager *m = userdata;
1883
1884         return method_do_shutdown_or_sleep(
1885                         m, message,
1886                         HANDLE_SUSPEND,
1887                         INHIBIT_SLEEP,
1888                         "org.freedesktop.login1.suspend",
1889                         "org.freedesktop.login1.suspend-multiple-sessions",
1890                         "org.freedesktop.login1.suspend-ignore-inhibit",
1891                         "suspend",
1892                         error);
1893 }
1894
1895 static int nologin_timeout_handler(
1896                         sd_event_source *s,
1897                         uint64_t usec,
1898                         void *userdata) {
1899
1900         Manager *m = userdata;
1901         int r;
1902
1903         log_info("Creating /run/nologin, blocking further logins...");
1904
1905         r = write_string_file_atomic_label("/run/nologin", "System is going down.");
1906         if (r < 0)
1907                 log_error_errno(r, "Failed to create /run/nologin: %m");
1908         else
1909                 m->unlink_nologin = true;
1910
1911         return 0;
1912 }
1913
1914 static int update_schedule_file(Manager *m) {
1915         _cleanup_free_ char *temp_path = NULL;
1916         _cleanup_fclose_ FILE *f = NULL;
1917         int r;
1918
1919         assert(m);
1920
1921         r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
1922         if (r < 0)
1923                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
1924
1925         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
1926         if (r < 0)
1927                 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
1928
1929         (void) fchmod(fileno(f), 0644);
1930
1931         fprintf(f,
1932                 "USEC="USEC_FMT"\n"
1933                 "WARN_WALL=%i\n"
1934                 "MODE=%s\n",
1935                 m->scheduled_shutdown_timeout,
1936                 m->enable_wall_messages,
1937                 m->scheduled_shutdown_type);
1938
1939         if (!isempty(m->wall_message)) {
1940                 _cleanup_free_ char *t;
1941
1942                 t = cescape(m->wall_message);
1943                 if (!t) {
1944                         r = -ENOMEM;
1945                         goto fail;
1946                 }
1947
1948                 fprintf(f, "WALL_MESSAGE=%s\n", t);
1949         }
1950
1951         r = fflush_and_check(f);
1952         if (r < 0)
1953                 goto fail;
1954
1955         if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
1956                 r = -errno;
1957                 goto fail;
1958         }
1959
1960         return 0;
1961
1962 fail:
1963                 (void) unlink(temp_path);
1964                 (void) unlink("/run/systemd/shutdown/scheduled");
1965
1966         return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
1967 }
1968
1969 static int manager_scheduled_shutdown_handler(
1970                         sd_event_source *s,
1971                         uint64_t usec,
1972                         void *userdata) {
1973
1974         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1975         Manager *m = userdata;
1976         HandleAction action;
1977         int r;
1978
1979         assert(m);
1980
1981         if (isempty(m->scheduled_shutdown_type))
1982                 return 0;
1983
1984         if (streq(m->scheduled_shutdown_type, "halt"))
1985                 action = HANDLE_HALT;
1986         else if (streq(m->scheduled_shutdown_type, "poweroff"))
1987                 action = HANDLE_POWEROFF;
1988         else
1989                 action = HANDLE_REBOOT;
1990
1991         r = execute_shutdown_or_sleep(m, 0, action, &error);
1992         if (r < 0)
1993                 return log_error_errno(r, "Unable to execute transition to %s: %m", m->scheduled_shutdown_type);
1994
1995         return 0;
1996 }
1997
1998 static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1999         Manager *m = userdata;
2000         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2001         const char *action_multiple_sessions = NULL;
2002         const char *action_ignore_inhibit = NULL;
2003         const char *action = NULL;
2004         uint64_t elapse;
2005         char *type;
2006         int r;
2007
2008         assert(m);
2009         assert(message);
2010
2011         r = sd_bus_message_read(message, "st", &type, &elapse);
2012         if (r < 0)
2013                 return r;
2014
2015         if (startswith(type, "dry-")) {
2016                 type += 4;
2017                 m->shutdown_dry_run = true;
2018         }
2019
2020         if (streq(type, "reboot")) {
2021                 action = "org.freedesktop.login1.reboot";
2022                 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
2023                 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
2024         } else if (streq(type, "halt")) {
2025                 action = "org.freedesktop.login1.halt";
2026                 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
2027                 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
2028         } else if (streq(type, "poweroff")) {
2029                 action = "org.freedesktop.login1.power-off";
2030                 action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions";
2031                 action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit";
2032         } else
2033                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
2034
2035         r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
2036                                   action, action_multiple_sessions, action_ignore_inhibit, error);
2037         if (r != 0)
2038                 return r;
2039
2040         if (m->scheduled_shutdown_timeout_source) {
2041                 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
2042                 if (r < 0)
2043                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
2044
2045                 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
2046                 if (r < 0)
2047                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
2048         } else {
2049                 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
2050                                       CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
2051                 if (r < 0)
2052                         return log_error_errno(r, "sd_event_add_time() failed: %m");
2053         }
2054
2055         r = free_and_strdup(&m->scheduled_shutdown_type, type);
2056         if (r < 0) {
2057                 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2058                 return log_oom();
2059         }
2060
2061         if (m->nologin_timeout_source) {
2062                 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
2063                 if (r < 0)
2064                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
2065
2066                 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
2067                 if (r < 0)
2068                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
2069         } else {
2070                 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
2071                                       CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
2072                 if (r < 0)
2073                         return log_error_errno(r, "sd_event_add_time() failed: %m");
2074         }
2075
2076         m->scheduled_shutdown_timeout = elapse;
2077
2078         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2079         if (r >= 0) {
2080                 const char *tty = NULL;
2081
2082                 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
2083                 (void) sd_bus_creds_get_tty(creds, &tty);
2084
2085                 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
2086                 if (r < 0) {
2087                         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
2088                         return log_oom();
2089                 }
2090         }
2091
2092 #if 0 /// elogind does not support utmp-wtmp
2093         r = manager_setup_wall_message_timer(m);
2094         if (r < 0)
2095                 return r;
2096 #endif // 0
2097
2098         if (!isempty(type)) {
2099                 r = update_schedule_file(m);
2100                 if (r < 0)
2101                         return r;
2102         } else
2103                 (void) unlink("/run/systemd/shutdown/scheduled");
2104
2105         return sd_bus_reply_method_return(message, NULL);
2106 }
2107
2108 static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2109         Manager *m = userdata;
2110         bool cancelled;
2111
2112         assert(m);
2113         assert(message);
2114
2115         cancelled = m->scheduled_shutdown_type != NULL;
2116         reset_scheduled_shutdown(m);
2117
2118 #if 0 /// elogind does not support utmp-wtmp
2119         if (cancelled) {
2120                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2121                 const char *tty = NULL;
2122                 uid_t uid = 0;
2123                 int r;
2124
2125                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
2126                 if (r >= 0) {
2127                         (void) sd_bus_creds_get_uid(creds, &uid);
2128                         (void) sd_bus_creds_get_tty(creds, &tty);
2129                 }
2130
2131                 utmp_wall("The system shutdown has been cancelled",
2132                           uid_to_name(uid), tty, logind_wall_tty_filter, m);
2133         }
2134 #endif // 0
2135
2136         return sd_bus_reply_method_return(message, "b", cancelled);
2137 }
2138
2139 static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2140         Manager *m = userdata;
2141
2142         return method_do_shutdown_or_sleep(
2143                         m, message,
2144                         HANDLE_HIBERNATE,
2145                         INHIBIT_SLEEP,
2146                         "org.freedesktop.login1.hibernate",
2147                         "org.freedesktop.login1.hibernate-multiple-sessions",
2148                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2149                         "hibernate",
2150                         error);
2151 }
2152
2153 static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2154         Manager *m = userdata;
2155
2156         return method_do_shutdown_or_sleep(
2157                         m, message,
2158                         HANDLE_HYBRID_SLEEP,
2159                         INHIBIT_SLEEP,
2160                         "org.freedesktop.login1.hibernate",
2161                         "org.freedesktop.login1.hibernate-multiple-sessions",
2162                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2163                         "hybrid-sleep",
2164                         error);
2165 }
2166
2167 static int method_can_shutdown_or_sleep(
2168                 Manager *m,
2169                 sd_bus_message *message,
2170                 InhibitWhat w,
2171                 const char *action,
2172                 const char *action_multiple_sessions,
2173                 const char *action_ignore_inhibit,
2174                 const char *sleep_verb,
2175                 sd_bus_error *error) {
2176
2177         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2178         bool multiple_sessions, challenge, blocked;
2179         const char *result = NULL;
2180         uid_t uid;
2181         int r;
2182
2183         assert(m);
2184         assert(message);
2185         assert(w >= 0);
2186         assert(w <= _INHIBIT_WHAT_MAX);
2187         assert(action);
2188         assert(action_multiple_sessions);
2189         assert(action_ignore_inhibit);
2190
2191         if (sleep_verb) {
2192                 r = can_sleep(m, sleep_verb);
2193                 if (r < 0)
2194                         return r;
2195                 if (r == 0)
2196                         return sd_bus_reply_method_return(message, "s", "na");
2197         }
2198
2199         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
2200         if (r < 0)
2201                 return r;
2202
2203         r = sd_bus_creds_get_euid(creds, &uid);
2204         if (r < 0)
2205                 return r;
2206
2207         r = have_multiple_sessions(m, uid);
2208         if (r < 0)
2209                 return r;
2210
2211         multiple_sessions = r > 0;
2212         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
2213
2214         if (multiple_sessions) {
2215                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
2216                 if (r < 0)
2217                         return r;
2218
2219                 if (r > 0)
2220                         result = "yes";
2221                 else if (challenge)
2222                         result = "challenge";
2223                 else
2224                         result = "no";
2225         }
2226
2227         if (blocked) {
2228                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
2229                 if (r < 0)
2230                         return r;
2231
2232                 if (r > 0 && !result)
2233                         result = "yes";
2234                 else if (challenge && (!result || streq(result, "yes")))
2235                         result = "challenge";
2236                 else
2237                         result = "no";
2238         }
2239
2240         if (!multiple_sessions && !blocked) {
2241                 /* If neither inhibit nor multiple sessions
2242                  * apply then just check the normal policy */
2243
2244                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
2245                 if (r < 0)
2246                         return r;
2247
2248                 if (r > 0)
2249                         result = "yes";
2250                 else if (challenge)
2251                         result = "challenge";
2252                 else
2253                         result = "no";
2254         }
2255
2256         return sd_bus_reply_method_return(message, "s", result);
2257 }
2258
2259 static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2260         Manager *m = userdata;
2261
2262         return method_can_shutdown_or_sleep(
2263                         m, message,
2264                         INHIBIT_SHUTDOWN,
2265                         "org.freedesktop.login1.power-off",
2266                         "org.freedesktop.login1.power-off-multiple-sessions",
2267                         "org.freedesktop.login1.power-off-ignore-inhibit",
2268                         NULL,
2269                         error);
2270 }
2271
2272 static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2273         Manager *m = userdata;
2274
2275         return method_can_shutdown_or_sleep(
2276                         m, message,
2277                         INHIBIT_SHUTDOWN,
2278                         "org.freedesktop.login1.reboot",
2279                         "org.freedesktop.login1.reboot-multiple-sessions",
2280                         "org.freedesktop.login1.reboot-ignore-inhibit",
2281                         NULL,
2282                         error);
2283 }
2284
2285 static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2286         Manager *m = userdata;
2287
2288         return method_can_shutdown_or_sleep(
2289                         m, message,
2290                         INHIBIT_SLEEP,
2291                         "org.freedesktop.login1.suspend",
2292                         "org.freedesktop.login1.suspend-multiple-sessions",
2293                         "org.freedesktop.login1.suspend-ignore-inhibit",
2294                         "suspend",
2295                         error);
2296 }
2297
2298 static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2299         Manager *m = userdata;
2300
2301         return method_can_shutdown_or_sleep(
2302                         m, message,
2303                         INHIBIT_SLEEP,
2304                         "org.freedesktop.login1.hibernate",
2305                         "org.freedesktop.login1.hibernate-multiple-sessions",
2306                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2307                         "hibernate",
2308                         error);
2309 }
2310
2311 static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2312         Manager *m = userdata;
2313
2314         return method_can_shutdown_or_sleep(
2315                         m, message,
2316                         INHIBIT_SLEEP,
2317                         "org.freedesktop.login1.hibernate",
2318                         "org.freedesktop.login1.hibernate-multiple-sessions",
2319                         "org.freedesktop.login1.hibernate-ignore-inhibit",
2320                         "hybrid-sleep",
2321                         error);
2322 }
2323
2324 static int property_get_reboot_to_firmware_setup(
2325                 sd_bus *bus,
2326                 const char *path,
2327                 const char *interface,
2328                 const char *property,
2329                 sd_bus_message *reply,
2330                 void *userdata,
2331                 sd_bus_error *error) {
2332 #if 0 /// elogind does not support EFI
2333         int r;
2334
2335         assert(bus);
2336         assert(reply);
2337         assert(userdata);
2338
2339         r = efi_get_reboot_to_firmware();
2340         if (r < 0 && r != -EOPNOTSUPP)
2341                 return r;
2342
2343         return sd_bus_message_append(reply, "b", r > 0);
2344 #else
2345         return sd_bus_message_append(reply, "b", -EOPNOTSUPP);
2346 #endif // 0
2347 }
2348
2349 static int method_set_reboot_to_firmware_setup(
2350                 sd_bus_message *message,
2351                 void *userdata,
2352                 sd_bus_error *error) {
2353
2354         int b, r;
2355         Manager *m = userdata;
2356
2357         assert(message);
2358         assert(m);
2359
2360         r = sd_bus_message_read(message, "b", &b);
2361         if (r < 0)
2362                 return r;
2363
2364         r = bus_verify_polkit_async(message,
2365                                     CAP_SYS_ADMIN,
2366                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
2367                                     NULL,
2368                                     false,
2369                                     UID_INVALID,
2370                                     &m->polkit_registry,
2371                                     error);
2372         if (r < 0)
2373                 return r;
2374         if (r == 0)
2375                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2376
2377 #if 0 /// elogind does not support EFI
2378         r = efi_set_reboot_to_firmware(b);
2379         if (r < 0)
2380                 return r;
2381 #endif // 0
2382
2383         return sd_bus_reply_method_return(message, NULL);
2384 }
2385
2386 static int method_can_reboot_to_firmware_setup(
2387                 sd_bus_message *message,
2388                 void *userdata,
2389                 sd_bus_error *error) {
2390
2391 #if 0 /// elogind does not support EFI
2392         int r;
2393         bool challenge;
2394         const char *result;
2395         Manager *m = userdata;
2396
2397         assert(message);
2398         assert(m);
2399
2400         r = efi_reboot_to_firmware_supported();
2401         if (r == -EOPNOTSUPP)
2402                 return sd_bus_reply_method_return(message, "s", "na");
2403         else if (r < 0)
2404                 return r;
2405
2406         r = bus_test_polkit(message,
2407                             CAP_SYS_ADMIN,
2408                             "org.freedesktop.login1.set-reboot-to-firmware-setup",
2409                             NULL,
2410                             UID_INVALID,
2411                             &challenge,
2412                             error);
2413         if (r < 0)
2414                 return r;
2415
2416         if (r > 0)
2417                 result = "yes";
2418         else if (challenge)
2419                 result = "challenge";
2420         else
2421                 result = "no";
2422
2423         return sd_bus_reply_method_return(message, "s", result);
2424 #else
2425         return sd_bus_reply_method_return(message, "s", "na");
2426 #endif // 0
2427 }
2428
2429 static int method_set_wall_message(
2430                 sd_bus_message *message,
2431                 void *userdata,
2432                 sd_bus_error *error) {
2433
2434         int r;
2435         Manager *m = userdata;
2436         char *wall_message;
2437         int enable_wall_messages;
2438
2439         assert(message);
2440         assert(m);
2441
2442         r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
2443         if (r < 0)
2444                 return r;
2445
2446         r = bus_verify_polkit_async(message,
2447                                     CAP_SYS_ADMIN,
2448                                     "org.freedesktop.login1.set-wall-message",
2449                                     NULL,
2450                                     false,
2451                                     UID_INVALID,
2452                                     &m->polkit_registry,
2453                                     error);
2454         if (r < 0)
2455                 return r;
2456         if (r == 0)
2457                 return 1; /* Will call us back */
2458
2459         if (isempty(wall_message))
2460                 m->wall_message = mfree(m->wall_message);
2461         else {
2462                 r = free_and_strdup(&m->wall_message, wall_message);
2463                 if (r < 0)
2464                         return log_oom();
2465         }
2466
2467         m->enable_wall_messages = enable_wall_messages;
2468
2469         return sd_bus_reply_method_return(message, NULL);
2470 }
2471
2472 static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2473         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2474         const char *who, *why, *what, *mode;
2475         _cleanup_free_ char *id = NULL;
2476         _cleanup_close_ int fifo_fd = -1;
2477         Manager *m = userdata;
2478         Inhibitor *i = NULL;
2479         InhibitMode mm;
2480         InhibitWhat w;
2481         pid_t pid;
2482         uid_t uid;
2483         int r;
2484
2485         assert(message);
2486         assert(m);
2487
2488         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2489         if (r < 0)
2490                 return r;
2491
2492         w = inhibit_what_from_string(what);
2493         if (w <= 0)
2494                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2495
2496         mm = inhibit_mode_from_string(mode);
2497         if (mm < 0)
2498                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2499
2500         /* Delay is only supported for shutdown/sleep */
2501         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2502                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2503
2504         /* Don't allow taking delay locks while we are already
2505          * executing the operation. We shouldn't create the impression
2506          * that the lock was successful if the machine is about to go
2507          * down/suspend any moment. */
2508         if (m->action_what & w)
2509                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2510
2511         r = bus_verify_polkit_async(
2512                         message,
2513                         CAP_SYS_BOOT,
2514                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2515                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
2516                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
2517                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
2518                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2519                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2520                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
2521                         NULL,
2522                         false,
2523                         UID_INVALID,
2524                         &m->polkit_registry,
2525                         error);
2526         if (r < 0)
2527                 return r;
2528         if (r == 0)
2529                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2530
2531         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2532         if (r < 0)
2533                 return r;
2534
2535         r = sd_bus_creds_get_euid(creds, &uid);
2536         if (r < 0)
2537                 return r;
2538
2539         r = sd_bus_creds_get_pid(creds, &pid);
2540         if (r < 0)
2541                 return r;
2542
2543         if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
2544                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.", m->inhibitors_max);
2545
2546         do {
2547                 id = mfree(id);
2548
2549                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2550                         return -ENOMEM;
2551
2552         } while (hashmap_get(m->inhibitors, id));
2553
2554         r = manager_add_inhibitor(m, id, &i);
2555         if (r < 0)
2556                 return r;
2557
2558         i->what = w;
2559         i->mode = mm;
2560         i->pid = pid;
2561         i->uid = uid;
2562         i->why = strdup(why);
2563         i->who = strdup(who);
2564
2565         if (!i->why || !i->who) {
2566                 r = -ENOMEM;
2567                 goto fail;
2568         }
2569
2570         fifo_fd = inhibitor_create_fifo(i);
2571         if (fifo_fd < 0) {
2572                 r = fifo_fd;
2573                 goto fail;
2574         }
2575
2576         inhibitor_start(i);
2577
2578         return sd_bus_reply_method_return(message, "h", fifo_fd);
2579
2580 fail:
2581         if (i)
2582                 inhibitor_free(i);
2583
2584         return r;
2585 }
2586
2587 const sd_bus_vtable manager_vtable[] = {
2588         SD_BUS_VTABLE_START(0),
2589
2590         SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
2591         SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
2592
2593 //        SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2594         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2595         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2596         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2597         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2598         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2599         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2600         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2601         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2602         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2603         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2604         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2605         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2606         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2607         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2608         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2609         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2610         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2611         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2612         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2613         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2614         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
2615         SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
2616         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
2617         SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
2618         SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
2619         SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0),
2620         SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
2621         SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0),
2622         SD_BUS_PROPERTY("UserTasksMax", "t", NULL, offsetof(Manager, user_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
2623
2624         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2625         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2626         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2627         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2628         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2629         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2630         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2631         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2632         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2633         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2634         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2635         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2636         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2637         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2638         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2639         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2640         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2641         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2642         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2643         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2644         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2645         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2646         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2647         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2648         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2649         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2650         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2651         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2652         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2653         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2654         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2655         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2656         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2657         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2658         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2659         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2660         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
2661         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2662         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2663         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2664         SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
2665
2666         SD_BUS_SIGNAL("SessionNew", "so", 0),
2667         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2668         SD_BUS_SIGNAL("UserNew", "uo", 0),
2669         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2670         SD_BUS_SIGNAL("SeatNew", "so", 0),
2671         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2672         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2673         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2674
2675         SD_BUS_VTABLE_END
2676 };
2677
2678 #if 0 /// UNNEEDED by elogind
2679 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2680         int r = 0;
2681
2682         assert(s);
2683         assert(unit);
2684
2685         if (!s->started)
2686                 return r;
2687
2688         if (streq(result, "done"))
2689                 r = session_send_create_reply(s, NULL);
2690         else {
2691                 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
2692
2693                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2694                 r = session_send_create_reply(s, &e);
2695         }
2696
2697         return r;
2698 }
2699
2700 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2701         const char *path, *result, *unit;
2702         Manager *m = userdata;
2703         Session *session;
2704         uint32_t id;
2705         User *user;
2706         int r;
2707
2708         assert(message);
2709         assert(m);
2710
2711         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2712         if (r < 0) {
2713                 bus_log_parse_error(r);
2714                 return 0;
2715         }
2716
2717         if (m->action_job && streq(m->action_job, path)) {
2718                 log_info("Operation '%s' finished.", inhibit_what_to_string(m->action_what));
2719
2720                 /* Tell people that they now may take a lock again */
2721                 send_prepare_for(m, m->action_what, false);
2722
2723                 m->action_job = mfree(m->action_job);
2724                 m->action_unit = NULL;
2725                 m->action_what = 0;
2726                 return 0;
2727         }
2728
2729         session = hashmap_get(m->session_units, unit);
2730         if (session && streq_ptr(path, session->scope_job)) {
2731                 session->scope_job = mfree(session->scope_job);
2732                 session_jobs_reply(session, unit, result);
2733
2734                 session_save(session);
2735                 user_save(session->user);
2736                 session_add_to_gc_queue(session);
2737         }
2738
2739         user = hashmap_get(m->user_units, unit);
2740         if (user &&
2741             (streq_ptr(path, user->service_job) ||
2742              streq_ptr(path, user->slice_job))) {
2743
2744                 if (streq_ptr(path, user->service_job))
2745                         user->service_job = mfree(user->service_job);
2746
2747                 if (streq_ptr(path, user->slice_job))
2748                         user->slice_job = mfree(user->slice_job);
2749
2750                 LIST_FOREACH(sessions_by_user, session, user->sessions)
2751                         session_jobs_reply(session, unit, result);
2752
2753                 user_save(user);
2754                 user_add_to_gc_queue(user);
2755         }
2756
2757         return 0;
2758 }
2759
2760 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2761         const char *path, *unit;
2762         Manager *m = userdata;
2763         Session *session;
2764         User *user;
2765         int r;
2766
2767         assert(message);
2768         assert(m);
2769
2770         r = sd_bus_message_read(message, "so", &unit, &path);
2771         if (r < 0) {
2772                 bus_log_parse_error(r);
2773                 return 0;
2774         }
2775
2776         session = hashmap_get(m->session_units, unit);
2777         if (session)
2778                 session_add_to_gc_queue(session);
2779
2780         user = hashmap_get(m->user_units, unit);
2781         if (user)
2782                 user_add_to_gc_queue(user);
2783
2784         return 0;
2785 }
2786
2787 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2788         _cleanup_free_ char *unit = NULL;
2789         Manager *m = userdata;
2790         const char *path;
2791         Session *session;
2792         User *user;
2793         int r;
2794
2795         assert(message);
2796         assert(m);
2797
2798         path = sd_bus_message_get_path(message);
2799         if (!path)
2800                 return 0;
2801
2802         r = unit_name_from_dbus_path(path, &unit);
2803         if (r == -EINVAL) /* not a unit */
2804                 return 0;
2805         if (r < 0) {
2806                 log_oom();
2807                 return 0;
2808         }
2809
2810         session = hashmap_get(m->session_units, unit);
2811         if (session)
2812                 session_add_to_gc_queue(session);
2813
2814         user = hashmap_get(m->user_units, unit);
2815         if (user)
2816                 user_add_to_gc_queue(user);
2817
2818         return 0;
2819 }
2820
2821 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2822         Manager *m = userdata;
2823         Session *session;
2824         Iterator i;
2825         int b, r;
2826
2827         assert(message);
2828         assert(m);
2829
2830         r = sd_bus_message_read(message, "b", &b);
2831         if (r < 0) {
2832                 bus_log_parse_error(r);
2833                 return 0;
2834         }
2835
2836         if (b)
2837                 return 0;
2838
2839         /* systemd finished reloading, let's recheck all our sessions */
2840         log_debug("System manager has been reloaded, rechecking sessions...");
2841
2842         HASHMAP_FOREACH(session, m->sessions, i)
2843                 session_add_to_gc_queue(session);
2844
2845         return 0;
2846 }
2847 #endif // 0
2848
2849 int manager_send_changed(Manager *manager, const char *property, ...) {
2850         char **l;
2851
2852         assert(manager);
2853
2854         l = strv_from_stdarg_alloca(property);
2855
2856         return sd_bus_emit_properties_changed_strv(
2857                         manager->bus,
2858                         "/org/freedesktop/login1",
2859                         "org.freedesktop.login1.Manager",
2860                         l);
2861 }
2862
2863 #if 0 /// UNNEEDED by elogind
2864 static int strdup_job(sd_bus_message *reply, char **job) {
2865         const char *j;
2866         char *copy;
2867         int r;
2868
2869         r = sd_bus_message_read(reply, "o", &j);
2870         if (r < 0)
2871                 return r;
2872
2873         copy = strdup(j);
2874         if (!copy)
2875                 return -ENOMEM;
2876
2877         *job = copy;
2878         return 1;
2879 }
2880
2881 int manager_start_slice(
2882                 Manager *manager,
2883                 const char *slice,
2884                 const char *description,
2885                 const char *after,
2886                 const char *after2,
2887                 uint64_t tasks_max,
2888                 sd_bus_error *error,
2889                 char **job) {
2890
2891         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
2892         int r;
2893
2894         assert(manager);
2895         assert(slice);
2896
2897         r = sd_bus_message_new_method_call(
2898                         manager->bus,
2899                         &m,
2900                         "org.freedesktop.systemd1",
2901                         "/org/freedesktop/systemd1",
2902                         "org.freedesktop.systemd1.Manager",
2903                         "StartTransientUnit");
2904         if (r < 0)
2905                 return r;
2906
2907         r = sd_bus_message_append(m, "ss", strempty(slice), "fail");
2908         if (r < 0)
2909                 return r;
2910
2911         r = sd_bus_message_open_container(m, 'a', "(sv)");
2912         if (r < 0)
2913                 return r;
2914
2915         if (!isempty(description)) {
2916                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2917                 if (r < 0)
2918                         return r;
2919         }
2920
2921         if (!isempty(after)) {
2922                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2923                 if (r < 0)
2924                         return r;
2925         }
2926
2927         if (!isempty(after2)) {
2928                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2929                 if (r < 0)
2930                         return r;
2931         }
2932
2933         r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
2934         if (r < 0)
2935                 return r;
2936
2937         r = sd_bus_message_close_container(m);
2938         if (r < 0)
2939                 return r;
2940
2941         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2942         if (r < 0)
2943                 return r;
2944
2945         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2946         if (r < 0)
2947                 return r;
2948
2949         if (job)
2950                 return strdup_job(reply, job);
2951         return 1;
2952 }
2953
2954 int manager_start_scope(
2955                 Manager *manager,
2956                 const char *scope,
2957                 pid_t pid,
2958                 const char *slice,
2959                 const char *description,
2960                 const char *after,
2961                 const char *after2,
2962                 uint64_t tasks_max,
2963                 sd_bus_error *error,
2964                 char **job) {
2965
2966         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
2967         int r;
2968
2969         assert(manager);
2970         assert(scope);
2971         assert(pid > 1);
2972
2973         r = sd_bus_message_new_method_call(
2974                         manager->bus,
2975                         &m,
2976                         "org.freedesktop.systemd1",
2977                         "/org/freedesktop/systemd1",
2978                         "org.freedesktop.systemd1.Manager",
2979                         "StartTransientUnit");
2980         if (r < 0)
2981                 return r;
2982
2983         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2984         if (r < 0)
2985                 return r;
2986
2987         r = sd_bus_message_open_container(m, 'a', "(sv)");
2988         if (r < 0)
2989                 return r;
2990
2991         if (!isempty(slice)) {
2992                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2993                 if (r < 0)
2994                         return r;
2995         }
2996
2997         if (!isempty(description)) {
2998                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2999                 if (r < 0)
3000                         return r;
3001         }
3002
3003         if (!isempty(after)) {
3004                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
3005                 if (r < 0)
3006                         return r;
3007         }
3008
3009         if (!isempty(after2)) {
3010                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
3011                 if (r < 0)
3012                         return r;
3013         }
3014
3015         /* cgroup empty notification is not available in containers
3016          * currently. To make this less problematic, let's shorten the
3017          * stop timeout for sessions, so that we don't wait
3018          * forever. */
3019
3020         /* Make sure that the session shells are terminated with
3021          * SIGHUP since bash and friends tend to ignore SIGTERM */
3022         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
3023         if (r < 0)
3024                 return r;
3025
3026         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
3027         if (r < 0)
3028                 return r;
3029
3030         r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
3031         if (r < 0)
3032                 return r;
3033
3034         r = sd_bus_message_close_container(m);
3035         if (r < 0)
3036                 return r;
3037
3038         r = sd_bus_message_append(m, "a(sa(sv))", 0);
3039         if (r < 0)
3040                 return r;
3041
3042         r = sd_bus_call(manager->bus, m, 0, error, &reply);
3043         if (r < 0)
3044                 return r;
3045
3046         if (job)
3047                 return strdup_job(reply, job);
3048         return 1;
3049 }
3050
3051 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
3052         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3053         int r;
3054
3055         assert(manager);
3056         assert(unit);
3057
3058         r = sd_bus_call_method(
3059                         manager->bus,
3060                         "org.freedesktop.systemd1",
3061                         "/org/freedesktop/systemd1",
3062                         "org.freedesktop.systemd1.Manager",
3063                         "StartUnit",
3064                         error,
3065                         &reply,
3066                         "ss", unit, "replace");
3067         if (r < 0)
3068                 return r;
3069
3070         if (job)
3071                 return strdup_job(reply, job);
3072         return 1;
3073 }
3074
3075 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
3076         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3077         int r;
3078
3079         assert(manager);
3080         assert(unit);
3081
3082         r = sd_bus_call_method(
3083                         manager->bus,
3084                         "org.freedesktop.systemd1",
3085                         "/org/freedesktop/systemd1",
3086                         "org.freedesktop.systemd1.Manager",
3087                         "StopUnit",
3088                         error,
3089                         &reply,
3090                         "ss", unit, "fail");
3091         if (r < 0) {
3092                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
3093                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
3094
3095                         if (job)
3096                                 *job = NULL;
3097
3098                         sd_bus_error_free(error);
3099                         return 0;
3100                 }
3101
3102                 return r;
3103         }
3104
3105         if (job)
3106                 return strdup_job(reply, job);
3107         return 1;
3108 }
3109
3110 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
3111         _cleanup_free_ char *path = NULL;
3112         int r;
3113
3114         assert(manager);
3115         assert(scope);
3116
3117         path = unit_dbus_path_from_name(scope);
3118         if (!path)
3119                 return -ENOMEM;
3120
3121         r = sd_bus_call_method(
3122                         manager->bus,
3123                         "org.freedesktop.systemd1",
3124                         path,
3125                         "org.freedesktop.systemd1.Scope",
3126                         "Abandon",
3127                         error,
3128                         NULL,
3129                         NULL);
3130         if (r < 0) {
3131                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
3132                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
3133                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
3134                         sd_bus_error_free(error);
3135                         return 0;
3136                 }
3137
3138                 return r;
3139         }
3140
3141         return 1;
3142 }
3143
3144 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
3145         assert(manager);
3146         assert(unit);
3147
3148         return sd_bus_call_method(
3149                         manager->bus,
3150                         "org.freedesktop.systemd1",
3151                         "/org/freedesktop/systemd1",
3152                         "org.freedesktop.systemd1.Manager",
3153                         "KillUnit",
3154                         error,
3155                         NULL,
3156                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
3157 }
3158
3159 int manager_unit_is_active(Manager *manager, const char *unit) {
3160         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3161         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3162         _cleanup_free_ char *path = NULL;
3163         const char *state;
3164         int r;
3165
3166         assert(manager);
3167         assert(unit);
3168
3169         path = unit_dbus_path_from_name(unit);
3170         if (!path)
3171                 return -ENOMEM;
3172
3173         r = sd_bus_get_property(
3174                         manager->bus,
3175                         "org.freedesktop.systemd1",
3176                         path,
3177                         "org.freedesktop.systemd1.Unit",
3178                         "ActiveState",
3179                         &error,
3180                         &reply,
3181                         "s");
3182         if (r < 0) {
3183                 /* systemd might have droppped off momentarily, let's
3184                  * not make this an error */
3185                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3186                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3187                         return true;
3188
3189                 /* If the unit is already unloaded then it's not
3190                  * active */
3191                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
3192                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
3193                         return false;
3194
3195                 return r;
3196         }
3197
3198         r = sd_bus_message_read(reply, "s", &state);
3199         if (r < 0)
3200                 return -EINVAL;
3201
3202         return !streq(state, "inactive") && !streq(state, "failed");
3203 }
3204
3205 int manager_job_is_active(Manager *manager, const char *path) {
3206         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3207         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
3208         int r;
3209
3210         assert(manager);
3211         assert(path);
3212
3213         r = sd_bus_get_property(
3214                         manager->bus,
3215                         "org.freedesktop.systemd1",
3216                         path,
3217                         "org.freedesktop.systemd1.Job",
3218                         "State",
3219                         &error,
3220                         &reply,
3221                         "s");
3222         if (r < 0) {
3223                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
3224                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
3225                         return true;
3226
3227                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
3228                         return false;
3229
3230                 return r;
3231         }
3232
3233         /* We don't actually care about the state really. The fact
3234          * that we could read the job state is enough for us */
3235
3236         return true;
3237 }
3238 #endif // 0