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