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