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