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