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