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