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