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