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