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