chiark / gitweb /
374e5983702e480c47ef0f2fe2fa1f76cc78be80
[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 method_do_shutdown_or_sleep(
1594                 Manager *m,
1595                 sd_bus_message *message,
1596                 const char *unit_name,
1597                 InhibitWhat w,
1598                 const char *action,
1599                 const char *action_multiple_sessions,
1600                 const char *action_ignore_inhibit,
1601                 const char *sleep_verb,
1602                 sd_bus_message_handler_t method,
1603                 sd_bus_error *error) {
1604
1605         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1606         bool multiple_sessions, blocked;
1607         int interactive, r;
1608         uid_t uid;
1609
1610         assert(m);
1611         assert(message);
1612         assert(unit_name);
1613         assert(w >= 0);
1614         assert(w <= _INHIBIT_WHAT_MAX);
1615         assert(action);
1616         assert(action_multiple_sessions);
1617         assert(action_ignore_inhibit);
1618         assert(method);
1619
1620         r = sd_bus_message_read(message, "b", &interactive);
1621         if (r < 0)
1622                 return r;
1623
1624         /* Don't allow multiple jobs being executed at the same time */
1625         if (m->action_what)
1626                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1627
1628         if (sleep_verb) {
1629                 r = can_sleep(sleep_verb);
1630                 if (r < 0)
1631                         return r;
1632
1633                 if (r == 0)
1634                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1635         }
1636
1637         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1638         if (r < 0)
1639                 return r;
1640
1641         r = sd_bus_creds_get_euid(creds, &uid);
1642         if (r < 0)
1643                 return r;
1644
1645         r = have_multiple_sessions(m, uid);
1646         if (r < 0)
1647                 return r;
1648
1649         multiple_sessions = r > 0;
1650         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1651
1652         if (multiple_sessions) {
1653                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
1654                 if (r < 0)
1655                         return r;
1656                 if (r == 0)
1657                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1658         }
1659
1660         if (blocked) {
1661                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
1662                 if (r < 0)
1663                         return r;
1664                 if (r == 0)
1665                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1666         }
1667
1668         if (!multiple_sessions && !blocked) {
1669                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
1670                 if (r < 0)
1671                         return r;
1672                 if (r == 0)
1673                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1674         }
1675
1676         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1677         if (r < 0)
1678                 return r;
1679
1680         return sd_bus_reply_method_return(message, NULL);
1681 }
1682
1683 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1684         Manager *m = userdata;
1685
1686         return method_do_shutdown_or_sleep(
1687                         m, message,
1688                         SPECIAL_POWEROFF_TARGET,
1689                         INHIBIT_SHUTDOWN,
1690                         "org.freedesktop.login1.power-off",
1691                         "org.freedesktop.login1.power-off-multiple-sessions",
1692                         "org.freedesktop.login1.power-off-ignore-inhibit",
1693                         NULL,
1694                         method_poweroff,
1695                         error);
1696 }
1697
1698 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1699         Manager *m = userdata;
1700
1701         return method_do_shutdown_or_sleep(
1702                         m, message,
1703                         SPECIAL_REBOOT_TARGET,
1704                         INHIBIT_SHUTDOWN,
1705                         "org.freedesktop.login1.reboot",
1706                         "org.freedesktop.login1.reboot-multiple-sessions",
1707                         "org.freedesktop.login1.reboot-ignore-inhibit",
1708                         NULL,
1709                         method_reboot,
1710                         error);
1711 }
1712
1713 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1714         Manager *m = userdata;
1715
1716         return method_do_shutdown_or_sleep(
1717                         m, message,
1718                         SPECIAL_SUSPEND_TARGET,
1719                         INHIBIT_SLEEP,
1720                         "org.freedesktop.login1.suspend",
1721                         "org.freedesktop.login1.suspend-multiple-sessions",
1722                         "org.freedesktop.login1.suspend-ignore-inhibit",
1723                         "suspend",
1724                         method_suspend,
1725                         error);
1726 }
1727
1728 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1729         Manager *m = userdata;
1730
1731         return method_do_shutdown_or_sleep(
1732                         m, message,
1733                         SPECIAL_HIBERNATE_TARGET,
1734                         INHIBIT_SLEEP,
1735                         "org.freedesktop.login1.hibernate",
1736                         "org.freedesktop.login1.hibernate-multiple-sessions",
1737                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1738                         "hibernate",
1739                         method_hibernate,
1740                         error);
1741 }
1742
1743 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1744         Manager *m = userdata;
1745
1746         return method_do_shutdown_or_sleep(
1747                         m, message,
1748                         SPECIAL_HYBRID_SLEEP_TARGET,
1749                         INHIBIT_SLEEP,
1750                         "org.freedesktop.login1.hibernate",
1751                         "org.freedesktop.login1.hibernate-multiple-sessions",
1752                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1753                         "hybrid-sleep",
1754                         method_hybrid_sleep,
1755                         error);
1756 }
1757
1758 static int method_can_shutdown_or_sleep(
1759                 Manager *m,
1760                 sd_bus_message *message,
1761                 InhibitWhat w,
1762                 const char *action,
1763                 const char *action_multiple_sessions,
1764                 const char *action_ignore_inhibit,
1765                 const char *sleep_verb,
1766                 sd_bus_error *error) {
1767
1768         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1769         bool multiple_sessions, challenge, blocked;
1770         const char *result = NULL;
1771         uid_t uid;
1772         int r;
1773
1774         assert(m);
1775         assert(message);
1776         assert(w >= 0);
1777         assert(w <= _INHIBIT_WHAT_MAX);
1778         assert(action);
1779         assert(action_multiple_sessions);
1780         assert(action_ignore_inhibit);
1781
1782         if (sleep_verb) {
1783                 r = can_sleep(sleep_verb);
1784                 if (r < 0)
1785                         return r;
1786                 if (r == 0)
1787                         return sd_bus_reply_method_return(message, "s", "na");
1788         }
1789
1790         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1791         if (r < 0)
1792                 return r;
1793
1794         r = sd_bus_creds_get_euid(creds, &uid);
1795         if (r < 0)
1796                 return r;
1797
1798         r = have_multiple_sessions(m, uid);
1799         if (r < 0)
1800                 return r;
1801
1802         multiple_sessions = r > 0;
1803         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1804
1805         if (multiple_sessions) {
1806                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
1807                 if (r < 0)
1808                         return r;
1809
1810                 if (r > 0)
1811                         result = "yes";
1812                 else if (challenge)
1813                         result = "challenge";
1814                 else
1815                         result = "no";
1816         }
1817
1818         if (blocked) {
1819                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
1820                 if (r < 0)
1821                         return r;
1822
1823                 if (r > 0 && !result)
1824                         result = "yes";
1825                 else if (challenge && (!result || streq(result, "yes")))
1826                         result = "challenge";
1827                 else
1828                         result = "no";
1829         }
1830
1831         if (!multiple_sessions && !blocked) {
1832                 /* If neither inhibit nor multiple sessions
1833                  * apply then just check the normal policy */
1834
1835                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
1836                 if (r < 0)
1837                         return r;
1838
1839                 if (r > 0)
1840                         result = "yes";
1841                 else if (challenge)
1842                         result = "challenge";
1843                 else
1844                         result = "no";
1845         }
1846
1847         return sd_bus_reply_method_return(message, "s", result);
1848 }
1849
1850 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1851         Manager *m = userdata;
1852
1853         return method_can_shutdown_or_sleep(
1854                         m, message,
1855                         INHIBIT_SHUTDOWN,
1856                         "org.freedesktop.login1.power-off",
1857                         "org.freedesktop.login1.power-off-multiple-sessions",
1858                         "org.freedesktop.login1.power-off-ignore-inhibit",
1859                         NULL,
1860                         error);
1861 }
1862
1863 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1864         Manager *m = userdata;
1865
1866         return method_can_shutdown_or_sleep(
1867                         m, message,
1868                         INHIBIT_SHUTDOWN,
1869                         "org.freedesktop.login1.reboot",
1870                         "org.freedesktop.login1.reboot-multiple-sessions",
1871                         "org.freedesktop.login1.reboot-ignore-inhibit",
1872                         NULL,
1873                         error);
1874 }
1875
1876 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1877         Manager *m = userdata;
1878
1879         return method_can_shutdown_or_sleep(
1880                         m, message,
1881                         INHIBIT_SLEEP,
1882                         "org.freedesktop.login1.suspend",
1883                         "org.freedesktop.login1.suspend-multiple-sessions",
1884                         "org.freedesktop.login1.suspend-ignore-inhibit",
1885                         "suspend",
1886                         error);
1887 }
1888
1889 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1890         Manager *m = userdata;
1891
1892         return method_can_shutdown_or_sleep(
1893                         m, message,
1894                         INHIBIT_SLEEP,
1895                         "org.freedesktop.login1.hibernate",
1896                         "org.freedesktop.login1.hibernate-multiple-sessions",
1897                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1898                         "hibernate",
1899                         error);
1900 }
1901
1902 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1903         Manager *m = userdata;
1904
1905         return method_can_shutdown_or_sleep(
1906                         m, message,
1907                         INHIBIT_SLEEP,
1908                         "org.freedesktop.login1.hibernate",
1909                         "org.freedesktop.login1.hibernate-multiple-sessions",
1910                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1911                         "hybrid-sleep",
1912                         error);
1913 }
1914
1915 static int property_get_reboot_to_firmware_setup(
1916                 sd_bus *bus,
1917                 const char *path,
1918                 const char *interface,
1919                 const char *property,
1920                 sd_bus_message *reply,
1921                 void *userdata,
1922                 sd_bus_error *error) {
1923         int r;
1924
1925         assert(bus);
1926         assert(reply);
1927         assert(userdata);
1928
1929         r = efi_get_reboot_to_firmware();
1930         if (r < 0 && r != -EOPNOTSUPP)
1931                 return r;
1932
1933         return sd_bus_message_append(reply, "b", r > 0);
1934 }
1935
1936 static int method_set_reboot_to_firmware_setup(
1937                 sd_bus *bus,
1938                 sd_bus_message *message,
1939                 void *userdata,
1940                 sd_bus_error *error) {
1941
1942         int b, r;
1943         Manager *m = userdata;
1944
1945         assert(bus);
1946         assert(message);
1947         assert(m);
1948
1949         r = sd_bus_message_read(message, "b", &b);
1950         if (r < 0)
1951                 return r;
1952
1953         r = bus_verify_polkit_async(message,
1954                                     CAP_SYS_ADMIN,
1955                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
1956                                     false,
1957                                     UID_INVALID,
1958                                     &m->polkit_registry,
1959                                     error);
1960         if (r < 0)
1961                 return r;
1962         if (r == 0)
1963                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1964
1965         r = efi_set_reboot_to_firmware(b);
1966         if (r < 0)
1967                 return r;
1968
1969         return sd_bus_reply_method_return(message, NULL);
1970 }
1971
1972 static int method_can_reboot_to_firmware_setup(
1973                 sd_bus *bus,
1974                 sd_bus_message *message,
1975                 void *userdata,
1976                 sd_bus_error *error) {
1977
1978         int r;
1979         bool challenge;
1980         const char *result;
1981         Manager *m = userdata;
1982
1983         assert(bus);
1984         assert(message);
1985         assert(m);
1986
1987         r = efi_reboot_to_firmware_supported();
1988         if (r == -EOPNOTSUPP)
1989                 return sd_bus_reply_method_return(message, "s", "na");
1990         else if (r < 0)
1991                 return r;
1992
1993         r = bus_test_polkit(message,
1994                             CAP_SYS_ADMIN,
1995                             "org.freedesktop.login1.set-reboot-to-firmware-setup",
1996                             UID_INVALID,
1997                             &challenge,
1998                             error);
1999         if (r < 0)
2000                 return r;
2001
2002         if (r > 0)
2003                 result = "yes";
2004         else if (challenge)
2005                 result = "challenge";
2006         else
2007                 result = "no";
2008
2009         return sd_bus_reply_method_return(message, "s", result);
2010 }
2011
2012 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2013         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
2014         const char *who, *why, *what, *mode;
2015         _cleanup_free_ char *id = NULL;
2016         _cleanup_close_ int fifo_fd = -1;
2017         Manager *m = userdata;
2018         Inhibitor *i = NULL;
2019         InhibitMode mm;
2020         InhibitWhat w;
2021         pid_t pid;
2022         uid_t uid;
2023         int r;
2024
2025         assert(bus);
2026         assert(message);
2027         assert(m);
2028
2029         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
2030         if (r < 0)
2031                 return r;
2032
2033         w = inhibit_what_from_string(what);
2034         if (w <= 0)
2035                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
2036
2037         mm = inhibit_mode_from_string(mode);
2038         if (mm < 0)
2039                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
2040
2041         /* Delay is only supported for shutdown/sleep */
2042         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
2043                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
2044
2045         /* Don't allow taking delay locks while we are already
2046          * executing the operation. We shouldn't create the impression
2047          * that the lock was successful if the machine is about to go
2048          * down/suspend any moment. */
2049         if (m->action_what & w)
2050                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
2051
2052         r = bus_verify_polkit_async(
2053                         message,
2054                         CAP_SYS_BOOT,
2055                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
2056                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
2057                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
2058                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
2059                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
2060                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
2061                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
2062                         false,
2063                         UID_INVALID,
2064                         &m->polkit_registry,
2065                         error);
2066         if (r < 0)
2067                 return r;
2068         if (r == 0)
2069                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2070
2071         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
2072         if (r < 0)
2073                 return r;
2074
2075         r = sd_bus_creds_get_euid(creds, &uid);
2076         if (r < 0)
2077                 return r;
2078
2079         r = sd_bus_creds_get_pid(creds, &pid);
2080         if (r < 0)
2081                 return r;
2082
2083         do {
2084                 free(id);
2085                 id = NULL;
2086
2087                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
2088                         return -ENOMEM;
2089
2090         } while (hashmap_get(m->inhibitors, id));
2091
2092         r = manager_add_inhibitor(m, id, &i);
2093         if (r < 0)
2094                 return r;
2095
2096         i->what = w;
2097         i->mode = mm;
2098         i->pid = pid;
2099         i->uid = uid;
2100         i->why = strdup(why);
2101         i->who = strdup(who);
2102
2103         if (!i->why || !i->who) {
2104                 r = -ENOMEM;
2105                 goto fail;
2106         }
2107
2108         fifo_fd = inhibitor_create_fifo(i);
2109         if (fifo_fd < 0) {
2110                 r = fifo_fd;
2111                 goto fail;
2112         }
2113
2114         inhibitor_start(i);
2115
2116         return sd_bus_reply_method_return(message, "h", fifo_fd);
2117
2118 fail:
2119         if (i)
2120                 inhibitor_free(i);
2121
2122         return r;
2123 }
2124
2125 const sd_bus_vtable manager_vtable[] = {
2126         SD_BUS_VTABLE_START(0),
2127
2128         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
2129         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
2130         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
2131         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
2132         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2133         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2134         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2135         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2136         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2137         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2138         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
2139         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
2140         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
2141         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
2142         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
2143         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
2144         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2145         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
2146         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2147         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
2148         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
2149
2150         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
2151         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2152         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
2153         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2154         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2155         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2156         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
2157         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
2158         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
2159         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
2160         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
2161         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2162         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2163         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2164         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
2165         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2166         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
2167         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
2168         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
2169         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
2170         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
2171         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
2172         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
2173         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
2174         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
2175         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2176         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2177         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2178         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2179         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2180         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
2181         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
2182         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
2183         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
2184         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
2185         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
2186         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2187         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
2188
2189         SD_BUS_SIGNAL("SessionNew", "so", 0),
2190         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
2191         SD_BUS_SIGNAL("UserNew", "uo", 0),
2192         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
2193         SD_BUS_SIGNAL("SeatNew", "so", 0),
2194         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
2195         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
2196         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
2197
2198         SD_BUS_VTABLE_END
2199 };
2200
2201 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
2202         int r = 0;
2203
2204         assert(s);
2205         assert(unit);
2206
2207         if (!s->started)
2208                 return r;
2209
2210         if (streq(result, "done"))
2211                 r = session_send_create_reply(s, NULL);
2212         else {
2213                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
2214
2215                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
2216                 r = session_send_create_reply(s, &e);
2217         }
2218
2219         return r;
2220 }
2221
2222 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2223         const char *path, *result, *unit;
2224         Manager *m = userdata;
2225         Session *session;
2226         uint32_t id;
2227         User *user;
2228         int r;
2229
2230         assert(bus);
2231         assert(message);
2232         assert(m);
2233
2234         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
2235         if (r < 0) {
2236                 bus_log_parse_error(r);
2237                 return r;
2238         }
2239
2240         if (m->action_job && streq(m->action_job, path)) {
2241                 log_info("Operation finished.");
2242
2243                 /* Tell people that they now may take a lock again */
2244                 send_prepare_for(m, m->action_what, false);
2245
2246                 free(m->action_job);
2247                 m->action_job = NULL;
2248                 m->action_unit = NULL;
2249                 m->action_what = 0;
2250                 return 0;
2251         }
2252
2253         session = hashmap_get(m->session_units, unit);
2254         if (session) {
2255
2256                 if (streq_ptr(path, session->scope_job)) {
2257                         free(session->scope_job);
2258                         session->scope_job = NULL;
2259                 }
2260
2261                 session_jobs_reply(session, unit, result);
2262
2263                 session_save(session);
2264                 session_add_to_gc_queue(session);
2265         }
2266
2267         user = hashmap_get(m->user_units, unit);
2268         if (user) {
2269
2270                 if (streq_ptr(path, user->service_job)) {
2271                         free(user->service_job);
2272                         user->service_job = NULL;
2273                 }
2274
2275                 if (streq_ptr(path, user->slice_job)) {
2276                         free(user->slice_job);
2277                         user->slice_job = NULL;
2278                 }
2279
2280                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2281                         session_jobs_reply(session, unit, result);
2282                 }
2283
2284                 user_save(user);
2285                 user_add_to_gc_queue(user);
2286         }
2287
2288         return 0;
2289 }
2290
2291 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2292         const char *path, *unit;
2293         Manager *m = userdata;
2294         Session *session;
2295         User *user;
2296         int r;
2297
2298         assert(bus);
2299         assert(message);
2300         assert(m);
2301
2302         r = sd_bus_message_read(message, "so", &unit, &path);
2303         if (r < 0) {
2304                 bus_log_parse_error(r);
2305                 return r;
2306         }
2307
2308         session = hashmap_get(m->session_units, unit);
2309         if (session)
2310                 session_add_to_gc_queue(session);
2311
2312         user = hashmap_get(m->user_units, unit);
2313         if (user)
2314                 user_add_to_gc_queue(user);
2315
2316         return 0;
2317 }
2318
2319 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2320         _cleanup_free_ char *unit = NULL;
2321         Manager *m = userdata;
2322         const char *path;
2323         Session *session;
2324         User *user;
2325         int r;
2326
2327         assert(bus);
2328         assert(message);
2329         assert(m);
2330
2331         path = sd_bus_message_get_path(message);
2332         if (!path)
2333                 return 0;
2334
2335         r = unit_name_from_dbus_path(path, &unit);
2336         if (r == -EINVAL) /* not a unit */
2337                 return 0;
2338         if (r < 0)
2339                 return r;
2340
2341         session = hashmap_get(m->session_units, unit);
2342         if (session)
2343                 session_add_to_gc_queue(session);
2344
2345         user = hashmap_get(m->user_units, unit);
2346         if (user)
2347                 user_add_to_gc_queue(user);
2348
2349         return 0;
2350 }
2351
2352 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2353         Manager *m = userdata;
2354         Session *session;
2355         Iterator i;
2356         int b, r;
2357
2358         assert(bus);
2359
2360         r = sd_bus_message_read(message, "b", &b);
2361         if (r < 0) {
2362                 bus_log_parse_error(r);
2363                 return r;
2364         }
2365
2366         if (b)
2367                 return 0;
2368
2369         /* systemd finished reloading, let's recheck all our sessions */
2370         log_debug("System manager has been reloaded, rechecking sessions...");
2371
2372         HASHMAP_FOREACH(session, m->sessions, i)
2373                 session_add_to_gc_queue(session);
2374
2375         return 0;
2376 }
2377
2378 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2379         const char *name, *old, *new;
2380         Manager *m = userdata;
2381         Session *session;
2382         Iterator i;
2383         int r;
2384
2385
2386         char *key;
2387
2388         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2389         if (r < 0) {
2390                 bus_log_parse_error(r);
2391                 return r;
2392         }
2393
2394         if (isempty(old) || !isempty(new))
2395                 return 0;
2396
2397         key = set_remove(m->busnames, (char*) old);
2398         if (!key)
2399                 return 0;
2400
2401         /* Drop all controllers owned by this name */
2402
2403         free(key);
2404
2405         HASHMAP_FOREACH(session, m->sessions, i)
2406                 if (session_is_controller(session, old))
2407                         session_drop_controller(session);
2408
2409         return 0;
2410 }
2411
2412 int manager_send_changed(Manager *manager, const char *property, ...) {
2413         char **l;
2414
2415         assert(manager);
2416
2417         l = strv_from_stdarg_alloca(property);
2418
2419         return sd_bus_emit_properties_changed_strv(
2420                         manager->bus,
2421                         "/org/freedesktop/login1",
2422                         "org.freedesktop.login1.Manager",
2423                         l);
2424 }
2425
2426 int manager_start_scope(
2427                 Manager *manager,
2428                 const char *scope,
2429                 pid_t pid,
2430                 const char *slice,
2431                 const char *description,
2432                 const char *after, const char *after2,
2433                 sd_bus_error *error,
2434                 char **job) {
2435
2436         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2437         int r;
2438
2439         assert(manager);
2440         assert(scope);
2441         assert(pid > 1);
2442
2443         r = sd_bus_message_new_method_call(
2444                         manager->bus,
2445                         &m,
2446                         "org.freedesktop.systemd1",
2447                         "/org/freedesktop/systemd1",
2448                         "org.freedesktop.systemd1.Manager",
2449                         "StartTransientUnit");
2450         if (r < 0)
2451                 return r;
2452
2453         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2454         if (r < 0)
2455                 return r;
2456
2457         r = sd_bus_message_open_container(m, 'a', "(sv)");
2458         if (r < 0)
2459                 return r;
2460
2461         if (!isempty(slice)) {
2462                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2463                 if (r < 0)
2464                         return r;
2465         }
2466
2467         if (!isempty(description)) {
2468                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2469                 if (r < 0)
2470                         return r;
2471         }
2472
2473         if (!isempty(after)) {
2474                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2475                 if (r < 0)
2476                         return r;
2477         }
2478
2479         if (!isempty(after2)) {
2480                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2481                 if (r < 0)
2482                         return r;
2483         }
2484
2485         /* cgroup empty notification is not available in containers
2486          * currently. To make this less problematic, let's shorten the
2487          * stop timeout for sessions, so that we don't wait
2488          * forever. */
2489
2490         /* Make sure that the session shells are terminated with
2491          * SIGHUP since bash and friends tend to ignore SIGTERM */
2492         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2493         if (r < 0)
2494                 return r;
2495
2496         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2497         if (r < 0)
2498                 return r;
2499
2500         r = sd_bus_message_close_container(m);
2501         if (r < 0)
2502                 return r;
2503
2504         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2505         if (r < 0)
2506                 return r;
2507
2508         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2509         if (r < 0)
2510                 return r;
2511
2512         if (job) {
2513                 const char *j;
2514                 char *copy;
2515
2516                 r = sd_bus_message_read(reply, "o", &j);
2517                 if (r < 0)
2518                         return r;
2519
2520                 copy = strdup(j);
2521                 if (!copy)
2522                         return -ENOMEM;
2523
2524                 *job = copy;
2525         }
2526
2527         return 1;
2528 }
2529
2530 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2531         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2532         int r;
2533
2534         assert(manager);
2535         assert(unit);
2536
2537         r = sd_bus_call_method(
2538                         manager->bus,
2539                         "org.freedesktop.systemd1",
2540                         "/org/freedesktop/systemd1",
2541                         "org.freedesktop.systemd1.Manager",
2542                         "StartUnit",
2543                         error,
2544                         &reply,
2545                         "ss", unit, "fail");
2546         if (r < 0)
2547                 return r;
2548
2549         if (job) {
2550                 const char *j;
2551                 char *copy;
2552
2553                 r = sd_bus_message_read(reply, "o", &j);
2554                 if (r < 0)
2555                         return r;
2556
2557                 copy = strdup(j);
2558                 if (!copy)
2559                         return -ENOMEM;
2560
2561                 *job = copy;
2562         }
2563
2564         return 1;
2565 }
2566
2567 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2568         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2569         int r;
2570
2571         assert(manager);
2572         assert(unit);
2573
2574         r = sd_bus_call_method(
2575                         manager->bus,
2576                         "org.freedesktop.systemd1",
2577                         "/org/freedesktop/systemd1",
2578                         "org.freedesktop.systemd1.Manager",
2579                         "StopUnit",
2580                         error,
2581                         &reply,
2582                         "ss", unit, "fail");
2583         if (r < 0) {
2584                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2585                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2586
2587                         if (job)
2588                                 *job = NULL;
2589
2590                         sd_bus_error_free(error);
2591                         return 0;
2592                 }
2593
2594                 return r;
2595         }
2596
2597         if (job) {
2598                 const char *j;
2599                 char *copy;
2600
2601                 r = sd_bus_message_read(reply, "o", &j);
2602                 if (r < 0)
2603                         return r;
2604
2605                 copy = strdup(j);
2606                 if (!copy)
2607                         return -ENOMEM;
2608
2609                 *job = copy;
2610         }
2611
2612         return 1;
2613 }
2614
2615 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2616         _cleanup_free_ char *path = NULL;
2617         int r;
2618
2619         assert(manager);
2620         assert(scope);
2621
2622         path = unit_dbus_path_from_name(scope);
2623         if (!path)
2624                 return -ENOMEM;
2625
2626         r = sd_bus_call_method(
2627                         manager->bus,
2628                         "org.freedesktop.systemd1",
2629                         path,
2630                         "org.freedesktop.systemd1.Scope",
2631                         "Abandon",
2632                         error,
2633                         NULL,
2634                         NULL);
2635         if (r < 0) {
2636                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2637                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2638                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2639                         sd_bus_error_free(error);
2640                         return 0;
2641                 }
2642
2643                 return r;
2644         }
2645
2646         return 1;
2647 }
2648
2649 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2650         assert(manager);
2651         assert(unit);
2652
2653         return sd_bus_call_method(
2654                         manager->bus,
2655                         "org.freedesktop.systemd1",
2656                         "/org/freedesktop/systemd1",
2657                         "org.freedesktop.systemd1.Manager",
2658                         "KillUnit",
2659                         error,
2660                         NULL,
2661                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2662 }
2663
2664 int manager_unit_is_active(Manager *manager, const char *unit) {
2665         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2666         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2667         _cleanup_free_ char *path = NULL;
2668         const char *state;
2669         int r;
2670
2671         assert(manager);
2672         assert(unit);
2673
2674         path = unit_dbus_path_from_name(unit);
2675         if (!path)
2676                 return -ENOMEM;
2677
2678         r = sd_bus_get_property(
2679                         manager->bus,
2680                         "org.freedesktop.systemd1",
2681                         path,
2682                         "org.freedesktop.systemd1.Unit",
2683                         "ActiveState",
2684                         &error,
2685                         &reply,
2686                         "s");
2687         if (r < 0) {
2688                 /* systemd might have droppped off momentarily, let's
2689                  * not make this an error */
2690                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2691                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2692                         return true;
2693
2694                 /* If the unit is already unloaded then it's not
2695                  * active */
2696                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2697                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2698                         return false;
2699
2700                 return r;
2701         }
2702
2703         r = sd_bus_message_read(reply, "s", &state);
2704         if (r < 0)
2705                 return -EINVAL;
2706
2707         return !streq(state, "inactive") && !streq(state, "failed");
2708 }
2709
2710 int manager_job_is_active(Manager *manager, const char *path) {
2711         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2712         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2713         int r;
2714
2715         assert(manager);
2716         assert(path);
2717
2718         r = sd_bus_get_property(
2719                         manager->bus,
2720                         "org.freedesktop.systemd1",
2721                         path,
2722                         "org.freedesktop.systemd1.Job",
2723                         "State",
2724                         &error,
2725                         &reply,
2726                         "s");
2727         if (r < 0) {
2728                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2729                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2730                         return true;
2731
2732                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2733                         return false;
2734
2735                 return r;
2736         }
2737
2738         /* We don't actually care about the state really. The fact
2739          * that we could read the job state is enough for us */
2740
2741         return true;
2742 }