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