chiark / gitweb /
47459617733da9f6295729173bc442c384e31f66
[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         /* We use the FIFO to detect stray sessions where the process
752            invoking PAM dies abnormally. We need to make sure that
753            that process is not killed if at the clean end of the
754            session it closes the FIFO. Hence, with this call
755            explicitly turn off the FIFO logic, so that the PAM code
756            can finish clean up on its own */
757         session_remove_fifo(session);
758         session_save(session);
759         user_save(session->user);
760
761         return sd_bus_reply_method_return(message, NULL);
762 }
763
764 static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
765         Manager *m = userdata;
766         Session *session;
767         const char *name;
768         int r;
769
770         assert(bus);
771         assert(message);
772         assert(m);
773
774         r = sd_bus_message_read(message, "s", &name);
775         if (r < 0)
776                 return r;
777
778         session = hashmap_get(m->sessions, name);
779         if (!session)
780                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
781
782         r = session_activate(session);
783         if (r < 0)
784                 return r;
785
786         return sd_bus_reply_method_return(message, NULL);
787 }
788
789 static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
790         const char *session_name, *seat_name;
791         Manager *m = userdata;
792         Session *session;
793         Seat *seat;
794         int r;
795
796         assert(bus);
797         assert(message);
798         assert(m);
799
800         /* Same as ActivateSession() but refuses to work if
801          * the seat doesn't match */
802
803         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
804         if (r < 0)
805                 return r;
806
807         session = hashmap_get(m->sessions, session_name);
808         if (!session)
809                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", session_name);
810
811         seat = hashmap_get(m->seats, seat_name);
812         if (!seat)
813                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", seat_name);
814
815         if (session->seat != seat)
816                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
817
818         r = session_activate(session);
819         if (r < 0)
820                 return r;
821
822         return sd_bus_reply_method_return(message, NULL);
823 }
824
825 static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
826         Manager *m = userdata;
827         Session *session;
828         const char *name;
829         int r;
830
831         assert(bus);
832         assert(message);
833         assert(m);
834
835         r = sd_bus_message_read(message, "s", &name);
836         if (r < 0)
837                 return r;
838
839         session = hashmap_get(m->sessions, name);
840         if (!session)
841                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
842
843         r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession"));
844         if (r < 0)
845                 return r;
846
847         return sd_bus_reply_method_return(message, NULL);
848 }
849
850 static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
851         Manager *m = userdata;
852         int r;
853
854         assert(bus);
855         assert(message);
856         assert(m);
857
858         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
859         if (r < 0)
860                 return r;
861
862         return sd_bus_reply_method_return(message, NULL);
863 }
864
865 static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
866         const char *name, *swho;
867         Manager *m = userdata;
868         Session *session;
869         int32_t signo;
870         KillWho who;
871         int r;
872
873         assert(bus);
874         assert(message);
875         assert(m);
876
877         r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
878         if (r < 0)
879                 return r;
880
881         if (isempty(swho))
882                 who = KILL_ALL;
883         else {
884                 who = kill_who_from_string(swho);
885                 if (who < 0)
886                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
887         }
888
889         if (signo <= 0 || signo >= _NSIG)
890                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
891
892         session = hashmap_get(m->sessions, name);
893         if (!session)
894                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
895
896         r = session_kill(session, who, signo);
897         if (r < 0)
898                 return r;
899
900         return sd_bus_reply_method_return(message, NULL);
901 }
902
903 static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
904         Manager *m = userdata;
905         uint32_t uid;
906         int32_t signo;
907         User *user;
908         int r;
909
910         assert(bus);
911         assert(message);
912         assert(m);
913
914         r = sd_bus_message_read(message, "ui", &uid, &signo);
915         if (r < 0)
916                 return r;
917
918         if (signo <= 0 || signo >= _NSIG)
919                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
920
921         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
922         if (!user)
923                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
924
925         r = user_kill(user, signo);
926         if (r < 0)
927                 return r;
928
929         return sd_bus_reply_method_return(message, NULL);
930 }
931
932 static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
933         Manager *m = userdata;
934         const char *name;
935         Session *session;
936         int r;
937
938         assert(bus);
939         assert(message);
940         assert(m);
941
942         r = sd_bus_message_read(message, "s", &name);
943         if (r < 0)
944                 return r;
945
946         session = hashmap_get(m->sessions, name);
947         if (!session)
948                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
949
950         r = session_stop(session);
951         if (r < 0)
952                 return r;
953
954         return sd_bus_reply_method_return(message, NULL);
955 }
956
957 static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
958         Manager *m = userdata;
959         uint32_t uid;
960         User *user;
961         int r;
962
963         assert(bus);
964         assert(message);
965         assert(m);
966
967         r = sd_bus_message_read(message, "u", &uid);
968         if (r < 0)
969                 return r;
970
971         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
972         if (!user)
973                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
974
975         r = user_stop(user);
976         if (r < 0)
977                 return r;
978
979         return sd_bus_reply_method_return(message, NULL);
980 }
981
982 static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
983         Manager *m = userdata;
984         const char *name;
985         Seat *seat;
986         int r;
987
988         assert(bus);
989         assert(message);
990         assert(m);
991
992         r = sd_bus_message_read(message, "s", &name);
993         if (r < 0)
994                 return r;
995
996         seat = hashmap_get(m->seats, name);
997         if (!seat)
998                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
999
1000         r = seat_stop_sessions(seat);
1001         if (r < 0)
1002                 return r;
1003
1004         return sd_bus_reply_method_return(message, NULL);
1005 }
1006
1007 static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1008         _cleanup_free_ char *cc = NULL;
1009         Manager *m = userdata;
1010         int b, r;
1011         struct passwd *pw;
1012         const char *path;
1013         uint32_t uid;
1014         int interactive;
1015
1016         assert(bus);
1017         assert(message);
1018         assert(m);
1019
1020         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
1021         if (r < 0)
1022                 return r;
1023
1024         errno = 0;
1025         pw = getpwuid(uid);
1026         if (!pw)
1027                 return errno ? -errno : -ENOENT;
1028
1029         r = bus_verify_polkit_async(bus,
1030                                     &m->polkit_registry,
1031                                     message,
1032                                     "org.freedesktop.login1.set-user-linger",
1033                                     interactive,
1034                                     error,
1035                                     method_set_user_linger, m);
1036         if (r < 0)
1037                 return r;
1038         if (r == 0)
1039                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1040
1041         mkdir_p_label("/var/lib/systemd", 0755);
1042
1043         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
1044         if (r < 0)
1045                 return r;
1046
1047         cc = cescape(pw->pw_name);
1048         if (!cc)
1049                 return -ENOMEM;
1050
1051         path = strappenda("/var/lib/systemd/linger/", cc);
1052         if (b) {
1053                 User *u;
1054
1055                 r = touch(path);
1056                 if (r < 0)
1057                         return r;
1058
1059                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
1060                         user_start(u);
1061
1062         } else {
1063                 User *u;
1064
1065                 r = unlink(path);
1066                 if (r < 0 && errno != ENOENT)
1067                         return -errno;
1068
1069                 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
1070                 if (u)
1071                         user_add_to_gc_queue(u);
1072         }
1073
1074         return sd_bus_reply_method_return(message, NULL);
1075 }
1076
1077 static int trigger_device(Manager *m, struct udev_device *d) {
1078         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
1079         struct udev_list_entry *first, *item;
1080         int r;
1081
1082         assert(m);
1083
1084         e = udev_enumerate_new(m->udev);
1085         if (!e)
1086                 return -ENOMEM;
1087
1088         if (d) {
1089                 r = udev_enumerate_add_match_parent(e, d);
1090                 if (r < 0)
1091                         return r;
1092         }
1093
1094         r = udev_enumerate_scan_devices(e);
1095         if (r < 0)
1096                 return r;
1097
1098         first = udev_enumerate_get_list_entry(e);
1099         udev_list_entry_foreach(item, first) {
1100                 _cleanup_free_ char *t = NULL;
1101                 const char *p;
1102
1103                 p = udev_list_entry_get_name(item);
1104
1105                 t = strappend(p, "/uevent");
1106                 if (!t)
1107                         return -ENOMEM;
1108
1109                 write_string_file(t, "change");
1110         }
1111
1112         return 0;
1113 }
1114
1115 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
1116         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
1117         _cleanup_free_ char *rule = NULL, *file = NULL;
1118         const char *id_for_seat;
1119         int r;
1120
1121         assert(m);
1122         assert(seat);
1123         assert(sysfs);
1124
1125         d = udev_device_new_from_syspath(m->udev, sysfs);
1126         if (!d)
1127                 return -ENODEV;
1128
1129         if (!udev_device_has_tag(d, "seat"))
1130                 return -ENODEV;
1131
1132         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
1133         if (!id_for_seat)
1134                 return -ENODEV;
1135
1136         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
1137                 return -ENOMEM;
1138
1139         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
1140                 return -ENOMEM;
1141
1142         mkdir_p_label("/etc/udev/rules.d", 0755);
1143         label_init("/etc");
1144         r = write_string_file_atomic_label(file, rule);
1145         if (r < 0)
1146                 return r;
1147
1148         return trigger_device(m, d);
1149 }
1150
1151 static int flush_devices(Manager *m) {
1152         _cleanup_closedir_ DIR *d;
1153
1154         assert(m);
1155
1156         d = opendir("/etc/udev/rules.d");
1157         if (!d) {
1158                 if (errno != ENOENT)
1159                         log_warning("Failed to open /etc/udev/rules.d: %m");
1160         } else {
1161                 struct dirent *de;
1162
1163                 while ((de = readdir(d))) {
1164
1165                         if (!dirent_is_file(de))
1166                                 continue;
1167
1168                         if (!startswith(de->d_name, "72-seat-"))
1169                                 continue;
1170
1171                         if (!endswith(de->d_name, ".rules"))
1172                                 continue;
1173
1174                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
1175                                 log_warning("Failed to unlink %s: %m", de->d_name);
1176                 }
1177         }
1178
1179         return trigger_device(m, NULL);
1180 }
1181
1182 static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1183         const char *sysfs, *seat;
1184         Manager *m = userdata;
1185         int interactive, r;
1186
1187         assert(bus);
1188         assert(message);
1189         assert(m);
1190
1191         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
1192         if (r < 0)
1193                 return r;
1194
1195         if (!path_startswith(sysfs, "/sys"))
1196                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
1197
1198         if (!seat_name_is_valid(seat))
1199                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
1200
1201         r = bus_verify_polkit_async(bus,
1202                                     &m->polkit_registry,
1203                                     message,
1204                                     "org.freedesktop.login1.attach-device",
1205                                     interactive,
1206                                     error,
1207                                     method_attach_device, m);
1208         if (r < 0)
1209                 return r;
1210         if (r == 0)
1211                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1212
1213         r = attach_device(m, seat, sysfs);
1214         if (r < 0)
1215                 return r;
1216
1217         return sd_bus_reply_method_return(message, NULL);
1218 }
1219
1220 static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1221         Manager *m = userdata;
1222         int interactive, r;
1223
1224         assert(bus);
1225         assert(message);
1226         assert(m);
1227
1228         r = sd_bus_message_read(message, "b", &interactive);
1229         if (r < 0)
1230                 return r;
1231
1232         r = bus_verify_polkit_async(bus,
1233                                     &m->polkit_registry,
1234                                     message,
1235                                     "org.freedesktop.login1.flush-devices",
1236                                     interactive,
1237                                     error,
1238                                     method_flush_devices, m);
1239         if (r < 0)
1240                 return r;
1241         if (r == 0)
1242                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1243
1244         r = flush_devices(m);
1245         if (r < 0)
1246                 return r;
1247
1248         return sd_bus_reply_method_return(message, NULL);
1249 }
1250
1251 static int have_multiple_sessions(
1252                 Manager *m,
1253                 uid_t uid) {
1254
1255         Session *session;
1256         Iterator i;
1257
1258         assert(m);
1259
1260         /* Check for other users' sessions. Greeter sessions do not
1261          * count, and non-login sessions do not count either. */
1262         HASHMAP_FOREACH(session, m->sessions, i)
1263                 if (session->class == SESSION_USER &&
1264                     session->user->uid != uid)
1265                         return true;
1266
1267         return false;
1268 }
1269
1270 static int bus_manager_log_shutdown(
1271                 Manager *m,
1272                 InhibitWhat w,
1273                 const char *unit_name) {
1274
1275         const char *p, *q;
1276
1277         assert(m);
1278         assert(unit_name);
1279
1280         if (w != INHIBIT_SHUTDOWN)
1281                 return 0;
1282
1283         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
1284                 p = "MESSAGE=System is powering down.";
1285                 q = "SHUTDOWN=power-off";
1286         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
1287                 p = "MESSAGE=System is halting.";
1288                 q = "SHUTDOWN=halt";
1289         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
1290                 p = "MESSAGE=System is rebooting.";
1291                 q = "SHUTDOWN=reboot";
1292         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
1293                 p = "MESSAGE=System is rebooting with kexec.";
1294                 q = "SHUTDOWN=kexec";
1295         } else {
1296                 p = "MESSAGE=System is shutting down.";
1297                 q = NULL;
1298         }
1299
1300         return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
1301                           p,
1302                           q, NULL);
1303 }
1304
1305 static int execute_shutdown_or_sleep(
1306                 Manager *m,
1307                 InhibitWhat w,
1308                 const char *unit_name,
1309                 sd_bus_error *error) {
1310
1311         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1312         const char *p;
1313         char *c;
1314         int r;
1315
1316         assert(m);
1317         assert(w >= 0);
1318         assert(w < _INHIBIT_WHAT_MAX);
1319         assert(unit_name);
1320
1321         bus_manager_log_shutdown(m, w, unit_name);
1322
1323         r = sd_bus_call_method(
1324                         m->bus,
1325                         "org.freedesktop.systemd1",
1326                         "/org/freedesktop/systemd1",
1327                         "org.freedesktop.systemd1.Manager",
1328                         "StartUnit",
1329                         error,
1330                         &reply,
1331                         "ss", unit_name, "replace-irreversibly");
1332         if (r < 0)
1333                 return r;
1334
1335         r = sd_bus_message_read(reply, "o", &p);
1336         if (r < 0)
1337                 return r;
1338
1339         c = strdup(p);
1340         if (!c)
1341                 return -ENOMEM;
1342
1343         m->action_unit = unit_name;
1344         free(m->action_job);
1345         m->action_job = c;
1346         m->action_what = w;
1347
1348         return 0;
1349 }
1350
1351 static int delay_shutdown_or_sleep(
1352                 Manager *m,
1353                 InhibitWhat w,
1354                 const char *unit_name) {
1355
1356         assert(m);
1357         assert(w >= 0);
1358         assert(w < _INHIBIT_WHAT_MAX);
1359         assert(unit_name);
1360
1361         m->action_timestamp = now(CLOCK_MONOTONIC);
1362         m->action_unit = unit_name;
1363         m->action_what = w;
1364
1365         return 0;
1366 }
1367
1368 static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
1369
1370         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
1371                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
1372                 [INHIBIT_SLEEP] = "PrepareForSleep"
1373         };
1374
1375         int active = _active;
1376
1377         assert(m);
1378         assert(w >= 0);
1379         assert(w < _INHIBIT_WHAT_MAX);
1380         assert(signal_name[w]);
1381
1382         return sd_bus_emit_signal(m->bus,
1383                                   "/org/freedesktop/login1",
1384                                   "org.freedesktop.login1.Manager",
1385                                   signal_name[w],
1386                                   "b",
1387                                   active);
1388 }
1389
1390 int bus_manager_shutdown_or_sleep_now_or_later(
1391                 Manager *m,
1392                 const char *unit_name,
1393                 InhibitWhat w,
1394                 sd_bus_error *error) {
1395
1396         bool delayed;
1397         int r;
1398
1399         assert(m);
1400         assert(unit_name);
1401         assert(w >= 0);
1402         assert(w <= _INHIBIT_WHAT_MAX);
1403         assert(!m->action_job);
1404
1405         /* Tell everybody to prepare for shutdown/sleep */
1406         send_prepare_for(m, w, true);
1407
1408         delayed =
1409                 m->inhibit_delay_max > 0 &&
1410                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
1411
1412         if (delayed)
1413                 /* Shutdown is delayed, keep in mind what we
1414                  * want to do, and start a timeout */
1415                 r = delay_shutdown_or_sleep(m, w, unit_name);
1416         else
1417                 /* Shutdown is not delayed, execute it
1418                  * immediately */
1419                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
1420
1421         return r;
1422 }
1423
1424 static int method_do_shutdown_or_sleep(
1425                 Manager *m,
1426                 sd_bus_message *message,
1427                 const char *unit_name,
1428                 InhibitWhat w,
1429                 const char *action,
1430                 const char *action_multiple_sessions,
1431                 const char *action_ignore_inhibit,
1432                 const char *sleep_verb,
1433                 sd_bus_message_handler_t method,
1434                 sd_bus_error *error) {
1435
1436         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1437         bool multiple_sessions, blocked;
1438         int interactive, r;
1439         uid_t uid;
1440
1441         assert(m);
1442         assert(message);
1443         assert(unit_name);
1444         assert(w >= 0);
1445         assert(w <= _INHIBIT_WHAT_MAX);
1446         assert(action);
1447         assert(action_multiple_sessions);
1448         assert(action_ignore_inhibit);
1449         assert(method);
1450
1451         r = sd_bus_message_read(message, "b", &interactive);
1452         if (r < 0)
1453                 return r;
1454
1455         /* Don't allow multiple jobs being executed at the same time */
1456         if (m->action_what)
1457                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
1458
1459         if (sleep_verb) {
1460                 r = can_sleep(sleep_verb);
1461                 if (r < 0)
1462                         return r;
1463
1464                 if (r == 0)
1465                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
1466         }
1467
1468         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1469         if (r < 0)
1470                 return r;
1471
1472         r = sd_bus_creds_get_uid(creds, &uid);
1473         if (r < 0)
1474                 return r;
1475
1476         r = have_multiple_sessions(m, uid);
1477         if (r < 0)
1478                 return r;
1479
1480         multiple_sessions = r > 0;
1481         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1482
1483         if (multiple_sessions) {
1484                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1485                                             action_multiple_sessions, interactive, error, method, m);
1486                 if (r < 0)
1487                         return r;
1488         }
1489
1490         if (blocked) {
1491                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1492                                             action_ignore_inhibit, interactive, error, method, m);
1493                 if (r < 0)
1494                         return r;
1495         }
1496
1497         if (!multiple_sessions && !blocked) {
1498                 r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
1499                                             action, interactive, error, method, m);
1500                 if (r < 0)
1501                         return r;
1502         }
1503
1504         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
1505         if (r < 0)
1506                 return r;
1507
1508         return sd_bus_reply_method_return(message, NULL);
1509 }
1510
1511 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1512         Manager *m = userdata;
1513
1514         return method_do_shutdown_or_sleep(
1515                         m, message,
1516                         SPECIAL_POWEROFF_TARGET,
1517                         INHIBIT_SHUTDOWN,
1518                         "org.freedesktop.login1.power-off",
1519                         "org.freedesktop.login1.power-off-multiple-sessions",
1520                         "org.freedesktop.login1.power-off-ignore-inhibit",
1521                         NULL,
1522                         method_poweroff,
1523                         error);
1524 }
1525
1526 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1527         Manager *m = userdata;
1528
1529         return method_do_shutdown_or_sleep(
1530                         m, message,
1531                         SPECIAL_REBOOT_TARGET,
1532                         INHIBIT_SHUTDOWN,
1533                         "org.freedesktop.login1.reboot",
1534                         "org.freedesktop.login1.reboot-multiple-sessions",
1535                         "org.freedesktop.login1.reboot-ignore-inhibit",
1536                         NULL,
1537                         method_reboot,
1538                         error);
1539 }
1540
1541 static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1542         Manager *m = userdata;
1543
1544         return method_do_shutdown_or_sleep(
1545                         m, message,
1546                         SPECIAL_SUSPEND_TARGET,
1547                         INHIBIT_SLEEP,
1548                         "org.freedesktop.login1.suspend",
1549                         "org.freedesktop.login1.suspend-multiple-sessions",
1550                         "org.freedesktop.login1.suspend-ignore-inhibit",
1551                         "suspend",
1552                         method_suspend,
1553                         error);
1554 }
1555
1556 static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1557         Manager *m = userdata;
1558
1559         return method_do_shutdown_or_sleep(
1560                         m, message,
1561                         SPECIAL_HIBERNATE_TARGET,
1562                         INHIBIT_SLEEP,
1563                         "org.freedesktop.login1.hibernate",
1564                         "org.freedesktop.login1.hibernate-multiple-sessions",
1565                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1566                         "hibernate",
1567                         method_hibernate,
1568                         error);
1569 }
1570
1571 static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1572         Manager *m = userdata;
1573
1574         return method_do_shutdown_or_sleep(
1575                         m, message,
1576                         SPECIAL_HYBRID_SLEEP_TARGET,
1577                         INHIBIT_SLEEP,
1578                         "org.freedesktop.login1.hibernate",
1579                         "org.freedesktop.login1.hibernate-multiple-sessions",
1580                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1581                         "hybrid-sleep",
1582                         method_hybrid_sleep,
1583                         error);
1584 }
1585
1586 static int method_can_shutdown_or_sleep(
1587                 Manager *m,
1588                 sd_bus_message *message,
1589                 InhibitWhat w,
1590                 const char *action,
1591                 const char *action_multiple_sessions,
1592                 const char *action_ignore_inhibit,
1593                 const char *sleep_verb,
1594                 sd_bus_error *error) {
1595
1596         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1597         bool multiple_sessions, challenge, blocked;
1598         const char *result = NULL;
1599         uid_t uid;
1600         int r;
1601
1602         assert(m);
1603         assert(message);
1604         assert(w >= 0);
1605         assert(w <= _INHIBIT_WHAT_MAX);
1606         assert(action);
1607         assert(action_multiple_sessions);
1608         assert(action_ignore_inhibit);
1609
1610         if (sleep_verb) {
1611                 r = can_sleep(sleep_verb);
1612                 if (r < 0)
1613                         return r;
1614                 if (r == 0)
1615                         return sd_bus_reply_method_return(message, "s", "na");
1616         }
1617
1618         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
1619         if (r < 0)
1620                 return r;
1621
1622         r = sd_bus_creds_get_uid(creds, &uid);
1623         if (r < 0)
1624                 return r;
1625
1626         r = have_multiple_sessions(m, uid);
1627         if (r < 0)
1628                 return r;
1629
1630         multiple_sessions = r > 0;
1631         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
1632
1633         if (multiple_sessions) {
1634                 r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
1635                 if (r < 0)
1636                         return r;
1637
1638                 if (r > 0)
1639                         result = "yes";
1640                 else if (challenge)
1641                         result = "challenge";
1642                 else
1643                         result = "no";
1644         }
1645
1646         if (blocked) {
1647                 r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
1648                 if (r < 0)
1649                         return r;
1650
1651                 if (r > 0 && !result)
1652                         result = "yes";
1653                 else if (challenge && (!result || streq(result, "yes")))
1654                         result = "challenge";
1655                 else
1656                         result = "no";
1657         }
1658
1659         if (!multiple_sessions && !blocked) {
1660                 /* If neither inhibit nor multiple sessions
1661                  * apply then just check the normal policy */
1662
1663                 r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
1664                 if (r < 0)
1665                         return r;
1666
1667                 if (r > 0)
1668                         result = "yes";
1669                 else if (challenge)
1670                         result = "challenge";
1671                 else
1672                         result = "no";
1673         }
1674
1675         return sd_bus_reply_method_return(message, "s", result);
1676 }
1677
1678 static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1679         Manager *m = userdata;
1680
1681         return method_can_shutdown_or_sleep(
1682                         m, message,
1683                         INHIBIT_SHUTDOWN,
1684                         "org.freedesktop.login1.power-off",
1685                         "org.freedesktop.login1.power-off-multiple-sessions",
1686                         "org.freedesktop.login1.power-off-ignore-inhibit",
1687                         NULL,
1688                         error);
1689 }
1690
1691 static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1692         Manager *m = userdata;
1693
1694         return method_can_shutdown_or_sleep(
1695                         m, message,
1696                         INHIBIT_SHUTDOWN,
1697                         "org.freedesktop.login1.reboot",
1698                         "org.freedesktop.login1.reboot-multiple-sessions",
1699                         "org.freedesktop.login1.reboot-ignore-inhibit",
1700                         NULL,
1701                         error);
1702 }
1703
1704 static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1705         Manager *m = userdata;
1706
1707         return method_can_shutdown_or_sleep(
1708                         m, message,
1709                         INHIBIT_SLEEP,
1710                         "org.freedesktop.login1.suspend",
1711                         "org.freedesktop.login1.suspend-multiple-sessions",
1712                         "org.freedesktop.login1.suspend-ignore-inhibit",
1713                         "suspend",
1714                         error);
1715 }
1716
1717 static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1718         Manager *m = userdata;
1719
1720         return method_can_shutdown_or_sleep(
1721                         m, message,
1722                         INHIBIT_SLEEP,
1723                         "org.freedesktop.login1.hibernate",
1724                         "org.freedesktop.login1.hibernate-multiple-sessions",
1725                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1726                         "hibernate",
1727                         error);
1728 }
1729
1730 static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1731         Manager *m = userdata;
1732
1733         return method_can_shutdown_or_sleep(
1734                         m, message,
1735                         INHIBIT_SLEEP,
1736                         "org.freedesktop.login1.hibernate",
1737                         "org.freedesktop.login1.hibernate-multiple-sessions",
1738                         "org.freedesktop.login1.hibernate-ignore-inhibit",
1739                         "hybrid-sleep",
1740                         error);
1741 }
1742
1743 static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1744         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
1745         const char *who, *why, *what, *mode;
1746         _cleanup_free_ char *id = NULL;
1747         _cleanup_close_ int fifo_fd = -1;
1748         Manager *m = userdata;
1749         Inhibitor *i = NULL;
1750         InhibitMode mm;
1751         InhibitWhat w;
1752         pid_t pid;
1753         uid_t uid;
1754         int r;
1755
1756         assert(bus);
1757         assert(message);
1758         assert(m);
1759
1760         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
1761         if (r < 0)
1762                 return r;
1763
1764         w = inhibit_what_from_string(what);
1765         if (w <= 0)
1766                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
1767
1768         mm = inhibit_mode_from_string(mode);
1769         if (mm < 0)
1770                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
1771
1772         /* Delay is only supported for shutdown/sleep */
1773         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
1774                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
1775
1776         /* Don't allow taking delay locks while we are already
1777          * executing the operation. We shouldn't create the impression
1778          * that the lock was successful if the machine is about to go
1779          * down/suspend any moment. */
1780         if (m->action_what & w)
1781                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
1782
1783         r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
1784                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
1785                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
1786                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
1787                                     w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
1788                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
1789                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
1790                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
1791                                     false, error, method_inhibit, m);
1792         if (r < 0)
1793                 return r;
1794         if (r == 0)
1795                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1796
1797         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
1798         if (r < 0)
1799                 return r;
1800
1801         r = sd_bus_creds_get_uid(creds, &uid);
1802         if (r < 0)
1803                 return r;
1804
1805         r = sd_bus_creds_get_pid(creds, &pid);
1806         if (r < 0)
1807                 return r;
1808
1809         do {
1810                 free(id);
1811                 id = NULL;
1812
1813                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
1814                         return -ENOMEM;
1815
1816         } while (hashmap_get(m->inhibitors, id));
1817
1818         r = manager_add_inhibitor(m, id, &i);
1819         if (r < 0)
1820                 return r;
1821
1822         i->what = w;
1823         i->mode = mm;
1824         i->pid = pid;
1825         i->uid = uid;
1826         i->why = strdup(why);
1827         i->who = strdup(who);
1828
1829         if (!i->why || !i->who) {
1830                 r = -ENOMEM;
1831                 goto fail;
1832         }
1833
1834         fifo_fd = inhibitor_create_fifo(i);
1835         if (fifo_fd < 0) {
1836                 r = fifo_fd;
1837                 goto fail;
1838         }
1839
1840         inhibitor_start(i);
1841
1842         return sd_bus_reply_method_return(message, "h", fifo_fd);
1843
1844 fail:
1845         if (i)
1846                 inhibitor_free(i);
1847
1848         return r;
1849 }
1850
1851 const sd_bus_vtable manager_vtable[] = {
1852         SD_BUS_VTABLE_START(0),
1853
1854         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
1855         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
1856         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
1857         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
1858         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1859         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1860         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1861         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1862         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1863         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
1864         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
1865         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
1866         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
1867         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
1868         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
1869         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1870         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
1871         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
1872
1873         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
1874         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1875         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
1876         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1877         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1878         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
1879         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
1880         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
1881         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
1882         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
1883         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
1884         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
1885         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
1886         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
1887         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
1888         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
1889         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
1890         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1891         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1892         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1893         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1894         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1895         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
1896         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
1897         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
1898         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1899         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1900         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1901         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1902         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1903         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
1904         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
1905         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
1906         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
1907         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
1908         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
1909
1910         SD_BUS_SIGNAL("SessionNew", "so", 0),
1911         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
1912         SD_BUS_SIGNAL("UserNew", "uo", 0),
1913         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
1914         SD_BUS_SIGNAL("SeatNew", "so", 0),
1915         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
1916         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
1917         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
1918
1919         SD_BUS_VTABLE_END
1920 };
1921
1922 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1923         const char *path, *result, *unit;
1924         Manager *m = userdata;
1925         Session *session;
1926         uint32_t id;
1927         User *user;
1928         int r;
1929
1930         assert(bus);
1931         assert(message);
1932         assert(m);
1933
1934         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1935         if (r < 0) {
1936                 bus_log_parse_error(r);
1937                 return r;
1938         }
1939
1940         if (m->action_job && streq(m->action_job, path)) {
1941                 log_info("Operation finished.");
1942
1943                 /* Tell people that they now may take a lock again */
1944                 send_prepare_for(m, m->action_what, false);
1945
1946                 free(m->action_job);
1947                 m->action_job = NULL;
1948                 m->action_unit = NULL;
1949                 m->action_what = 0;
1950                 return 0;
1951         }
1952
1953         session = hashmap_get(m->session_units, unit);
1954         if (session) {
1955
1956                 if (streq_ptr(path, session->scope_job)) {
1957                         free(session->scope_job);
1958                         session->scope_job = NULL;
1959                 }
1960
1961                 if (session->started) {
1962                         if (streq(result, "done"))
1963                                 session_send_create_reply(session, NULL);
1964                         else {
1965                                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1966
1967                                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1968                                 session_send_create_reply(session, &e);
1969                         }
1970                 } else
1971                         session_save(session);
1972
1973                 session_add_to_gc_queue(session);
1974         }
1975
1976         user = hashmap_get(m->user_units, unit);
1977         if (user) {
1978
1979                 if (streq_ptr(path, user->service_job)) {
1980                         free(user->service_job);
1981                         user->service_job = NULL;
1982                 }
1983
1984                 if (streq_ptr(path, user->slice_job)) {
1985                         free(user->slice_job);
1986                         user->slice_job = NULL;
1987                 }
1988
1989                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
1990                         if (!session->started)
1991                                 continue;
1992
1993                         if (streq(result, "done"))
1994                                 session_send_create_reply(session, NULL);
1995                         else {
1996                                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
1997
1998                                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1999                                 session_send_create_reply(session, &e);
2000                         }
2001                 }
2002
2003                 user_save(user);
2004                 user_add_to_gc_queue(user);
2005         }
2006
2007         return 0;
2008 }
2009
2010 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2011         const char *path, *unit;
2012         Manager *m = userdata;
2013         Session *session;
2014         User *user;
2015         int r;
2016
2017         assert(bus);
2018         assert(message);
2019         assert(m);
2020
2021         r = sd_bus_message_read(message, "so", &unit, &path);
2022         if (r < 0) {
2023                 bus_log_parse_error(r);
2024                 return r;
2025         }
2026
2027         session = hashmap_get(m->session_units, unit);
2028         if (session)
2029                 session_add_to_gc_queue(session);
2030
2031         user = hashmap_get(m->user_units, unit);
2032         if (user)
2033                 user_add_to_gc_queue(user);
2034
2035         return 0;
2036 }
2037
2038 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2039         _cleanup_free_ char *unit = NULL;
2040         Manager *m = userdata;
2041         const char *path;
2042         Session *session;
2043         User *user;
2044         int r;
2045
2046         assert(bus);
2047         assert(message);
2048         assert(m);
2049
2050         path = sd_bus_message_get_path(message);
2051         if (!path)
2052                 return 0;
2053
2054         r = unit_name_from_dbus_path(path, &unit);
2055         if (r < 0)
2056                 return r;
2057
2058         session = hashmap_get(m->session_units, unit);
2059         if (session)
2060                 session_add_to_gc_queue(session);
2061
2062         user = hashmap_get(m->user_units, unit);
2063         if (user)
2064                 user_add_to_gc_queue(user);
2065
2066         return 0;
2067 }
2068
2069 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2070         Manager *m = userdata;
2071         Session *session;
2072         Iterator i;
2073         int b, r;
2074
2075         assert(bus);
2076
2077         r = sd_bus_message_read(message, "b", &b);
2078         if (r < 0) {
2079                 bus_log_parse_error(r);
2080                 return r;
2081         }
2082
2083         if (b)
2084                 return 0;
2085
2086         /* systemd finished reloading, let's recheck all our sessions */
2087         log_debug("System manager has been reloaded, rechecking sessions...");
2088
2089         HASHMAP_FOREACH(session, m->sessions, i)
2090                 session_add_to_gc_queue(session);
2091
2092         return 0;
2093 }
2094
2095 int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2096         const char *name, *old, *new;
2097         Manager *m = userdata;
2098         Session *session;
2099         Iterator i;
2100         int r;
2101
2102
2103         char *key;
2104
2105         r = sd_bus_message_read(message, "sss", &name, &old, &new);
2106         if (r < 0) {
2107                 bus_log_parse_error(r);
2108                 return r;
2109         }
2110
2111         if (isempty(old) || !isempty(new))
2112                 return 0;
2113
2114         key = set_remove(m->busnames, (char*) old);
2115         if (!key)
2116                 return 0;
2117
2118         /* Drop all controllers owned by this name */
2119
2120         free(key);
2121
2122         HASHMAP_FOREACH(session, m->sessions, i)
2123                 if (session_is_controller(session, old))
2124                         session_drop_controller(session);
2125
2126         return 0;
2127 }
2128
2129 int manager_send_changed(Manager *manager, const char *property, ...) {
2130         char **l;
2131
2132         assert(manager);
2133
2134         l = strv_from_stdarg_alloca(property);
2135
2136         return sd_bus_emit_properties_changed_strv(
2137                         manager->bus,
2138                         "/org/freedesktop/login1",
2139                         "org.freedesktop.login1.Manager",
2140                         l);
2141 }
2142
2143 int manager_dispatch_delayed(Manager *manager) {
2144         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2145         Inhibitor *offending = NULL;
2146         int r;
2147
2148         assert(manager);
2149
2150         if (manager->action_what == 0 || manager->action_job)
2151                 return 0;
2152
2153         /* Continue delay? */
2154         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
2155                 _cleanup_free_ char *comm = NULL, *u = NULL;
2156
2157                 get_process_comm(offending->pid, &comm);
2158                 u = uid_to_name(offending->uid);
2159
2160                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
2161                         return 0;
2162
2163                 log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
2164                          (unsigned long) offending->uid, strna(u),
2165                          (unsigned long) offending->pid, strna(comm));
2166         }
2167
2168         /* Actually do the operation */
2169         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
2170         if (r < 0) {
2171                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
2172
2173                 manager->action_unit = NULL;
2174                 manager->action_what = 0;
2175                 return r;
2176         }
2177
2178         return 1;
2179 }
2180
2181 int manager_start_scope(
2182                 Manager *manager,
2183                 const char *scope,
2184                 pid_t pid,
2185                 const char *slice,
2186                 const char *description,
2187                 const char *after,
2188                 const char *kill_mode,
2189                 sd_bus_error *error,
2190                 char **job) {
2191
2192         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2193         int r;
2194
2195         assert(manager);
2196         assert(scope);
2197         assert(pid > 1);
2198
2199         r = sd_bus_message_new_method_call(
2200                         manager->bus,
2201                         "org.freedesktop.systemd1",
2202                         "/org/freedesktop/systemd1",
2203                         "org.freedesktop.systemd1.Manager",
2204                         "StartTransientUnit",
2205                         &m);
2206         if (r < 0)
2207                 return r;
2208
2209         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
2210         if (r < 0)
2211                 return r;
2212
2213         r = sd_bus_message_open_container(m, 'a', "(sv)");
2214         if (r < 0)
2215                 return r;
2216
2217         if (!isempty(slice)) {
2218                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
2219                 if (r < 0)
2220                         return r;
2221         }
2222
2223         if (!isempty(description)) {
2224                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
2225                 if (r < 0)
2226                         return r;
2227         }
2228
2229         if (!isempty(description)) {
2230                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
2231                 if (r < 0)
2232                         return r;
2233         }
2234
2235         if (!isempty(kill_mode)) {
2236                 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", kill_mode);
2237                 if (r < 0)
2238                         return r;
2239         }
2240
2241         /* cgroup empty notification is not available in containers
2242          * currently. To make this less problematic, let's shorten the
2243          * stop timeout for sessions, so that we don't wait
2244          * forever. */
2245
2246         r = sd_bus_message_append(m, "(sv)", "TimeoutStopUSec", "t", 500 * USEC_PER_MSEC);
2247         if (r < 0)
2248                 return r;
2249
2250         /* Make sure that the session shells are terminated with
2251          * SIGHUP since bash and friends tend to ignore SIGTERM */
2252         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
2253         if (r < 0)
2254                 return r;
2255
2256         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
2257         if (r < 0)
2258                 return r;
2259
2260         r = sd_bus_message_close_container(m);
2261         if (r < 0)
2262                 return r;
2263
2264         r = sd_bus_message_append(m, "a(sa(sv))", 0);
2265         if (r < 0)
2266                 return r;
2267
2268         r = sd_bus_call(manager->bus, m, 0, error, &reply);
2269         if (r < 0)
2270                 return r;
2271
2272         if (job) {
2273                 const char *j;
2274                 char *copy;
2275
2276                 r = sd_bus_message_read(reply, "o", &j);
2277                 if (r < 0)
2278                         return r;
2279
2280                 copy = strdup(j);
2281                 if (!copy)
2282                         return -ENOMEM;
2283
2284                 *job = copy;
2285         }
2286
2287         return 1;
2288 }
2289
2290 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2291         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2292         int r;
2293
2294         assert(manager);
2295         assert(unit);
2296
2297         r = sd_bus_call_method(
2298                         manager->bus,
2299                         "org.freedesktop.systemd1",
2300                         "/org/freedesktop/systemd1",
2301                         "org.freedesktop.systemd1.Manager",
2302                         "StartUnit",
2303                         error,
2304                         &reply,
2305                         "ss", unit, "fail");
2306         if (r < 0)
2307                 return r;
2308
2309         if (job) {
2310                 const char *j;
2311                 char *copy;
2312
2313                 r = sd_bus_message_read(reply, "o", &j);
2314                 if (r < 0)
2315                         return r;
2316
2317                 copy = strdup(j);
2318                 if (!copy)
2319                         return -ENOMEM;
2320
2321                 *job = copy;
2322         }
2323
2324         return 1;
2325 }
2326
2327 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
2328         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2329         int r;
2330
2331         assert(manager);
2332         assert(unit);
2333
2334         r = sd_bus_call_method(
2335                         manager->bus,
2336                         "org.freedesktop.systemd1",
2337                         "/org/freedesktop/systemd1",
2338                         "org.freedesktop.systemd1.Manager",
2339                         "StopUnit",
2340                         error,
2341                         &reply,
2342                         "ss", unit, "fail");
2343         if (r < 0) {
2344                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
2345                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
2346
2347                         if (job)
2348                                 *job = NULL;
2349
2350                         sd_bus_error_free(error);
2351                         return 0;
2352                 }
2353
2354                 return r;
2355         }
2356
2357         if (job) {
2358                 const char *j;
2359                 char *copy;
2360
2361                 r = sd_bus_message_read(reply, "o", &j);
2362                 if (r < 0)
2363                         return r;
2364
2365                 copy = strdup(j);
2366                 if (!copy)
2367                         return -ENOMEM;
2368
2369                 *job = copy;
2370         }
2371
2372         return 1;
2373 }
2374
2375 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
2376         assert(manager);
2377         assert(unit);
2378
2379         return sd_bus_call_method(
2380                         manager->bus,
2381                         "org.freedesktop.systemd1",
2382                         "/org/freedesktop/systemd1",
2383                         "org.freedesktop.systemd1.Manager",
2384                         "KillUnit",
2385                         error,
2386                         NULL,
2387                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
2388 }
2389
2390 int manager_unit_is_active(Manager *manager, const char *unit) {
2391         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2392         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2393         _cleanup_free_ char *path = NULL;
2394         const char *state;
2395         int r;
2396
2397         assert(manager);
2398         assert(unit);
2399
2400         path = unit_dbus_path_from_name(unit);
2401         if (!path)
2402                 return -ENOMEM;
2403
2404         r = sd_bus_get_property(
2405                         manager->bus,
2406                         "org.freedesktop.systemd1",
2407                         path,
2408                         "org.freedesktop.systemd1.Unit",
2409                         "ActiveState",
2410                         &error,
2411                         &reply,
2412                         "s");
2413         if (r < 0) {
2414                 /* systemd might have droppped off momentarily, let's
2415                  * not make this an error */
2416                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2417                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2418                         return true;
2419
2420                 /* If the unit is already unloaded then it's not
2421                  * active */
2422                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
2423                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
2424                         return false;
2425
2426                 return r;
2427         }
2428
2429         r = sd_bus_message_read(reply, "s", &state);
2430         if (r < 0)
2431                 return -EINVAL;
2432
2433         return !streq(state, "inactive") && !streq(state, "failed");
2434 }
2435
2436 int manager_job_is_active(Manager *manager, const char *path) {
2437         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2438         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2439         int r;
2440
2441         assert(manager);
2442         assert(path);
2443
2444         r = sd_bus_get_property(
2445                         manager->bus,
2446                         "org.freedesktop.systemd1",
2447                         path,
2448                         "org.freedesktop.systemd1.Job",
2449                         "State",
2450                         &error,
2451                         &reply,
2452                         "s");
2453         if (r < 0) {
2454                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
2455                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
2456                         return true;
2457
2458                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
2459                         return false;
2460
2461                 return r;
2462         }
2463
2464         /* We don't actually care about the state really. The fact
2465          * that we could read the job state is enough for us */
2466
2467         return true;
2468 }