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