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