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