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