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