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