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