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