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