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