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