chiark / gitweb /
logind: fix policykit checks
[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                 if (r == 0)
1484                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1485         }
1486
1487         if (blocked) {
1488                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1489                                             action_ignore_inhibit, interactive, error, method, m);
1490                 if (r < 0)
1491                         return r;
1492                 if (r == 0)
1493                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1494         }
1495
1496         if (!multiple_sessions && !blocked) {
1497                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1498                                             action, interactive, error, method, m);
1499                 if (r < 0)
1500                         return r;
1501                 if (r == 0)
1502                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1503         }
1504
1505         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1506         if (r < 0)
1507                 return r;
1508
1509         return sd_bus_reply_method_return(message, NULL);
1510 }
1511
1512 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1513         Manager *m = userdata;
1514
1515         return method_do_shutdown_or_sleep(
1516                         m, message,
1517                         SPECIAL_POWEROFF_TARGET,
1518                         INHIBIT_SHUTDOWN,
1519                         "org.freedesktop.login1.power-off",
1520                         "org.freedesktop.login1.power-off-multiple-sessions",
1521                         "org.freedesktop.login1.power-off-ignore-inhibit",
1522                         NULL,
1523                         method_poweroff,
1524                         error);
1525 }
1526
1527 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1528         Manager *m = userdata;
1529
1530         return method_do_shutdown_or_sleep(
1531                         m, message,
1532                         SPECIAL_REBOOT_TARGET,
1533                         INHIBIT_SHUTDOWN,
1534                         "org.freedesktop.login1.reboot",
1535                         "org.freedesktop.login1.reboot-multiple-sessions",
1536                         "org.freedesktop.login1.reboot-ignore-inhibit",
1537                         NULL,
1538                         method_reboot,
1539                         error);
1540 }
1541
1542 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1543         Manager *m = userdata;
1544
1545         return method_do_shutdown_or_sleep(
1546                         m, message,
1547                         SPECIAL_SUSPEND_TARGET,
1548                         INHIBIT_SLEEP,
1549                         "org.freedesktop.login1.suspend",
1550                         "org.freedesktop.login1.suspend-multiple-sessions",
1551                         "org.freedesktop.login1.suspend-ignore-inhibit",
1552                         "suspend",
1553                         method_suspend,
1554                         error);
1555 }
1556
1557 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1558         Manager *m = userdata;
1559
1560         return method_do_shutdown_or_sleep(
1561                         m, message,
1562                         SPECIAL_HIBERNATE_TARGET,
1563                         INHIBIT_SLEEP,
1564                         "org.freedesktop.login1.hibernate",
1565                         "org.freedesktop.login1.hibernate-multiple-sessions",
1566                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1567                         "hibernate",
1568                         method_hibernate,
1569                         error);
1570 }
1571
1572 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1573         Manager *m = userdata;
1574
1575         return method_do_shutdown_or_sleep(
1576                         m, message,
1577                         SPECIAL_HYBRID_SLEEP_TARGET,
1578                         INHIBIT_SLEEP,
1579                         "org.freedesktop.login1.hibernate",
1580                         "org.freedesktop.login1.hibernate-multiple-sessions",
1581                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1582                         "hybrid-sleep",
1583                         method_hybrid_sleep,
1584                         error);
1585 }
1586
1587 static int method_can_shutdown_or_sleep(
1588                 Manager *m,
1589                 sd_bus_message *message,
1590                 InhibitWhat w,
1591                 const char *action,
1592                 const char *action_multiple_sessions,
1593                 const char *action_ignore_inhibit,
1594                 const char *sleep_verb,
1595                 sd_bus_error *error) {
1596
1597         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1598         bool multiple_sessions, challenge, blocked;
1599         const char *result = NULL;
1600         uid_t uid;
1601         int r;
1602
1603         assert(m);
1604         assert(message);
1605         assert(w >= 0);
1606         assert(w <= _INHIBIT_WHAT_MAX);
1607         assert(action);
1608         assert(action_multiple_sessions);
1609         assert(action_ignore_inhibit);
1610
1611         if (sleep_verb) {
1612                 r = can_sleep(sleep_verb);
1613                 if (r < 0)
1614                         return r;
1615                 if (r == 0)
1616                         return sd_bus_reply_method_return(message, "s", "na");
1617         }
1618
1619         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1620         if (r < 0)
1621                 return r;
1622
1623         r = sd_bus_creds_get_uid(creds, &uid);
1624         if (r < 0)
1625                 return r;
1626
1627         r = have_multiple_sessions(m, uid);
1628         if (r < 0)
1629                 return r;
1630
1631         multiple_sessions = r > 0;
1632         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1633
1634         if (multiple_sessions) {
1635                 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1636                 if (r < 0)
1637                         return r;
1638
1639                 if (r > 0)
1640                         result = "yes";
1641                 else if (challenge)
1642                         result = "challenge";
1643                 else
1644                         result = "no";
1645         }
1646
1647         if (blocked) {
1648                 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1649                 if (r < 0)
1650                         return r;
1651
1652                 if (r > 0 && !result)
1653                         result = "yes";
1654                 else if (challenge && (!result || streq(result, "yes")))
1655                         result = "challenge";
1656                 else
1657                         result = "no";
1658         }
1659
1660         if (!multiple_sessions && !blocked) {
1661                 /* If neither inhibit nor multiple sessions
1662                  * apply then just check the normal policy */
1663
1664                 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1665                 if (r < 0)
1666                         return r;
1667
1668                 if (r > 0)
1669                         result = "yes";
1670                 else if (challenge)
1671                         result = "challenge";
1672                 else
1673                         result = "no";
1674         }
1675
1676         return sd_bus_reply_method_return(message, "s", result);
1677 }
1678
1679 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1680         Manager *m = userdata;
1681
1682         return method_can_shutdown_or_sleep(
1683                         m, message,
1684                         INHIBIT_SHUTDOWN,
1685                         "org.freedesktop.login1.power-off",
1686                         "org.freedesktop.login1.power-off-multiple-sessions",
1687                         "org.freedesktop.login1.power-off-ignore-inhibit",
1688                         NULL,
1689                         error);
1690 }
1691
1692 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1693         Manager *m = userdata;
1694
1695         return method_can_shutdown_or_sleep(
1696                         m, message,
1697                         INHIBIT_SHUTDOWN,
1698                         "org.freedesktop.login1.reboot",
1699                         "org.freedesktop.login1.reboot-multiple-sessions",
1700                         "org.freedesktop.login1.reboot-ignore-inhibit",
1701                         NULL,
1702                         error);
1703 }
1704
1705 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1706         Manager *m = userdata;
1707
1708         return method_can_shutdown_or_sleep(
1709                         m, message,
1710                         INHIBIT_SLEEP,
1711                         "org.freedesktop.login1.suspend",
1712                         "org.freedesktop.login1.suspend-multiple-sessions",
1713                         "org.freedesktop.login1.suspend-ignore-inhibit",
1714                         "suspend",
1715                         error);
1716 }
1717
1718 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1719         Manager *m = userdata;
1720
1721         return method_can_shutdown_or_sleep(
1722                         m, message,
1723                         INHIBIT_SLEEP,
1724                         "org.freedesktop.login1.hibernate",
1725                         "org.freedesktop.login1.hibernate-multiple-sessions",
1726                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1727                         "hibernate",
1728                         error);
1729 }
1730
1731 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1732         Manager *m = userdata;
1733
1734         return method_can_shutdown_or_sleep(
1735                         m, message,
1736                         INHIBIT_SLEEP,
1737                         "org.freedesktop.login1.hibernate",
1738                         "org.freedesktop.login1.hibernate-multiple-sessions",
1739                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1740                         "hybrid-sleep",
1741                         error);
1742 }
1743
1744 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1745         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1746         const char *who, *why, *what, *mode;
1747         _cleanup_free_ char *id = NULL;
1748         _cleanup_close_ int fifo_fd = -1;
1749         Manager *m = userdata;
1750         Inhibitor *i = NULL;
1751         InhibitMode mm;
1752         InhibitWhat w;
1753         pid_t pid;
1754         uid_t uid;
1755         int r;
1756
1757         assert(bus);
1758         assert(message);
1759         assert(m);
1760
1761         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1762         if (r < 0)
1763                 return r;
1764
1765         w = inhibit_what_from_string(what);
1766         if (w <= 0)
1767                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1768
1769         mm = inhibit_mode_from_string(mode);
1770         if (mm < 0)
1771                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1772
1773         /* Delay is only supported for shutdown/sleep */
1774         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1775                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1776
1777         /* Don't allow taking delay locks while we are already
1778          * executing the operation. We shouldn't create the impression
1779          * that the lock was successful if the machine is about to go
1780          * down/suspend any moment. */
1781         if (m->action_what & w)
1782                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1783
1784         r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1785                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1786                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
1787                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
1788                                     w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
1789                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1790                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1791                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
1792                                     false, error, method_inhibit, m);
1793         if (r < 0)
1794                 return r;
1795         if (r == 0)
1796                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1797
1798         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1799         if (r < 0)
1800                 return r;
1801
1802         r = sd_bus_creds_get_uid(creds, &uid);
1803         if (r < 0)
1804                 return r;
1805
1806         r = sd_bus_creds_get_pid(creds, &pid);
1807         if (r < 0)
1808                 return r;
1809
1810         do {
1811                 free(id);
1812                 id = NULL;
1813
1814                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1815                         return -ENOMEM;
1816
1817         } while (hashmap_get(m->inhibitors, id));
1818
1819         r = manager_add_inhibitor(m, id, &i);
1820         if (r < 0)
1821                 return r;
1822
1823         i->what = w;
1824         i->mode = mm;
1825         i->pid = pid;
1826         i->uid = uid;
1827         i->why = strdup(why);
1828         i->who = strdup(who);
1829
1830         if (!i->why || !i->who) {
1831                 r = -ENOMEM;
1832                 goto fail;
1833         }
1834
1835         fifo_fd = inhibitor_create_fifo(i);
1836         if (fifo_fd < 0) {
1837                 r = fifo_fd;
1838                 goto fail;
1839         }
1840
1841         inhibitor_start(i);
1842
1843         return sd_bus_reply_method_return(message, "h", fifo_fd);
1844
1845 fail:
1846         if (i)
1847                 inhibitor_free(i);
1848
1849         return r;
1850 }
1851
1852 const sd_bus_vtable manager_vtable[] = {
1853         SD_BUS_VTABLE_START(0),
1854
1855         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1856         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1857         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1858         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1859         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1860         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1861         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1862         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1863         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1864         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1865         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1866         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1867         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1868         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1869         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1870         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1871         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1872         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1873
1874         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1875         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1876         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1877         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1878         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1879         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1880         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1881         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1882         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1883         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1884         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1885         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1886         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1887         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1888         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1889         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1890         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1891         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1892         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1893         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1894         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1895         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1896         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1897         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1898         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1899         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1900         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1901         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1902         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1903         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1904         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1905         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1906         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1907         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1908         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1909         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1910
1911         SD_BUS_SIGNAL("SessionNew", "so", 0),
1912         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1913         SD_BUS_SIGNAL("UserNew", "uo", 0),
1914         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1915         SD_BUS_SIGNAL("SeatNew", "so", 0),
1916         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1917         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1918         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1919
1920         SD_BUS_VTABLE_END
1921 };
1922
1923 static int session_jobs_reply(Session *s, const char *unit, const char *result) {
1924         int r = 0;
1925
1926         assert(s);
1927         assert(unit);
1928
1929         if (!s->started)
1930                 return r;
1931
1932         if (streq(result, "done"))
1933                 r = session_send_create_reply(s, NULL);
1934         else {
1935                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1936
1937                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1938                 r = session_send_create_reply(s, &e);
1939         }
1940
1941         return r;
1942 }
1943
1944 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1945         const char *path, *result, *unit;
1946         Manager *m = userdata;
1947         Session *session;
1948         uint32_t id;
1949         User *user;
1950         int r;
1951
1952         assert(bus);
1953         assert(message);
1954         assert(m);
1955
1956         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1957         if (r < 0) {
1958                 bus_log_parse_error(r);
1959                 return r;
1960         }
1961
1962         if (m->action_job && streq(m->action_job, path)) {
1963                 log_info("Operation finished.");
1964
1965                 /* Tell people that they now may take a lock again */
1966                 send_prepare_for(m, m->action_what, false);
1967
1968                 free(m->action_job);
1969                 m->action_job = NULL;
1970                 m->action_unit = NULL;
1971                 m->action_what = 0;
1972                 return 0;
1973         }
1974
1975         session = hashmap_get(m->session_units, unit);
1976         if (session) {
1977
1978                 if (streq_ptr(path, session->scope_job)) {
1979                         free(session->scope_job);
1980                         session->scope_job = NULL;
1981                 }
1982
1983                 session_jobs_reply(session, unit, result);
1984
1985                 session_save(session);
1986                 session_add_to_gc_queue(session);
1987         }
1988
1989         user = hashmap_get(m->user_units, unit);
1990         if (user) {
1991
1992                 if (streq_ptr(path, user->service_job)) {
1993                         free(user->service_job);
1994                         user->service_job = NULL;
1995                 }
1996
1997                 if (streq_ptr(path, user->slice_job)) {
1998                         free(user->slice_job);
1999                         user->slice_job = NULL;
2000                 }
2001
2002                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
2003                         session_jobs_reply(session, unit, result);
2004                 }
2005
2006                 user_save(user);
2007                 user_add_to_gc_queue(user);
2008         }
2009
2010         return 0;
2011 }
2012
2013 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2014         const char *path, *unit;
2015         Manager *m = userdata;
2016         Session *session;
2017         User *user;
2018         int r;
2019
2020         assert(bus);
2021         assert(message);
2022         assert(m);
2023
2024         r = sd_bus_message_read(message, "so", &unit, &path);
2025         if (r < 0) {
2026                 bus_log_parse_error(r);
2027                 return r;
2028         }
2029
2030         session = hashmap_get(m->session_units, unit);
2031         if (session)
2032                 session_add_to_gc_queue(session);
2033
2034         user = hashmap_get(m->user_units, unit);
2035         if (user)
2036                 user_add_to_gc_queue(user);
2037
2038         return 0;
2039 }
2040
2041 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2042         _cleanup_free_ char *unit = NULL;
2043         Manager *m = userdata;
2044         const char *path;
2045         Session *session;
2046         User *user;
2047         int r;
2048
2049         assert(bus);
2050         assert(message);
2051         assert(m);
2052
2053         path = sd_bus_message_get_path(message);
2054         if (!path)
2055                 return 0;
2056
2057         r = unit_name_from_dbus_path(path, &unit);
2058         if (r < 0)
2059                 /* quietly ignore non-units paths */
2060                 return r == -EINVAL ? 0 : r;
2061
2062         session = hashmap_get(m->session_units, unit);
2063         if (session)
2064                 session_add_to_gc_queue(session);
2065
2066         user = hashmap_get(m->user_units, unit);
2067         if (user)
2068                 user_add_to_gc_queue(user);
2069
2070         return 0;
2071 }
2072
2073 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2074         Manager *m = userdata;
2075         Session *session;
2076         Iterator i;
2077         int b, r;
2078
2079         assert(bus);
2080
2081         r = sd_bus_message_read(message, "b", &b);
2082         if (r < 0) {
2083                 bus_log_parse_error(r);
2084                 return r;
2085         }
2086
2087         if (b)
2088                 return 0;
2089
2090         /* systemd finished reloading, let's recheck all our sessions */
2091         log_debug("System manager has been reloaded, rechecking sessions...");
2092
2093         HASHMAP_FOREACH(session, m->sessions, i)
2094                 session_add_to_gc_queue(session);
2095
2096         return 0;
2097 }
2098
2099 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2100         const char *name, *old, *new;
2101         Manager *m = userdata;
2102         Session *session;
2103         Iterator i;
2104         int r;
2105
2106
2107         char *key;
2108
2109         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2110         if (r < 0) {
2111                 bus_log_parse_error(r);
2112                 return r;
2113         }
2114
2115         if (isempty(old) || !isempty(new))
2116                 return 0;
2117
2118         key = set_remove(m->busnames, (char*) old);
2119         if (!key)
2120                 return 0;
2121
2122         /* Drop all controllers owned by this name */
2123
2124         free(key);
2125
2126         HASHMAP_FOREACH(session, m->sessions, i)
2127                 if (session_is_controller(session, old))
2128                         session_drop_controller(session);
2129
2130         return 0;
2131 }
2132
2133 int manager_send_changed(Manager *manager, const char *property, ...) {
2134         char **l;
2135
2136         assert(manager);
2137
2138         l = strv_from_stdarg_alloca(property);
2139
2140         return sd_bus_emit_properties_changed_strv(
2141                         manager->bus,
2142                         "/org/freedesktop/login1",
2143                         "org.freedesktop.login1.Manager",
2144                         l);
2145 }
2146
2147 int manager_dispatch_delayed(Manager *manager) {
2148         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2149         Inhibitor *offending = NULL;
2150         int r;
2151
2152         assert(manager);
2153
2154         if (manager->action_what == 0 || manager->action_job)
2155                 return 0;
2156
2157         /* Continue delay? */
2158         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2159                 _cleanup_free_ char *comm = NULL, *u = NULL;
2160
2161                 get_process_comm(offending->pid, &comm);
2162                 u = uid_to_name(offending->uid);
2163
2164                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2165                         return 0;
2166
2167                 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2168                          (unsigned long) offending->uid, strna(u),
2169                          (unsigned long) offending->pid, strna(comm));
2170         }
2171
2172         /* Actually do the operation */
2173         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2174         if (r < 0) {
2175                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2176
2177                 manager->action_unit = NULL;
2178                 manager->action_what = 0;
2179                 return r;
2180         }
2181
2182         return 1;
2183 }
2184
2185 int manager_start_scope(
2186                 Manager *manager,
2187                 const char *scope,
2188                 pid_t pid,
2189                 const char *slice,
2190                 const char *description,
2191                 const char *after, const char *after2,
2192                 sd_bus_error *error,
2193                 char **job) {
2194
2195         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2196         int r;
2197
2198         assert(manager);
2199         assert(scope);
2200         assert(pid > 1);
2201
2202         r = sd_bus_message_new_method_call(
2203                         manager->bus,
2204                         &m,
2205                         "org.freedesktop.systemd1",
2206                         "/org/freedesktop/systemd1",
2207                         "org.freedesktop.systemd1.Manager",
2208                         "StartTransientUnit");
2209         if (r < 0)
2210                 return r;
2211
2212         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2213         if (r < 0)
2214                 return r;
2215
2216         r = sd_bus_message_open_container(m, 'a', "(sv)");
2217         if (r < 0)
2218                 return r;
2219
2220         if (!isempty(slice)) {
2221                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2222                 if (r < 0)
2223                         return r;
2224         }
2225
2226         if (!isempty(description)) {
2227                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2228                 if (r < 0)
2229                         return r;
2230         }
2231
2232         if (!isempty(after)) {
2233                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2234                 if (r < 0)
2235                         return r;
2236         }
2237
2238         if (!isempty(after2)) {
2239                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
2240                 if (r < 0)
2241                         return r;
2242         }
2243
2244         /* cgroup empty notification is not available in containers
2245          * currently. To make this less problematic, let's shorten the
2246          * stop timeout for sessions, so that we don't wait
2247          * forever. */
2248
2249         /* Make sure that the session shells are terminated with
2250          * SIGHUP since bash and friends tend to ignore SIGTERM */
2251         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2252         if (r < 0)
2253                 return r;
2254
2255         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2256         if (r < 0)
2257                 return r;
2258
2259         r = sd_bus_message_close_container(m);
2260         if (r < 0)
2261                 return r;
2262
2263         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2264         if (r < 0)
2265                 return r;
2266
2267         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2268         if (r < 0)
2269                 return r;
2270
2271         if (job) {
2272                 const char *j;
2273                 char *copy;
2274
2275                 r = sd_bus_message_read(reply, "o", &j);
2276                 if (r < 0)
2277                         return r;
2278
2279                 copy = strdup(j);
2280                 if (!copy)
2281                         return -ENOMEM;
2282
2283                 *job = copy;
2284         }
2285
2286         return 1;
2287 }
2288
2289 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2290         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2291         int r;
2292
2293         assert(manager);
2294         assert(unit);
2295
2296         r = sd_bus_call_method(
2297                         manager->bus,
2298                         "org.freedesktop.systemd1",
2299                         "/org/freedesktop/systemd1",
2300                         "org.freedesktop.systemd1.Manager",
2301                         "StartUnit",
2302                         error,
2303                         &reply,
2304                         "ss", unit, "fail");
2305         if (r < 0)
2306                 return r;
2307
2308         if (job) {
2309                 const char *j;
2310                 char *copy;
2311
2312                 r = sd_bus_message_read(reply, "o", &j);
2313                 if (r < 0)
2314                         return r;
2315
2316                 copy = strdup(j);
2317                 if (!copy)
2318                         return -ENOMEM;
2319
2320                 *job = copy;
2321         }
2322
2323         return 1;
2324 }
2325
2326 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2327         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2328         int r;
2329
2330         assert(manager);
2331         assert(unit);
2332
2333         r = sd_bus_call_method(
2334                         manager->bus,
2335                         "org.freedesktop.systemd1",
2336                         "/org/freedesktop/systemd1",
2337                         "org.freedesktop.systemd1.Manager",
2338                         "StopUnit",
2339                         error,
2340                         &reply,
2341                         "ss", unit, "fail");
2342         if (r < 0) {
2343                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2344                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2345
2346                         if (job)
2347                                 *job = NULL;
2348
2349                         sd_bus_error_free(error);
2350                         return 0;
2351                 }
2352
2353                 return r;
2354         }
2355
2356         if (job) {
2357                 const char *j;
2358                 char *copy;
2359
2360                 r = sd_bus_message_read(reply, "o", &j);
2361                 if (r < 0)
2362                         return r;
2363
2364                 copy = strdup(j);
2365                 if (!copy)
2366                         return -ENOMEM;
2367
2368                 *job = copy;
2369         }
2370
2371         return 1;
2372 }
2373
2374 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
2375         _cleanup_free_ char *path = NULL;
2376         int r;
2377
2378         assert(manager);
2379         assert(scope);
2380
2381         path = unit_dbus_path_from_name(scope);
2382         if (!path)
2383                 return -ENOMEM;
2384
2385         r = sd_bus_call_method(
2386                         manager->bus,
2387                         "org.freedesktop.systemd1",
2388                         path,
2389                         "org.freedesktop.systemd1.Scope",
2390                         "Abandon",
2391                         error,
2392                         NULL,
2393                         NULL);
2394         if (r < 0) {
2395                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2396                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
2397                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
2398                         sd_bus_error_free(error);
2399                         return 0;
2400                 }
2401
2402                 return r;
2403         }
2404
2405         return 1;
2406 }
2407
2408 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2409         assert(manager);
2410         assert(unit);
2411
2412         return sd_bus_call_method(
2413                         manager->bus,
2414                         "org.freedesktop.systemd1",
2415                         "/org/freedesktop/systemd1",
2416                         "org.freedesktop.systemd1.Manager",
2417                         "KillUnit",
2418                         error,
2419                         NULL,
2420                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2421 }
2422
2423 int manager_unit_is_active(Manager *manager, const char *unit) {
2424         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2425         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2426         _cleanup_free_ char *path = NULL;
2427         const char *state;
2428         int r;
2429
2430         assert(manager);
2431         assert(unit);
2432
2433         path = unit_dbus_path_from_name(unit);
2434         if (!path)
2435                 return -ENOMEM;
2436
2437         r = sd_bus_get_property(
2438                         manager->bus,
2439                         "org.freedesktop.systemd1",
2440                         path,
2441                         "org.freedesktop.systemd1.Unit",
2442                         "ActiveState",
2443                         &error,
2444                         &reply,
2445                         "s");
2446         if (r < 0) {
2447                 /* systemd might have droppped off momentarily, let's
2448                  * not make this an error */
2449                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2450                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2451                         return true;
2452
2453                 /* If the unit is already unloaded then it's not
2454                  * active */
2455                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2456                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2457                         return false;
2458
2459                 return r;
2460         }
2461
2462         r = sd_bus_message_read(reply, "s", &state);
2463         if (r < 0)
2464                 return -EINVAL;
2465
2466         return !streq(state, "inactive") && !streq(state, "failed");
2467 }
2468
2469 int manager_job_is_active(Manager *manager, const char *path) {
2470         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2471         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2472         int r;
2473
2474         assert(manager);
2475         assert(path);
2476
2477         r = sd_bus_get_property(
2478                         manager->bus,
2479                         "org.freedesktop.systemd1",
2480                         path,
2481                         "org.freedesktop.systemd1.Job",
2482                         "State",
2483                         &error,
2484                         &reply,
2485                         "s");
2486         if (r < 0) {
2487                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2488                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2489                         return true;
2490
2491                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2492                         return false;
2493
2494                 return r;
2495         }
2496
2497         /* We don't actually care about the state really. The fact
2498          * that we could read the job state is enough for us */
2499
2500         return true;
2501 }