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