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