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