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