chiark / gitweb /
logind,machined,run: properly invoke StartTransientUnit() bus call
[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-id128.h"
28 #include "sd-messages.h"
29 #include "strv.h"
30 #include "mkdir.h"
31 #include "path-util.h"
32 #include "special.h"
33 #include "sleep-config.h"
34 #include "fileio-label.h"
35 #include "label.h"
36 #include "utf8.h"
37 #include "unit-name.h"
38 #include "virt.h"
39 #include "audit.h"
40 #include "bus-util.h"
41 #include "bus-error.h"
42 #include "logind.h"
43 #include "bus-errors.h"
44
45 static int property_get_idle_hint(
46                 sd_bus *bus,
47                 const char *path,
48                 const char *interface,
49                 const char *property,
50                 sd_bus_message *reply,
51                 void *userdata,
52                 sd_bus_error *error) {
53
54         Manager *m = userdata;
55
56         assert(bus);
57         assert(reply);
58         assert(m);
59
60         return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
61 }
62
63 static int property_get_idle_since_hint(
64                 sd_bus *bus,
65                 const char *path,
66                 const char *interface,
67                 const char *property,
68                 sd_bus_message *reply,
69                 void *userdata,
70                 sd_bus_error *error) {
71
72         Manager *m = userdata;
73         dual_timestamp t;
74
75         assert(bus);
76         assert(reply);
77         assert(m);
78
79         manager_get_idle_hint(m, &t);
80
81         return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
82 }
83
84 static int property_get_inhibited(
85                 sd_bus *bus,
86                 const char *path,
87                 const char *interface,
88                 const char *property,
89                 sd_bus_message *reply,
90                 void *userdata,
91                 sd_bus_error *error) {
92
93         Manager *m = userdata;
94         InhibitWhat w;
95
96         assert(bus);
97         assert(reply);
98         assert(m);
99
100         w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
101
102         return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
103 }
104
105 static int property_get_preparing(
106                 sd_bus *bus,
107                 const char *path,
108                 const char *interface,
109                 const char *property,
110                 sd_bus_message *reply,
111                 void *userdata,
112                 sd_bus_error *error) {
113
114         Manager *m = userdata;
115         bool b;
116
117         assert(bus);
118         assert(reply);
119         assert(m);
120
121         if (streq(property, "PreparingForShutdown"))
122                 b = !!(m->action_what & INHIBIT_SHUTDOWN);
123         else
124                 b = !!(m->action_what & INHIBIT_SLEEP);
125
126         return sd_bus_message_append(reply, "b", b);
127 }
128
129 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
130
131 static int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
132         _cleanup_free_ char *p = NULL;
133         Manager *m = userdata;
134         const char *name;
135         Session *session;
136         int r;
137
138         assert(bus);
139         assert(message);
140         assert(m);
141
142         r = sd_bus_message_read(message, "s", &name);
143         if (r < 0)
144                 return r;
145
146         session = hashmap_get(m->sessions, name);
147         if (!session)
148                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
149
150         p = session_bus_path(session);
151         if (!p)
152                 return -ENOMEM;
153
154         return sd_bus_reply_method_return(message, "o", p);
155 }
156
157 static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
158         _cleanup_free_ char *p = NULL;
159         Session *session = NULL;
160         Manager *m = userdata;
161         pid_t pid;
162         int r;
163
164         assert(bus);
165         assert(message);
166         assert(m);
167
168         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
169
170         r = sd_bus_message_read(message, "u", &pid);
171         if (r < 0)
172                 return r;
173
174         if (pid == 0) {
175                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
176                 if (r < 0)
177                         return r;
178         }
179
180         r = manager_get_session_by_pid(m, pid, &session);
181         if (r < 0)
182                 return r;
183         if (!session)
184                 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
185
186         p = session_bus_path(session);
187         if (!p)
188                 return -ENOMEM;
189
190         return sd_bus_reply_method_return(message, "o", p);
191 }
192
193 static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
194         _cleanup_free_ char *p = NULL;
195         Manager *m = userdata;
196         uint32_t uid;
197         User *user;
198         int r;
199
200         assert(bus);
201         assert(message);
202         assert(m);
203
204         r = sd_bus_message_read(message, "u", &uid);
205         if (r < 0)
206                 return r;
207
208         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
209         if (!user)
210                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
211
212         p = user_bus_path(user);
213         if (!p)
214                 return -ENOMEM;
215
216         return sd_bus_reply_method_return(message, "o", p);
217 }
218
219 static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
220         _cleanup_free_ char *p = NULL;
221         Manager *m = userdata;
222         User *user = NULL;
223         pid_t pid;
224         int r;
225
226         assert(bus);
227         assert(message);
228         assert(m);
229
230         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
231
232         r = sd_bus_message_read(message, "u", &pid);
233         if (r < 0)
234                 return r;
235
236         if (pid == 0) {
237                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
238                 if (r < 0)
239                         return r;
240         }
241
242         r = manager_get_user_by_pid(m, pid, &user);
243         if (r < 0)
244                 return r;
245         if (!user)
246                 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
247
248         p = user_bus_path(user);
249         if (!p)
250                 return -ENOMEM;
251
252         return sd_bus_reply_method_return(message, "o", p);
253 }
254
255 static int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
256         _cleanup_free_ char *p = NULL;
257         Manager *m = userdata;
258         const char *name;
259         Seat *seat;
260         int r;
261
262         assert(bus);
263         assert(message);
264         assert(m);
265
266         r = sd_bus_message_read(message, "s", &name);
267         if (r < 0)
268                 return r;
269
270         seat = hashmap_get(m->seats, name);
271         if (!seat)
272                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
273
274         p = seat_bus_path(seat);
275         if (!p)
276                 return -ENOMEM;
277
278         return sd_bus_reply_method_return(message, "o", p);
279 }
280
281 static int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
282         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
283         Manager *m = userdata;
284         Session *session;
285         Iterator i;
286         int r;
287
288         assert(bus);
289         assert(message);
290         assert(m);
291
292         r = sd_bus_message_new_method_return(message, &reply);
293         if (r < 0)
294                 return r;
295
296         r = sd_bus_message_open_container(reply, 'a', "(susso)");
297         if (r < 0)
298                 return r;
299
300         HASHMAP_FOREACH(session, m->sessions, i) {
301                 _cleanup_free_ char *p = NULL;
302
303                 p = session_bus_path(session);
304                 if (!p)
305                         return -ENOMEM;
306
307                 r = sd_bus_message_append(reply, "(susso)",
308                                           session->id,
309                                           (uint32_t) session->user->uid,
310                                           session->user->name,
311                                           session->seat ? session->seat->id : "",
312                                           p);
313                 if (r < 0)
314                         return r;
315         }
316
317         r = sd_bus_message_close_container(reply);
318         if (r < 0)
319                 return r;
320
321         return sd_bus_send(bus, reply, NULL);
322 }
323
324 static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
325         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
326         Manager *m = userdata;
327         User *user;
328         Iterator i;
329         int r;
330
331         assert(bus);
332         assert(message);
333         assert(m);
334
335         r = sd_bus_message_new_method_return(message, &reply);
336         if (r < 0)
337                 return r;
338
339         r = sd_bus_message_open_container(reply, 'a', "(uso)");
340         if (r < 0)
341                 return r;
342
343         HASHMAP_FOREACH(user, m->users, i) {
344                 _cleanup_free_ char *p = NULL;
345
346                 p = user_bus_path(user);
347                 if (!p)
348                         return -ENOMEM;
349
350                 r = sd_bus_message_append(reply, "(uso)",
351                                           (uint32_t) user->uid,
352                                           user->name,
353                                           p);
354                 if (r < 0)
355                         return r;
356         }
357
358         r = sd_bus_message_close_container(reply);
359         if (r < 0)
360                 return r;
361
362         return sd_bus_send(bus, reply, NULL);
363 }
364
365 static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
366         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
367         Manager *m = userdata;
368         Seat *seat;
369         Iterator i;
370         int r;
371
372         assert(bus);
373         assert(message);
374         assert(m);
375
376         r = sd_bus_message_new_method_return(message, &reply);
377         if (r < 0)
378                 return r;
379
380         r = sd_bus_message_open_container(reply, 'a', "(so)");
381         if (r < 0)
382                 return r;
383
384         HASHMAP_FOREACH(seat, m->seats, i) {
385                 _cleanup_free_ char *p = NULL;
386
387                 p = seat_bus_path(seat);
388                 if (!p)
389                         return -ENOMEM;
390
391                 r = sd_bus_message_append(reply, "(so)", seat->id, p);
392                 if (r < 0)
393                         return r;
394         }
395
396         r = sd_bus_message_close_container(reply);
397         if (r < 0)
398                 return r;
399
400         return sd_bus_send(bus, reply, NULL);
401 }
402
403 static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
404         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
405         Manager *m = userdata;
406         Inhibitor *inhibitor;
407         Iterator i;
408         int r;
409
410         r = sd_bus_message_new_method_return(message, &reply);
411         if (r < 0)
412                 return r;
413
414         r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
415         if (r < 0)
416                 return r;
417
418         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
419
420                 r = sd_bus_message_append(reply, "(ssssuu)",
421                                           strempty(inhibit_what_to_string(inhibitor->what)),
422                                           strempty(inhibitor->who),
423                                           strempty(inhibitor->why),
424                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
425                                           (uint32_t) inhibitor->uid,
426                                           (uint32_t) inhibitor->pid);
427                 if (r < 0)
428                         return r;
429         }
430
431         r = sd_bus_message_close_container(reply);
432         if (r < 0)
433                 return r;
434
435         return sd_bus_send(bus, reply, NULL);
436 }
437
438 static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
439         const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host;
440         uint32_t uid, leader, audit_id = 0;
441         _cleanup_free_ char *id = NULL;
442         Session *session = NULL;
443         Manager *m = userdata;
444         User *user = NULL;
445         Seat *seat = NULL;
446         int remote;
447         uint32_t vtnr = 0;
448         SessionType t;
449         SessionClass c;
450         int r;
451
452         assert(bus);
453         assert(message);
454         assert(m);
455
456         r = sd_bus_message_read(message, "uussssussbss", &uid, &leader, &service, &type, &class, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
457         if (r < 0)
458                 return r;
459
460         if (leader == 1)
461                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
462
463         if (isempty(type))
464                 t = _SESSION_TYPE_INVALID;
465         else {
466                 t = session_type_from_string(type);
467                 if (t < 0)
468                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
469         }
470
471         if (isempty(class))
472                 c = _SESSION_CLASS_INVALID;
473         else {
474                 c = session_class_from_string(class);
475                 if (c < 0)
476                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
477         }
478
479         if (isempty(cseat))
480                 seat = NULL;
481         else {
482                 seat = hashmap_get(m->seats, cseat);
483                 if (!seat)
484                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat);
485         }
486
487         if (tty_is_vc(tty)) {
488                 int v;
489
490                 if (!seat)
491                         seat = m->seat0;
492                 else if (seat != m->seat0)
493                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat);
494
495                 v = vtnr_from_tty(tty);
496                 if (v <= 0)
497                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
498
499                 if (vtnr <= 0)
500                         vtnr = (uint32_t) v;
501                 else if (vtnr != (uint32_t) v)
502                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
503
504         } else if (tty_is_console(tty)) {
505
506                 if (!seat)
507                         seat = m->seat0;
508                 else if (seat != m->seat0)
509                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
510
511                 if (vtnr != 0)
512                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
513         }
514
515         if (seat) {
516                 if (seat_has_vts(seat)) {
517                         if (vtnr > 63)
518                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
519                 } else {
520                         if (vtnr != 0)
521                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
522                 }
523         }
524
525         r = sd_bus_message_enter_container(message, 'a', "(sv)");
526         if (r < 0)
527                 return r;
528
529         if (t == _SESSION_TYPE_INVALID) {
530                 if (!isempty(display))
531                         t = SESSION_X11;
532                 else if (!isempty(tty))
533                         t = SESSION_TTY;
534                 else
535                         t = SESSION_UNSPECIFIED;
536         }
537
538         if (c == _SESSION_CLASS_INVALID) {
539                 if (!isempty(display) || !isempty(tty))
540                         c = SESSION_USER;
541                 else
542                         c = SESSION_BACKGROUND;
543         }
544
545         if (leader <= 0) {
546                 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
547
548                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
549                 if (r < 0)
550                         return r;
551         }
552
553         manager_get_session_by_pid(m, leader, &session);
554         if (session) {
555                 _cleanup_free_ char *path = NULL;
556                 _cleanup_close_ int fifo_fd = -1;
557
558                 /* Session already exists, client is probably
559                  * something like "su" which changes uid but is still
560                  * the same session */
561
562                 fifo_fd = session_create_fifo(session);
563                 if (fifo_fd < 0)
564                         return fifo_fd;
565
566                 path = session_bus_path(session);
567                 if (!path)
568                         return -ENOMEM;
569
570                 return sd_bus_reply_method_return(
571                                 message, "soshsub",
572                                 session->id,
573                                 path,
574                                 session->user->runtime_path,
575                                 fifo_fd,
576                                 session->seat ? session->seat->id : "",
577                                 (uint32_t) session->vtnr,
578                                 true);
579         }
580
581         audit_session_from_pid(leader, &audit_id);
582         if (audit_id > 0) {
583                 /* Keep our session IDs and the audit session IDs in sync */
584
585                 if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
586                         return -ENOMEM;
587
588                 /* Wut? There's already a session by this name and we
589                  * didn't find it above? Weird, then let's not trust
590                  * the audit data and let's better register a new
591                  * ID */
592                 if (hashmap_get(m->sessions, id)) {
593                         log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
594                         audit_id = 0;
595
596                         free(id);
597                         id = NULL;
598                 }
599         }
600
601         if (!id) {
602                 do {
603                         free(id);
604                         id = NULL;
605
606                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
607                                 return -ENOMEM;
608
609                 } while (hashmap_get(m->sessions, id));
610         }
611
612         r = manager_add_user_by_uid(m, uid, &user);
613         if (r < 0)
614                 goto fail;
615
616         r = manager_add_session(m, id, &session);
617         if (r < 0)
618                 goto fail;
619
620         session_set_user(session, user);
621
622         session->leader = leader;
623         session->audit_id = audit_id;
624         session->type = t;
625         session->class = c;
626         session->remote = remote;
627         session->vtnr = vtnr;
628
629         if (!isempty(tty)) {
630                 session->tty = strdup(tty);
631                 if (!session->tty) {
632                         r = -ENOMEM;
633                         goto fail;
634                 }
635         }
636
637         if (!isempty(display)) {
638                 session->display = strdup(display);
639                 if (!session->display) {
640                         r = -ENOMEM;
641                         goto fail;
642                 }
643         }
644
645         if (!isempty(remote_user)) {
646                 session->remote_user = strdup(remote_user);
647                 if (!session->remote_user) {
648                         r = -ENOMEM;
649                         goto fail;
650                 }
651         }
652
653         if (!isempty(remote_host)) {
654                 session->remote_host = strdup(remote_host);
655                 if (!session->remote_host) {
656                         r = -ENOMEM;
657                         goto fail;
658                 }
659         }
660
661         if (!isempty(service)) {
662                 session->service = strdup(service);
663                 if (!session->service) {
664                         r = -ENOMEM;
665                         goto fail;
666                 }
667         }
668
669         if (seat) {
670                 r = seat_attach_session(seat, session);
671                 if (r < 0)
672                         goto fail;
673         }
674
675         r = session_start(session);
676         if (r < 0)
677                 goto fail;
678
679         session->create_message = sd_bus_message_ref(message);
680
681         /* Now, let's wait until the slice unit and stuff got
682          * created. We send the reply back from
683          * session_send_create_reply().*/
684
685         return 1;
686
687 fail:
688         if (session)
689                 session_add_to_gc_queue(session);
690
691         if (user)
692                 user_add_to_gc_queue(user);
693
694         return r;
695 }
696
697 static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
698         Manager *m = userdata;
699         Session *session;
700         const char *name;
701         int r;
702
703         assert(bus);
704         assert(message);
705         assert(m);
706
707         r = sd_bus_message_read(message, "s", &name);
708         if (r < 0)
709                 return r;
710
711         session = hashmap_get(m->sessions, name);
712         if (!session)
713                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
714
715         /* We use the FIFO to detect stray sessions where the process
716            invoking PAM dies abnormally. We need to make sure that
717            that process is not killed if at the clean end of the
718            session it closes the FIFO. Hence, with this call
719            explicitly turn off the FIFO logic, so that the PAM code
720            can finish clean up on its own */
721         session_remove_fifo(session);
722         session_save(session);
723         user_save(session->user);
724
725         return sd_bus_reply_method_return(message, NULL);
726 }
727
728 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
729         Manager *m = userdata;
730         Session *session;
731         const char *name;
732         int r;
733
734         assert(bus);
735         assert(message);
736         assert(m);
737
738         r = sd_bus_message_read(message, "s", &name);
739         if (r < 0)
740                 return r;
741
742         session = hashmap_get(m->sessions, name);
743         if (!session)
744                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
745
746         r = session_activate(session);
747         if (r < 0)
748                 return r;
749
750         return sd_bus_reply_method_return(message, NULL);
751 }
752
753 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
754         const char *session_name, *seat_name;
755         Manager *m = userdata;
756         Session *session;
757         Seat *seat;
758         int r;
759
760         assert(bus);
761         assert(message);
762         assert(m);
763
764         /* Same as ActivateSession() but refuses to work if
765          * the seat doesn't match */
766
767         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
768         if (r < 0)
769                 return r;
770
771         session = hashmap_get(m->sessions, session_name);
772         if (!session)
773                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
774
775         seat = hashmap_get(m->seats, seat_name);
776         if (!seat)
777                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
778
779         if (session->seat != seat)
780                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
781
782         r = session_activate(session);
783         if (r < 0)
784                 return r;
785
786         return sd_bus_reply_method_return(message, NULL);
787 }
788
789 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
790         Manager *m = userdata;
791         Session *session;
792         const char *name;
793         int r;
794
795         assert(bus);
796         assert(message);
797         assert(m);
798
799         r = sd_bus_message_read(message, "s", &name);
800         if (r < 0)
801                 return r;
802
803         session = hashmap_get(m->sessions, name);
804         if (!session)
805                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
806
807         r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
808         if (r < 0)
809                 return r;
810
811         return sd_bus_reply_method_return(message, NULL);
812 }
813
814 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
815         Manager *m = userdata;
816         int r;
817
818         assert(bus);
819         assert(message);
820         assert(m);
821
822         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
823         if (r < 0)
824                 return r;
825
826         return sd_bus_reply_method_return(message, NULL);
827 }
828
829 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
830         const char *name, *swho;
831         Manager *m = userdata;
832         Session *session;
833         int32_t signo;
834         KillWho who;
835         int r;
836
837         assert(bus);
838         assert(message);
839         assert(m);
840
841         r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
842         if (r < 0)
843                 return r;
844
845         if (isempty(swho))
846                 who = KILL_ALL;
847         else {
848                 who = kill_who_from_string(swho);
849                 if (who < 0)
850                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
851         }
852
853         if (signo <= 0 || signo >= _NSIG)
854                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
855
856         session = hashmap_get(m->sessions, name);
857         if (!session)
858                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
859
860         r = session_kill(session, who, signo);
861         if (r < 0)
862                 return r;
863
864         return sd_bus_reply_method_return(message, NULL);
865 }
866
867 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
868         Manager *m = userdata;
869         uint32_t uid;
870         int32_t signo;
871         User *user;
872         int r;
873
874         assert(bus);
875         assert(message);
876         assert(m);
877
878         r = sd_bus_message_read(message, "ui", &uid, &signo);
879         if (r < 0)
880                 return r;
881
882         if (signo <= 0 || signo >= _NSIG)
883                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
884
885         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
886         if (!user)
887                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
888
889         r = user_kill(user, signo);
890         if (r < 0)
891                 return r;
892
893         return sd_bus_reply_method_return(message, NULL);
894 }
895
896 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
897         Manager *m = userdata;
898         const char *name;
899         Session *session;
900         int r;
901
902         assert(bus);
903         assert(message);
904         assert(m);
905
906         r = sd_bus_message_read(message, "s", &name);
907         if (r < 0)
908                 return r;
909
910         session = hashmap_get(m->sessions, name);
911         if (!session)
912                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
913
914         r = session_stop(session);
915         if (r < 0)
916                 return r;
917
918         return sd_bus_reply_method_return(message, NULL);
919 }
920
921 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
922         Manager *m = userdata;
923         uint32_t uid;
924         User *user;
925         int r;
926
927         assert(bus);
928         assert(message);
929         assert(m);
930
931         r = sd_bus_message_read(message, "u", &uid);
932         if (r < 0)
933                 return r;
934
935         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
936         if (!user)
937                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
938
939         r = user_stop(user);
940         if (r < 0)
941                 return r;
942
943         return sd_bus_reply_method_return(message, NULL);
944 }
945
946 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
947         Manager *m = userdata;
948         const char *name;
949         Seat *seat;
950         int r;
951
952         assert(bus);
953         assert(message);
954         assert(m);
955
956         r = sd_bus_message_read(message, "s", &name);
957         if (r < 0)
958                 return r;
959
960         seat = hashmap_get(m->seats, name);
961         if (!seat)
962                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
963
964         r = seat_stop_sessions(seat);
965         if (r < 0)
966                 return r;
967
968         return sd_bus_reply_method_return(message, NULL);
969 }
970
971 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
972         _cleanup_free_ char *cc = NULL;
973         Manager *m = userdata;
974         int b, r;
975         struct passwd *pw;
976         const char *path;
977         uint32_t uid;
978         int interactive;
979
980         assert(bus);
981         assert(message);
982         assert(m);
983
984         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
985         if (r < 0)
986                 return r;
987
988         errno = 0;
989         pw = getpwuid(uid);
990         if (!pw)
991                 return errno ? -errno : -ENOENT;
992
993         r = bus_verify_polkit_async(bus,
994                                     &m->polkit_registry,
995                                     message,
996                                     "org.freedesktop.login1.set-user-linger",
997                                     interactive,
998                                     error,
999                                     method_set_user_linger, m);
1000         if (r < 0)
1001                 return r;
1002         if (r == 0)
1003                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1004
1005         mkdir_p_label("/var/lib/systemd", 0755);
1006
1007         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1008         if (r < 0)
1009                 return r;
1010
1011         cc = cescape(pw->pw_name);
1012         if (!cc)
1013                 return -ENOMEM;
1014
1015         path = strappenda("/var/lib/systemd/linger/", cc);
1016         if (b) {
1017                 User *u;
1018
1019                 r = touch(path);
1020                 if (r < 0)
1021                         return r;
1022
1023                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1024                         user_start(u);
1025
1026         } else {
1027                 User *u;
1028
1029                 r = unlink(path);
1030                 if (r < 0 && errno != ENOENT)
1031                         return -errno;
1032
1033                 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1034                 if (u)
1035                         user_add_to_gc_queue(u);
1036         }
1037
1038         return sd_bus_reply_method_return(message, NULL);
1039 }
1040
1041 static int trigger_device(Manager *m, struct udev_device *d) {
1042         struct udev_enumerate *e;
1043         struct udev_list_entry *first, *item;
1044         int r;
1045
1046         assert(m);
1047
1048         e = udev_enumerate_new(m->udev);
1049         if (!e) {
1050                 r = -ENOMEM;
1051                 goto finish;
1052         }
1053
1054         if (d) {
1055                 if (udev_enumerate_add_match_parent(e, d) < 0) {
1056                         r = -EIO;
1057                         goto finish;
1058                 }
1059         }
1060
1061         if (udev_enumerate_scan_devices(e) < 0) {
1062                 r = -EIO;
1063                 goto finish;
1064         }
1065
1066         first = udev_enumerate_get_list_entry(e);
1067         udev_list_entry_foreach(item, first) {
1068                 _cleanup_free_ char *t = NULL;
1069                 const char *p;
1070
1071                 p = udev_list_entry_get_name(item);
1072
1073                 t = strappend(p, "/uevent");
1074                 if (!t) {
1075                         r = -ENOMEM;
1076                         goto finish;
1077                 }
1078
1079                 write_string_file(t, "change");
1080         }
1081
1082         r = 0;
1083
1084 finish:
1085         if (e)
1086                 udev_enumerate_unref(e);
1087
1088         return r;
1089 }
1090
1091 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1092         _cleanup_free_ char *rule = NULL, *file = NULL;
1093         const char *id_for_seat;
1094         struct udev_device *d;
1095         int r;
1096
1097         assert(m);
1098         assert(seat);
1099         assert(sysfs);
1100
1101         d = udev_device_new_from_syspath(m->udev, sysfs);
1102         if (!d)
1103                 return -ENODEV;
1104
1105         if (!udev_device_has_tag(d, "seat")) {
1106                 r = -ENODEV;
1107                 goto finish;
1108         }
1109
1110         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1111         if (!id_for_seat) {
1112                 r = -ENODEV;
1113                 goto finish;
1114         }
1115
1116         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
1117                 r = -ENOMEM;
1118                 goto finish;
1119         }
1120
1121         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
1122                 r = -ENOMEM;
1123                 goto finish;
1124         }
1125
1126         mkdir_p_label("/etc/udev/rules.d", 0755);
1127         label_init("/etc");
1128         r = write_string_file_atomic_label(file, rule);
1129         if (r < 0)
1130                 goto finish;
1131
1132         r = trigger_device(m, d);
1133
1134 finish:
1135         if (d)
1136                 udev_device_unref(d);
1137
1138         return r;
1139 }
1140
1141 static int flush_devices(Manager *m) {
1142         _cleanup_closedir_ DIR *d;
1143
1144         assert(m);
1145
1146         d = opendir("/etc/udev/rules.d");
1147         if (!d) {
1148                 if (errno != ENOENT)
1149                         log_warning("Failed to open /etc/udev/rules.d: %m");
1150         } else {
1151                 struct dirent *de;
1152
1153                 while ((de = readdir(d))) {
1154
1155                         if (!dirent_is_file(de))
1156                                 continue;
1157
1158                         if (!startswith(de->d_name, "72-seat-"))
1159                                 continue;
1160
1161                         if (!endswith(de->d_name, ".rules"))
1162                                 continue;
1163
1164                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1165                                 log_warning("Failed to unlink %s: %m", de->d_name);
1166                 }
1167         }
1168
1169         return trigger_device(m, NULL);
1170 }
1171
1172 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1173         const char *sysfs, *seat;
1174         Manager *m = userdata;
1175         int interactive, r;
1176
1177         assert(bus);
1178         assert(message);
1179         assert(m);
1180
1181         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1182         if (r < 0)
1183                 return r;
1184
1185         if (!path_startswith(sysfs, "/sys"))
1186                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1187
1188         if (!seat_name_is_valid(seat))
1189                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1190
1191         r = bus_verify_polkit_async(bus,
1192                                     &m->polkit_registry,
1193                                     message,
1194                                     "org.freedesktop.login1.attach-device",
1195                                     interactive,
1196                                     error,
1197                                     method_attach_device, m);
1198         if (r < 0)
1199                 return r;
1200         if (r == 0)
1201                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1202
1203         r = attach_device(m, seat, sysfs);
1204         if (r < 0)
1205                 return r;
1206
1207         return sd_bus_reply_method_return(message, NULL);
1208 }
1209
1210 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1211         Manager *m = userdata;
1212         int interactive, r;
1213
1214         assert(bus);
1215         assert(message);
1216         assert(m);
1217
1218         r = sd_bus_message_read(message, "b", &interactive);
1219         if (r < 0)
1220                 return r;
1221
1222         r = bus_verify_polkit_async(bus,
1223                                     &m->polkit_registry,
1224                                     message,
1225                                     "org.freedesktop.login1.flush-devices",
1226                                     interactive,
1227                                     error,
1228                                     method_flush_devices, m);
1229         if (r < 0)
1230                 return r;
1231         if (r == 0)
1232                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1233
1234         r = flush_devices(m);
1235         if (r < 0)
1236                 return r;
1237
1238         return sd_bus_reply_method_return(message, NULL);
1239 }
1240
1241 static int have_multiple_sessions(
1242                 Manager *m,
1243                 uid_t uid) {
1244
1245         Session *session;
1246         Iterator i;
1247
1248         assert(m);
1249
1250         /* Check for other users' sessions. Greeter sessions do not
1251          * count, and non-login sessions do not count either. */
1252         HASHMAP_FOREACH(session, m->sessions, i)
1253                 if (session->class == SESSION_USER &&
1254                     !session->closing &&
1255                     session->user->uid != uid)
1256                         return true;
1257
1258         return false;
1259 }
1260
1261 static int bus_manager_log_shutdown(
1262                 Manager *m,
1263                 InhibitWhat w,
1264                 const char *unit_name) {
1265
1266         const char *p, *q;
1267
1268         assert(m);
1269         assert(unit_name);
1270
1271         if (w != INHIBIT_SHUTDOWN)
1272                 return 0;
1273
1274         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1275                 p = "MESSAGE=System is powering down.";
1276                 q = "SHUTDOWN=power-off";
1277         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1278                 p = "MESSAGE=System is halting.";
1279                 q = "SHUTDOWN=halt";
1280         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1281                 p = "MESSAGE=System is rebooting.";
1282                 q = "SHUTDOWN=reboot";
1283         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1284                 p = "MESSAGE=System is rebooting with kexec.";
1285                 q = "SHUTDOWN=kexec";
1286         } else {
1287                 p = "MESSAGE=System is shutting down.";
1288                 q = NULL;
1289         }
1290
1291         return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1292                           p,
1293                           q, NULL);
1294 }
1295
1296 static int execute_shutdown_or_sleep(
1297                 Manager *m,
1298                 InhibitWhat w,
1299                 const char *unit_name,
1300                 sd_bus_error *error) {
1301
1302         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1303         const char *p;
1304         char *c;
1305         int r;
1306
1307         assert(m);
1308         assert(w >= 0);
1309         assert(w < _INHIBIT_WHAT_MAX);
1310         assert(unit_name);
1311
1312         bus_manager_log_shutdown(m, w, unit_name);
1313
1314         r = sd_bus_call_method(
1315                         m->bus,
1316                         "org.freedesktop.systemd1",
1317                         "/org/freedesktop/systemd1",
1318                         "org.freedesktop.systemd1.Manager",
1319                         "StartUnit",
1320                         error,
1321                         &reply,
1322                         "ss", unit_name, "replace-irreversibly");
1323         if (r < 0)
1324                 return r;
1325
1326         r = sd_bus_message_read(reply, "o", &p);
1327         if (r < 0)
1328                 return r;
1329
1330         c = strdup(p);
1331         if (!c)
1332                 return -ENOMEM;
1333
1334         m->action_unit = unit_name;
1335         free(m->action_job);
1336         m->action_job = c;
1337         m->action_what = w;
1338
1339         return 0;
1340 }
1341
1342 static int delay_shutdown_or_sleep(
1343                 Manager *m,
1344                 InhibitWhat w,
1345                 const char *unit_name) {
1346
1347         assert(m);
1348         assert(w >= 0);
1349         assert(w < _INHIBIT_WHAT_MAX);
1350         assert(unit_name);
1351
1352         m->action_timestamp = now(CLOCK_MONOTONIC);
1353         m->action_unit = unit_name;
1354         m->action_what = w;
1355
1356         return 0;
1357 }
1358
1359 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1360
1361         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1362                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1363                 [INHIBIT_SLEEP] = "PrepareForSleep"
1364         };
1365
1366         int active = _active;
1367
1368         assert(m);
1369         assert(w >= 0);
1370         assert(w < _INHIBIT_WHAT_MAX);
1371         assert(signal_name[w]);
1372
1373         return sd_bus_emit_signal(m->bus,
1374                                   "/org/freedesktop/login1",
1375                                   "org.freedesktop.login1.Manager",
1376                                   signal_name[w],
1377                                   "b",
1378                                   active);
1379 }
1380
1381 int bus_manager_shutdown_or_sleep_now_or_later(
1382                 Manager *m,
1383                 const char *unit_name,
1384                 InhibitWhat w,
1385                 sd_bus_error *error) {
1386
1387         bool delayed;
1388         int r;
1389
1390         assert(m);
1391         assert(unit_name);
1392         assert(w >= 0);
1393         assert(w <= _INHIBIT_WHAT_MAX);
1394         assert(!m->action_job);
1395
1396         /* Tell everybody to prepare for shutdown/sleep */
1397         send_prepare_for(m, w, true);
1398
1399         delayed =
1400                 m->inhibit_delay_max > 0 &&
1401                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0);
1402
1403         if (delayed)
1404                 /* Shutdown is delayed, keep in mind what we
1405                  * want to do, and start a timeout */
1406                 r = delay_shutdown_or_sleep(m, w, unit_name);
1407         else
1408                 /* Shutdown is not delayed, execute it
1409                  * immediately */
1410                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1411
1412         return r;
1413 }
1414
1415 static int method_do_shutdown_or_sleep(
1416                 Manager *m,
1417                 sd_bus_message *message,
1418                 const char *unit_name,
1419                 InhibitWhat w,
1420                 const char *action,
1421                 const char *action_multiple_sessions,
1422                 const char *action_ignore_inhibit,
1423                 const char *sleep_verb,
1424                 sd_bus_message_handler_t method,
1425                 sd_bus_error *error) {
1426
1427         bool multiple_sessions, blocked;
1428         int interactive, r;
1429         uid_t uid;
1430
1431         assert(m);
1432         assert(message);
1433         assert(unit_name);
1434         assert(w >= 0);
1435         assert(w <= _INHIBIT_WHAT_MAX);
1436         assert(action);
1437         assert(action_multiple_sessions);
1438         assert(action_ignore_inhibit);
1439         assert(method);
1440
1441         r = sd_bus_message_read(message, "b", &interactive);
1442         if (r < 0)
1443                 return r;
1444
1445         /* Don't allow multiple jobs being executed at the same time */
1446         if (m->action_what)
1447                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1448
1449         if (sleep_verb) {
1450                 r = can_sleep(sleep_verb);
1451                 if (r < 0)
1452                         return r;
1453
1454                 if (r == 0)
1455                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1456         }
1457
1458         r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1459         if (r < 0)
1460                 return r;
1461
1462         r = have_multiple_sessions(m, uid);
1463         if (r < 0)
1464                 return r;
1465
1466         multiple_sessions = r > 0;
1467         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1468
1469         if (multiple_sessions) {
1470                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1471                                             action_multiple_sessions, interactive, error, method, m);
1472                 if (r < 0)
1473                         return r;
1474         }
1475
1476         if (blocked) {
1477                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1478                                             action_ignore_inhibit, interactive, error, method, m);
1479                 if (r < 0)
1480                         return r;
1481         }
1482
1483         if (!multiple_sessions && !blocked) {
1484                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1485                                             action, interactive, error, method, m);
1486                 if (r < 0)
1487                         return r;
1488         }
1489
1490         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1491         if (r < 0)
1492                 return r;
1493
1494         return sd_bus_reply_method_return(message, NULL);
1495 }
1496
1497 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1498         Manager *m = userdata;
1499
1500         return method_do_shutdown_or_sleep(
1501                         m, message,
1502                         SPECIAL_POWEROFF_TARGET,
1503                         INHIBIT_SHUTDOWN,
1504                         "org.freedesktop.login1.power-off",
1505                         "org.freedesktop.login1.power-off-multiple-sessions",
1506                         "org.freedesktop.login1.power-off-ignore-inhibit",
1507                         NULL,
1508                         method_poweroff,
1509                         error);
1510 }
1511
1512 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1513         Manager *m = userdata;
1514
1515         return method_do_shutdown_or_sleep(
1516                         m, message,
1517                         SPECIAL_REBOOT_TARGET,
1518                         INHIBIT_SHUTDOWN,
1519                         "org.freedesktop.login1.reboot",
1520                         "org.freedesktop.login1.reboot-multiple-sessions",
1521                         "org.freedesktop.login1.reboot-ignore-inhibit",
1522                         NULL,
1523                         method_reboot,
1524                         error);
1525 }
1526
1527 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1528         Manager *m = userdata;
1529
1530         return method_do_shutdown_or_sleep(
1531                         m, message,
1532                         SPECIAL_SUSPEND_TARGET,
1533                         INHIBIT_SLEEP,
1534                         "org.freedesktop.login1.suspend",
1535                         "org.freedesktop.login1.suspend-multiple-sessions",
1536                         "org.freedesktop.login1.suspend-ignore-inhibit",
1537                         "suspend",
1538                         method_suspend,
1539                         error);
1540 }
1541
1542 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1543         Manager *m = userdata;
1544
1545         return method_do_shutdown_or_sleep(
1546                         m, message,
1547                         SPECIAL_HIBERNATE_TARGET,
1548                         INHIBIT_SLEEP,
1549                         "org.freedesktop.login1.hibernate",
1550                         "org.freedesktop.login1.hibernate-multiple-sessions",
1551                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1552                         "hibernate",
1553                         method_hibernate,
1554                         error);
1555 }
1556
1557 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1558         Manager *m = userdata;
1559
1560         return method_do_shutdown_or_sleep(
1561                         m, message,
1562                         SPECIAL_HYBRID_SLEEP_TARGET,
1563                         INHIBIT_SLEEP,
1564                         "org.freedesktop.login1.hibernate",
1565                         "org.freedesktop.login1.hibernate-multiple-sessions",
1566                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1567                         "hybrid-sleep",
1568                         method_hybrid_sleep,
1569                         error);
1570 }
1571
1572 static int method_can_shutdown_or_sleep(
1573                 Manager *m,
1574                 sd_bus_message *message,
1575                 InhibitWhat w,
1576                 const char *action,
1577                 const char *action_multiple_sessions,
1578                 const char *action_ignore_inhibit,
1579                 const char *sleep_verb,
1580                 sd_bus_error *error) {
1581
1582         bool multiple_sessions, challenge, blocked;
1583         const char *result = NULL;
1584         uid_t uid;
1585         int r;
1586
1587         assert(m);
1588         assert(message);
1589         assert(w >= 0);
1590         assert(w <= _INHIBIT_WHAT_MAX);
1591         assert(action);
1592         assert(action_multiple_sessions);
1593         assert(action_ignore_inhibit);
1594
1595         if (sleep_verb) {
1596                 r = can_sleep(sleep_verb);
1597                 if (r < 0)
1598                         return r;
1599                 if (r == 0)
1600                         return sd_bus_reply_method_return(message, "s", "na");
1601         }
1602
1603         r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1604         if (r < 0)
1605                 return r;
1606
1607         r = have_multiple_sessions(m, uid);
1608         if (r < 0)
1609                 return r;
1610
1611         multiple_sessions = r > 0;
1612         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
1613
1614         if (multiple_sessions) {
1615                 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1616                 if (r < 0)
1617                         return r;
1618
1619                 if (r > 0)
1620                         result = "yes";
1621                 else if (challenge)
1622                         result = "challenge";
1623                 else
1624                         result = "no";
1625         }
1626
1627         if (blocked) {
1628                 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1629                 if (r < 0)
1630                         return r;
1631
1632                 if (r > 0 && !result)
1633                         result = "yes";
1634                 else if (challenge && (!result || streq(result, "yes")))
1635                         result = "challenge";
1636                 else
1637                         result = "no";
1638         }
1639
1640         if (!multiple_sessions && !blocked) {
1641                 /* If neither inhibit nor multiple sessions
1642                  * apply then just check the normal policy */
1643
1644                 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1645                 if (r < 0)
1646                         return r;
1647
1648                 if (r > 0)
1649                         result = "yes";
1650                 else if (challenge)
1651                         result = "challenge";
1652                 else
1653                         result = "no";
1654         }
1655
1656         return sd_bus_reply_method_return(message, "s", result);
1657 }
1658
1659 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1660         Manager *m = userdata;
1661
1662         return method_can_shutdown_or_sleep(
1663                         m, message,
1664                         INHIBIT_SHUTDOWN,
1665                         "org.freedesktop.login1.power-off",
1666                         "org.freedesktop.login1.power-off-multiple-sessions",
1667                         "org.freedesktop.login1.power-off-ignore-inhibit",
1668                         NULL,
1669                         error);
1670 }
1671
1672 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1673         Manager *m = userdata;
1674
1675         return method_can_shutdown_or_sleep(
1676                         m, message,
1677                         INHIBIT_SHUTDOWN,
1678                         "org.freedesktop.login1.reboot",
1679                         "org.freedesktop.login1.reboot-multiple-sessions",
1680                         "org.freedesktop.login1.reboot-ignore-inhibit",
1681                         NULL,
1682                         error);
1683 }
1684
1685 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1686         Manager *m = userdata;
1687
1688         return method_can_shutdown_or_sleep(
1689                         m, message,
1690                         INHIBIT_SLEEP,
1691                         "org.freedesktop.login1.suspend",
1692                         "org.freedesktop.login1.suspend-multiple-sessions",
1693                         "org.freedesktop.login1.suspend-ignore-inhibit",
1694                         "suspend",
1695                         error);
1696 }
1697
1698 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1699         Manager *m = userdata;
1700
1701         return method_can_shutdown_or_sleep(
1702                         m, message,
1703                         INHIBIT_SLEEP,
1704                         "org.freedesktop.login1.hibernate",
1705                         "org.freedesktop.login1.hibernate-multiple-sessions",
1706                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1707                         "hibernate",
1708                         error);
1709 }
1710
1711 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1712         Manager *m = userdata;
1713
1714         return method_can_shutdown_or_sleep(
1715                         m, message,
1716                         INHIBIT_SLEEP,
1717                         "org.freedesktop.login1.hibernate",
1718                         "org.freedesktop.login1.hibernate-multiple-sessions",
1719                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1720                         "hybrid-sleep",
1721                         error);
1722 }
1723
1724 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1725         const char *who, *why, *what, *mode;
1726         _cleanup_free_ char *id = NULL;
1727         _cleanup_close_ int fifo_fd = -1;
1728         Manager *m = userdata;
1729         Inhibitor *i = NULL;
1730         InhibitMode mm;
1731         InhibitWhat w;
1732         pid_t pid;
1733         uid_t uid;
1734         int r;
1735
1736         assert(bus);
1737         assert(message);
1738         assert(m);
1739
1740         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1741         if (r < 0)
1742                 return r;
1743
1744         w = inhibit_what_from_string(what);
1745         if (w <= 0)
1746                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1747
1748         mm = inhibit_mode_from_string(mode);
1749         if (mm < 0)
1750                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1751
1752         /* Delay is only supported for shutdown/sleep */
1753         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1754                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1755
1756         /* Don't allow taking delay locks while we are already
1757          * executing the operation. We shouldn't create the impression
1758          * that the lock was successful if the machine is about to go
1759          * down/suspend any moment. */
1760         if (m->action_what & w)
1761                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1762
1763         r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1764                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1765                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
1766                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
1767                                     w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
1768                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1769                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1770                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
1771                                     false, error, method_inhibit, m);
1772         if (r < 0)
1773                 return r;
1774         if (r == 0)
1775                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1776
1777         r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
1778         if (r < 0)
1779                 return r;
1780
1781         r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
1782         if (r < 0)
1783                 return r;
1784
1785         do {
1786                 free(id);
1787                 id = NULL;
1788
1789                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1790                         return -ENOMEM;
1791
1792         } while (hashmap_get(m->inhibitors, id));
1793
1794         r = manager_add_inhibitor(m, id, &i);
1795         if (r < 0)
1796                 return r;
1797
1798         i->what = w;
1799         i->mode = mm;
1800         i->pid = pid;
1801         i->uid = uid;
1802         i->why = strdup(why);
1803         i->who = strdup(who);
1804
1805         if (!i->why || !i->who) {
1806                 r = -ENOMEM;
1807                 goto fail;
1808         }
1809
1810         fifo_fd = inhibitor_create_fifo(i);
1811         if (fifo_fd < 0) {
1812                 r = fifo_fd;
1813                 goto fail;
1814         }
1815
1816         inhibitor_start(i);
1817
1818         return sd_bus_reply_method_return(message, "h", fifo_fd);
1819
1820 fail:
1821         if (i)
1822                 inhibitor_free(i);
1823
1824         return r;
1825 }
1826
1827 const sd_bus_vtable manager_vtable[] = {
1828         SD_BUS_VTABLE_START(0),
1829
1830         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), 0),
1831         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), 0),
1832         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), 0),
1833         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), 0),
1834         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1835         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1836         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1837         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1838         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1839         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), 0),
1840         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), 0),
1841         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), 0),
1842         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), 0),
1843         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), 0),
1844         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), 0),
1845         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), 0),
1846         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1847         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1848
1849         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
1850         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
1851         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
1852         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
1853         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
1854         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
1855         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
1856         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
1857         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
1858         SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshsub", method_create_session, 0),
1859         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1860         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
1861         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
1862         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1863         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1864         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1865         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1866         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
1867         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
1868         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
1869         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
1870         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
1871         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
1872         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
1873         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
1874         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
1875         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
1876         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
1877         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
1878         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
1879         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
1880         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
1881         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
1882         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
1883         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
1884         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
1885
1886         SD_BUS_SIGNAL("SessionNew", "so", 0),
1887         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1888         SD_BUS_SIGNAL("UserNew", "uo", 0),
1889         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1890         SD_BUS_SIGNAL("SeatNew", "so", 0),
1891         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1892         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1893         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1894
1895         SD_BUS_VTABLE_END
1896 };
1897
1898 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1899         const char *path, *result, *unit;
1900         Manager *m = userdata;
1901         Session *session;
1902         uint32_t id;
1903         User *user;
1904         int r;
1905
1906         assert(bus);
1907         assert(message);
1908         assert(m);
1909
1910         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1911         if (r < 0) {
1912                 bus_log_parse_error(r);
1913                 return r;
1914         }
1915
1916         if (m->action_job && streq(m->action_job, path)) {
1917                 log_info("Operation finished.");
1918
1919                 /* Tell people that they now may take a lock again */
1920                 send_prepare_for(m, m->action_what, false);
1921
1922                 free(m->action_job);
1923                 m->action_job = NULL;
1924                 m->action_unit = NULL;
1925                 m->action_what = 0;
1926                 return 0;
1927         }
1928
1929         session = hashmap_get(m->session_units, unit);
1930         if (session) {
1931
1932                 if (streq_ptr(path, session->scope_job)) {
1933                         free(session->scope_job);
1934                         session->scope_job = NULL;
1935                 }
1936
1937                 if (session->started) {
1938                         if (streq(result, "done"))
1939                                 session_send_create_reply(session, NULL);
1940                         else {
1941                                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1942
1943                                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1944                                 session_send_create_reply(session, &e);
1945                         }
1946                 } else
1947                         session_save(session);
1948
1949                 session_add_to_gc_queue(session);
1950         }
1951
1952         user = hashmap_get(m->user_units, unit);
1953         if (user) {
1954
1955                 if (streq_ptr(path, user->service_job)) {
1956                         free(user->service_job);
1957                         user->service_job = NULL;
1958                 }
1959
1960                 if (streq_ptr(path, user->slice_job)) {
1961                         free(user->slice_job);
1962                         user->slice_job = NULL;
1963                 }
1964
1965                 user_save(user);
1966                 user_add_to_gc_queue(user);
1967         }
1968
1969         return 0;
1970 }
1971
1972 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1973         const char *path, *unit;
1974         Manager *m = userdata;
1975         Session *session;
1976         User *user;
1977         int r;
1978
1979         assert(bus);
1980         assert(message);
1981         assert(m);
1982
1983         r = sd_bus_message_read(message, "so", &unit, &path);
1984         if (r < 0) {
1985                 bus_log_parse_error(r);
1986                 return r;
1987         }
1988
1989         session = hashmap_get(m->session_units, unit);
1990         if (session)
1991                 session_add_to_gc_queue(session);
1992
1993         user = hashmap_get(m->user_units, unit);
1994         if (user)
1995                 user_add_to_gc_queue(user);
1996
1997         return 0;
1998 }
1999
2000 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2001         _cleanup_free_ char *unit = NULL;
2002         Manager *m = userdata;
2003         const char *path;
2004         Session *session;
2005         User *user;
2006         int r;
2007
2008         assert(bus);
2009         assert(message);
2010         assert(m);
2011
2012         path = sd_bus_message_get_path(message);
2013         if (!path)
2014                 return 0;
2015
2016         r = unit_name_from_dbus_path(path, &unit);
2017         if (r < 0)
2018                 return r;
2019
2020         session = hashmap_get(m->session_units, unit);
2021         if (session)
2022                 session_add_to_gc_queue(session);
2023
2024         user = hashmap_get(m->user_units, unit);
2025         if (user)
2026                 user_add_to_gc_queue(user);
2027
2028         return 0;
2029 }
2030
2031 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2032         Manager *m = userdata;
2033         Session *session;
2034         Iterator i;
2035         int b, r;
2036
2037         assert(bus);
2038
2039         r = sd_bus_message_read(message, "b", &b);
2040         if (r < 0) {
2041                 bus_log_parse_error(r);
2042                 return r;
2043         }
2044
2045         if (b)
2046                 return 0;
2047
2048         /* systemd finished reloading, let's recheck all our sessions */
2049         log_debug("System manager has been reloaded, rechecking sessions...");
2050
2051         HASHMAP_FOREACH(session, m->sessions, i)
2052                 session_add_to_gc_queue(session);
2053
2054         return 0;
2055 }
2056
2057 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2058         const char *name, *old, *new;
2059         Manager *m = userdata;
2060         Session *session;
2061         Iterator i;
2062         int r;
2063
2064
2065         char *key;
2066
2067         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2068         if (r < 0) {
2069                 bus_log_parse_error(r);
2070                 return r;
2071         }
2072
2073         if (isempty(old) || !isempty(new))
2074                 return 0;
2075
2076         key = set_remove(m->busnames, (char*) old);
2077         if (!key)
2078                 return 0;
2079
2080         /* Drop all controllers owned by this name */
2081
2082         free(key);
2083
2084         HASHMAP_FOREACH(session, m->sessions, i)
2085                 if (session_is_controller(session, old))
2086                         session_drop_controller(session);
2087
2088         return 0;
2089 }
2090
2091 int manager_send_changed(Manager *manager, const char *property, ...) {
2092         char **l;
2093
2094         assert(manager);
2095
2096         l = strv_from_stdarg_alloca(property);
2097
2098         return sd_bus_emit_properties_changed_strv(
2099                         manager->bus,
2100                         "/org/freedesktop/login1",
2101                         "org.freedesktop.login1.Manager",
2102                         l);
2103 }
2104
2105 int manager_dispatch_delayed(Manager *manager) {
2106         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2107         int r;
2108
2109         assert(manager);
2110
2111         if (manager->action_what == 0 || manager->action_job)
2112                 return 0;
2113
2114         /* Continue delay? */
2115         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0)) {
2116
2117                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2118                         return 0;
2119
2120                 log_info("Delay lock is active but inhibitor timeout is reached.");
2121         }
2122
2123         /* Actually do the operation */
2124         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2125         if (r < 0) {
2126                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2127
2128                 manager->action_unit = NULL;
2129                 manager->action_what = 0;
2130                 return r;
2131         }
2132
2133         return 1;
2134 }
2135
2136 int manager_start_scope(
2137                 Manager *manager,
2138                 const char *scope,
2139                 pid_t pid,
2140                 const char *slice,
2141                 const char *description,
2142                 const char *after,
2143                 const char *kill_mode,
2144                 sd_bus_error *error,
2145                 char **job) {
2146
2147         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2148         int r;
2149
2150         assert(manager);
2151         assert(scope);
2152         assert(pid > 1);
2153
2154         r = sd_bus_message_new_method_call(
2155                         manager->bus,
2156                         "org.freedesktop.systemd1",
2157                         "/org/freedesktop/systemd1",
2158                         "org.freedesktop.systemd1.Manager",
2159                         "StartTransientUnit",
2160                         &m);
2161         if (r < 0)
2162                 return r;
2163
2164         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2165         if (r < 0)
2166                 return r;
2167
2168         r = sd_bus_message_open_container(m, 'a', "(sv)");
2169         if (r < 0)
2170                 return r;
2171
2172         if (!isempty(slice)) {
2173                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2174                 if (r < 0)
2175                         return r;
2176         }
2177
2178         if (!isempty(description)) {
2179                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2180                 if (r < 0)
2181                         return r;
2182         }
2183
2184         if (!isempty(description)) {
2185                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2186                 if (r < 0)
2187                         return r;
2188         }
2189
2190         if (!isempty(kill_mode)) {
2191                 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2192                 if (r < 0)
2193                         return r;
2194         }
2195
2196         /* cgroup empty notification is not available in containers
2197          * currently. To make this less problematic, let's shorten the
2198          * stop timeout for sessions, so that we don't wait
2199          * forever. */
2200
2201         r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2202         if (r < 0)
2203                 return r;
2204
2205         /* Make sure that the session shells are terminated with
2206          * SIGHUP since bash and friends tend to ignore SIGTERM */
2207         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2208         if (r < 0)
2209                 return r;
2210
2211         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2212         if (r < 0)
2213                 return r;
2214
2215         r = sd_bus_message_close_container(m);
2216         if (r < 0)
2217                 return r;
2218
2219         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2220         if (r < 0)
2221                 return r;
2222
2223         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2224         if (r < 0)
2225                 return r;
2226
2227         if (job) {
2228                 const char *j;
2229                 char *copy;
2230
2231                 r = sd_bus_message_read(reply, "o", &j);
2232                 if (r < 0)
2233                         return r;
2234
2235                 copy = strdup(j);
2236                 if (!copy)
2237                         return -ENOMEM;
2238
2239                 *job = copy;
2240         }
2241
2242         return 1;
2243 }
2244
2245 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2246         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2247         int r;
2248
2249         assert(manager);
2250         assert(unit);
2251
2252         r = sd_bus_call_method(
2253                         manager->bus,
2254                         "org.freedesktop.systemd1",
2255                         "/org/freedesktop/systemd1",
2256                         "org.freedesktop.systemd1.Manager",
2257                         "StartUnit",
2258                         error,
2259                         &reply,
2260                         "ss", unit, "fail");
2261         if (r < 0)
2262                 return r;
2263
2264         if (job) {
2265                 const char *j;
2266                 char *copy;
2267
2268                 r = sd_bus_message_read(reply, "o", &j);
2269                 if (r < 0)
2270                         return r;
2271
2272                 copy = strdup(j);
2273                 if (!copy)
2274                         return -ENOMEM;
2275
2276                 *job = copy;
2277         }
2278
2279         return 1;
2280 }
2281
2282 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2283         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2284         int r;
2285
2286         assert(manager);
2287         assert(unit);
2288
2289         r = sd_bus_call_method(
2290                         manager->bus,
2291                         "org.freedesktop.systemd1",
2292                         "/org/freedesktop/systemd1",
2293                         "org.freedesktop.systemd1.Manager",
2294                         "StopUnit",
2295                         error,
2296                         &reply,
2297                         "ss", unit, "fail");
2298         if (r < 0) {
2299                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2300                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2301
2302                         if (job)
2303                                 *job = NULL;
2304
2305                         sd_bus_error_free(error);
2306                         return 0;
2307                 }
2308
2309                 return r;
2310         }
2311
2312         if (job) {
2313                 const char *j;
2314                 char *copy;
2315
2316                 r = sd_bus_message_read(reply, "o", &j);
2317                 if (r < 0)
2318                         return r;
2319
2320                 copy = strdup(j);
2321                 if (!copy)
2322                         return -ENOMEM;
2323
2324                 *job = copy;
2325         }
2326
2327         return 1;
2328 }
2329
2330 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2331         assert(manager);
2332         assert(unit);
2333
2334         return sd_bus_call_method(
2335                         manager->bus,
2336                         "org.freedesktop.systemd1",
2337                         "/org/freedesktop/systemd1",
2338                         "org.freedesktop.systemd1.Manager",
2339                         "KillUnit",
2340                         error,
2341                         NULL,
2342                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2343 }
2344
2345 int manager_unit_is_active(Manager *manager, const char *unit) {
2346         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2347         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2348         _cleanup_free_ char *path = NULL;
2349         const char *state;
2350         int r;
2351
2352         assert(manager);
2353         assert(unit);
2354
2355         path = unit_dbus_path_from_name(unit);
2356         if (!path)
2357                 return -ENOMEM;
2358
2359         r = sd_bus_get_property(
2360                         manager->bus,
2361                         "org.freedesktop.systemd1",
2362                         path,
2363                         "org.freedesktop.systemd1.Unit",
2364                         "ActiveState",
2365                         &error,
2366                         &reply,
2367                         "s");
2368         if (r < 0) {
2369                 /* systemd might have droppped off momentarily, let's
2370                  * not make this an error */
2371                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2372                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2373                         return true;
2374
2375                 /* If the unit is already unloaded then it's not
2376                  * active */
2377                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2378                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2379                         return false;
2380
2381                 return r;
2382         }
2383
2384         r = sd_bus_message_read(reply, "s", &state);
2385         if (r < 0)
2386                 return -EINVAL;
2387
2388         return !streq(state, "inactive") && !streq(state, "failed");
2389 }
2390
2391 int manager_job_is_active(Manager *manager, const char *path) {
2392         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2393         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2394         int r;
2395
2396         assert(manager);
2397         assert(path);
2398
2399         r = sd_bus_get_property(
2400                         manager->bus,
2401                         "org.freedesktop.systemd1",
2402                         path,
2403                         "org.freedesktop.systemd1.Job",
2404                         "State",
2405                         &error,
2406                         &reply,
2407                         "s");
2408         if (r < 0) {
2409                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2410                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2411                         return true;
2412
2413                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2414                         return false;
2415
2416                 return r;
2417         }
2418
2419         /* We don't actually care about the state really. The fact
2420          * that we could read the job state is enough for us */
2421
2422         return true;
2423 }