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