]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind-session-dbus.c
Merge pull request #7411 from joergsteffens/tapechanger
[thirdparty/systemd.git] / src / login / logind-session-dbus.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <string.h>
5
6 #include "alloc-util.h"
7 #include "bus-common-errors.h"
8 #include "bus-label.h"
9 #include "bus-util.h"
10 #include "fd-util.h"
11 #include "logind-session-device.h"
12 #include "logind-session.h"
13 #include "logind.h"
14 #include "signal-util.h"
15 #include "strv.h"
16 #include "util.h"
17
18 static int property_get_user(
19 sd_bus *bus,
20 const char *path,
21 const char *interface,
22 const char *property,
23 sd_bus_message *reply,
24 void *userdata,
25 sd_bus_error *error) {
26
27 _cleanup_free_ char *p = NULL;
28 Session *s = userdata;
29
30 assert(bus);
31 assert(reply);
32 assert(s);
33
34 p = user_bus_path(s->user);
35 if (!p)
36 return -ENOMEM;
37
38 return sd_bus_message_append(reply, "(uo)", (uint32_t) s->user->uid, p);
39 }
40
41 static int property_get_name(
42 sd_bus *bus,
43 const char *path,
44 const char *interface,
45 const char *property,
46 sd_bus_message *reply,
47 void *userdata,
48 sd_bus_error *error) {
49
50 Session *s = userdata;
51
52 assert(bus);
53 assert(reply);
54 assert(s);
55
56 return sd_bus_message_append(reply, "s", s->user->name);
57 }
58
59 static int property_get_seat(
60 sd_bus *bus,
61 const char *path,
62 const char *interface,
63 const char *property,
64 sd_bus_message *reply,
65 void *userdata,
66 sd_bus_error *error) {
67
68 _cleanup_free_ char *p = NULL;
69 Session *s = userdata;
70
71 assert(bus);
72 assert(reply);
73 assert(s);
74
75 p = s->seat ? seat_bus_path(s->seat) : strdup("/");
76 if (!p)
77 return -ENOMEM;
78
79 return sd_bus_message_append(reply, "(so)", s->seat ? s->seat->id : "", p);
80 }
81
82 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, session_type, SessionType);
83 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, session_class, SessionClass);
84 static BUS_DEFINE_PROPERTY_GET(property_get_active, "b", Session, session_is_active);
85 static BUS_DEFINE_PROPERTY_GET2(property_get_state, "s", Session, session_get_state, session_state_to_string);
86
87 static int property_get_idle_hint(
88 sd_bus *bus,
89 const char *path,
90 const char *interface,
91 const char *property,
92 sd_bus_message *reply,
93 void *userdata,
94 sd_bus_error *error) {
95
96 Session *s = userdata;
97
98 assert(bus);
99 assert(reply);
100 assert(s);
101
102 return sd_bus_message_append(reply, "b", session_get_idle_hint(s, NULL) > 0);
103 }
104
105 static int property_get_idle_since_hint(
106 sd_bus *bus,
107 const char *path,
108 const char *interface,
109 const char *property,
110 sd_bus_message *reply,
111 void *userdata,
112 sd_bus_error *error) {
113
114 Session *s = userdata;
115 dual_timestamp t = DUAL_TIMESTAMP_NULL;
116 uint64_t u;
117 int r;
118
119 assert(bus);
120 assert(reply);
121 assert(s);
122
123 r = session_get_idle_hint(s, &t);
124 if (r < 0)
125 return r;
126
127 u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
128
129 return sd_bus_message_append(reply, "t", u);
130 }
131
132 static int property_get_locked_hint(
133 sd_bus *bus,
134 const char *path,
135 const char *interface,
136 const char *property,
137 sd_bus_message *reply,
138 void *userdata,
139 sd_bus_error *error) {
140
141 Session *s = userdata;
142
143 assert(bus);
144 assert(reply);
145 assert(s);
146
147 return sd_bus_message_append(reply, "b", session_get_locked_hint(s) > 0);
148 }
149
150 int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
151 Session *s = userdata;
152 int r;
153
154 assert(message);
155 assert(s);
156
157 r = bus_verify_polkit_async(
158 message,
159 CAP_KILL,
160 "org.freedesktop.login1.manage",
161 NULL,
162 false,
163 s->user->uid,
164 &s->manager->polkit_registry,
165 error);
166 if (r < 0)
167 return r;
168 if (r == 0)
169 return 1; /* Will call us back */
170
171 r = session_stop(s, true);
172 if (r < 0)
173 return r;
174
175 return sd_bus_reply_method_return(message, NULL);
176 }
177
178 int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
179 Session *s = userdata;
180 int r;
181
182 assert(message);
183 assert(s);
184
185 r = session_activate(s);
186 if (r < 0)
187 return r;
188
189 return sd_bus_reply_method_return(message, NULL);
190 }
191
192 int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error) {
193 Session *s = userdata;
194 int r;
195
196 assert(message);
197 assert(s);
198
199 r = bus_verify_polkit_async(
200 message,
201 CAP_SYS_ADMIN,
202 "org.freedesktop.login1.lock-sessions",
203 NULL,
204 false,
205 s->user->uid,
206 &s->manager->polkit_registry,
207 error);
208 if (r < 0)
209 return r;
210 if (r == 0)
211 return 1; /* Will call us back */
212
213 r = session_send_lock(s, strstr(sd_bus_message_get_member(message), "Lock"));
214 if (r < 0)
215 return r;
216
217 return sd_bus_reply_method_return(message, NULL);
218 }
219
220 static int method_set_idle_hint(sd_bus_message *message, void *userdata, sd_bus_error *error) {
221 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
222 Session *s = userdata;
223 uid_t uid;
224 int r, b;
225
226 assert(message);
227 assert(s);
228
229 r = sd_bus_message_read(message, "b", &b);
230 if (r < 0)
231 return r;
232
233 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
234 if (r < 0)
235 return r;
236
237 r = sd_bus_creds_get_euid(creds, &uid);
238 if (r < 0)
239 return r;
240
241 if (uid != 0 && uid != s->user->uid)
242 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set idle hint");
243
244 session_set_idle_hint(s, b);
245
246 return sd_bus_reply_method_return(message, NULL);
247 }
248
249 static int method_set_locked_hint(sd_bus_message *message, void *userdata, sd_bus_error *error) {
250 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
251 Session *s = userdata;
252 uid_t uid;
253 int r, b;
254
255 assert(message);
256 assert(s);
257
258 r = sd_bus_message_read(message, "b", &b);
259 if (r < 0)
260 return r;
261
262 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
263 if (r < 0)
264 return r;
265
266 r = sd_bus_creds_get_euid(creds, &uid);
267 if (r < 0)
268 return r;
269
270 if (uid != 0 && uid != s->user->uid)
271 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set locked hint");
272
273 session_set_locked_hint(s, b);
274
275 return sd_bus_reply_method_return(message, NULL);
276 }
277
278 int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
279 Session *s = userdata;
280 const char *swho;
281 int32_t signo;
282 KillWho who;
283 int r;
284
285 assert(message);
286 assert(s);
287
288 r = sd_bus_message_read(message, "si", &swho, &signo);
289 if (r < 0)
290 return r;
291
292 if (isempty(swho))
293 who = KILL_ALL;
294 else {
295 who = kill_who_from_string(swho);
296 if (who < 0)
297 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
298 }
299
300 if (!SIGNAL_VALID(signo))
301 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
302
303 r = bus_verify_polkit_async(
304 message,
305 CAP_KILL,
306 "org.freedesktop.login1.manage",
307 NULL,
308 false,
309 s->user->uid,
310 &s->manager->polkit_registry,
311 error);
312 if (r < 0)
313 return r;
314 if (r == 0)
315 return 1; /* Will call us back */
316
317 r = session_kill(s, who, signo);
318 if (r < 0)
319 return r;
320
321 return sd_bus_reply_method_return(message, NULL);
322 }
323
324 static int method_take_control(sd_bus_message *message, void *userdata, sd_bus_error *error) {
325 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
326 Session *s = userdata;
327 int r, force;
328 uid_t uid;
329
330 assert(message);
331 assert(s);
332
333 r = sd_bus_message_read(message, "b", &force);
334 if (r < 0)
335 return r;
336
337 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
338 if (r < 0)
339 return r;
340
341 r = sd_bus_creds_get_euid(creds, &uid);
342 if (r < 0)
343 return r;
344
345 if (uid != 0 && (force || uid != s->user->uid))
346 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
347
348 r = session_set_controller(s, sd_bus_message_get_sender(message), force, true);
349 if (r < 0)
350 return r;
351
352 return sd_bus_reply_method_return(message, NULL);
353 }
354
355 static int method_release_control(sd_bus_message *message, void *userdata, sd_bus_error *error) {
356 Session *s = userdata;
357
358 assert(message);
359 assert(s);
360
361 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
362 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
363
364 session_drop_controller(s);
365
366 return sd_bus_reply_method_return(message, NULL);
367 }
368
369 static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
370 Session *s = userdata;
371 uint32_t major, minor;
372 SessionDevice *sd;
373 dev_t dev;
374 int r;
375
376 assert(message);
377 assert(s);
378
379 r = sd_bus_message_read(message, "uu", &major, &minor);
380 if (r < 0)
381 return r;
382
383 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
384 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
385
386 dev = makedev(major, minor);
387 sd = hashmap_get(s->devices, &dev);
388 if (sd)
389 /* We don't allow retrieving a device multiple times.
390 * The related ReleaseDevice call is not ref-counted.
391 * The caller should use dup() if it requires more
392 * than one fd (it would be functionally
393 * equivalent). */
394 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
395
396 r = session_device_new(s, dev, true, &sd);
397 if (r < 0)
398 return r;
399
400 r = session_device_save(sd);
401 if (r < 0)
402 goto error;
403
404 r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
405 if (r < 0)
406 goto error;
407
408 session_save(s);
409 return 1;
410
411 error:
412 session_device_free(sd);
413 return r;
414 }
415
416 static int method_release_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
417 Session *s = userdata;
418 uint32_t major, minor;
419 SessionDevice *sd;
420 dev_t dev;
421 int r;
422
423 assert(message);
424 assert(s);
425
426 r = sd_bus_message_read(message, "uu", &major, &minor);
427 if (r < 0)
428 return r;
429
430 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
431 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
432
433 dev = makedev(major, minor);
434 sd = hashmap_get(s->devices, &dev);
435 if (!sd)
436 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
437
438 session_device_free(sd);
439 session_save(s);
440
441 return sd_bus_reply_method_return(message, NULL);
442 }
443
444 static int method_pause_device_complete(sd_bus_message *message, void *userdata, sd_bus_error *error) {
445 Session *s = userdata;
446 uint32_t major, minor;
447 SessionDevice *sd;
448 dev_t dev;
449 int r;
450
451 assert(message);
452 assert(s);
453
454 r = sd_bus_message_read(message, "uu", &major, &minor);
455 if (r < 0)
456 return r;
457
458 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
459 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
460
461 dev = makedev(major, minor);
462 sd = hashmap_get(s->devices, &dev);
463 if (!sd)
464 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
465
466 session_device_complete_pause(sd);
467
468 return sd_bus_reply_method_return(message, NULL);
469 }
470
471 const sd_bus_vtable session_vtable[] = {
472 SD_BUS_VTABLE_START(0),
473
474 SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
475 SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
476 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
477 BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
478 SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
479 SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
480 SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
481 SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
482 SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
483 SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
484 SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
485 SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
486 SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
487 SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
488 SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
489 SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
490 SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_CONST),
491 SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
492 SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
493 SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
494 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
495 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
496 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
497 SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
498
499 SD_BUS_METHOD("Terminate", NULL, NULL, bus_session_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
500 SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
501 SD_BUS_METHOD("Lock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
502 SD_BUS_METHOD("Unlock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
503 SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
504 SD_BUS_METHOD("SetLockedHint", "b", NULL, method_set_locked_hint, SD_BUS_VTABLE_UNPRIVILEGED),
505 SD_BUS_METHOD("Kill", "si", NULL, bus_session_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
506 SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, SD_BUS_VTABLE_UNPRIVILEGED),
507 SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED),
508 SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED),
509 SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED),
510 SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
511
512 SD_BUS_SIGNAL("PauseDevice", "uus", 0),
513 SD_BUS_SIGNAL("ResumeDevice", "uuh", 0),
514 SD_BUS_SIGNAL("Lock", NULL, 0),
515 SD_BUS_SIGNAL("Unlock", NULL, 0),
516
517 SD_BUS_VTABLE_END
518 };
519
520 int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
521 Manager *m = userdata;
522 Session *session;
523 int r;
524
525 assert(bus);
526 assert(path);
527 assert(interface);
528 assert(found);
529 assert(m);
530
531 if (streq(path, "/org/freedesktop/login1/session/self")) {
532 sd_bus_message *message;
533
534 message = sd_bus_get_current_message(bus);
535 if (!message)
536 return 0;
537
538 r = manager_get_session_from_creds(m, message, NULL, error, &session);
539 if (r < 0)
540 return r;
541 } else {
542 _cleanup_free_ char *e = NULL;
543 const char *p;
544
545 p = startswith(path, "/org/freedesktop/login1/session/");
546 if (!p)
547 return 0;
548
549 e = bus_label_unescape(p);
550 if (!e)
551 return -ENOMEM;
552
553 session = hashmap_get(m->sessions, e);
554 if (!session)
555 return 0;
556 }
557
558 *found = session;
559 return 1;
560 }
561
562 char *session_bus_path(Session *s) {
563 _cleanup_free_ char *t = NULL;
564
565 assert(s);
566
567 t = bus_label_escape(s->id);
568 if (!t)
569 return NULL;
570
571 return strappend("/org/freedesktop/login1/session/", t);
572 }
573
574 int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
575 _cleanup_strv_free_ char **l = NULL;
576 sd_bus_message *message;
577 Manager *m = userdata;
578 Session *session;
579 Iterator i;
580 int r;
581
582 assert(bus);
583 assert(path);
584 assert(nodes);
585
586 HASHMAP_FOREACH(session, m->sessions, i) {
587 char *p;
588
589 p = session_bus_path(session);
590 if (!p)
591 return -ENOMEM;
592
593 r = strv_consume(&l, p);
594 if (r < 0)
595 return r;
596 }
597
598 message = sd_bus_get_current_message(bus);
599 if (message) {
600 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
601 const char *name;
602
603 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
604 if (r >= 0) {
605 r = sd_bus_creds_get_session(creds, &name);
606 if (r >= 0) {
607 session = hashmap_get(m->sessions, name);
608 if (session) {
609 r = strv_extend(&l, "/org/freedesktop/login1/session/self");
610 if (r < 0)
611 return r;
612 }
613 }
614 }
615 }
616
617 *nodes = TAKE_PTR(l);
618
619 return 1;
620 }
621
622 int session_send_signal(Session *s, bool new_session) {
623 _cleanup_free_ char *p = NULL;
624
625 assert(s);
626
627 p = session_bus_path(s);
628 if (!p)
629 return -ENOMEM;
630
631 return sd_bus_emit_signal(
632 s->manager->bus,
633 "/org/freedesktop/login1",
634 "org.freedesktop.login1.Manager",
635 new_session ? "SessionNew" : "SessionRemoved",
636 "so", s->id, p);
637 }
638
639 int session_send_changed(Session *s, const char *properties, ...) {
640 _cleanup_free_ char *p = NULL;
641 char **l;
642
643 assert(s);
644
645 if (!s->started)
646 return 0;
647
648 p = session_bus_path(s);
649 if (!p)
650 return -ENOMEM;
651
652 l = strv_from_stdarg_alloca(properties);
653
654 return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Session", l);
655 }
656
657 int session_send_lock(Session *s, bool lock) {
658 _cleanup_free_ char *p = NULL;
659
660 assert(s);
661
662 p = session_bus_path(s);
663 if (!p)
664 return -ENOMEM;
665
666 return sd_bus_emit_signal(
667 s->manager->bus,
668 p,
669 "org.freedesktop.login1.Session",
670 lock ? "Lock" : "Unlock",
671 NULL);
672 }
673
674 int session_send_lock_all(Manager *m, bool lock) {
675 Session *session;
676 Iterator i;
677 int r = 0;
678
679 assert(m);
680
681 HASHMAP_FOREACH(session, m->sessions, i) {
682 int k;
683
684 k = session_send_lock(session, lock);
685 if (k < 0)
686 r = k;
687 }
688
689 return r;
690 }
691
692 static bool session_ready(Session *s) {
693 assert(s);
694
695 /* Returns true when the session is ready, i.e. all jobs we enqueued for it are done (regardless if successful or not) */
696
697 return !s->scope_job &&
698 !s->user->service_job;
699 }
700
701 int session_send_create_reply(Session *s, sd_bus_error *error) {
702 _cleanup_(sd_bus_message_unrefp) sd_bus_message *c = NULL;
703 _cleanup_close_ int fifo_fd = -1;
704 _cleanup_free_ char *p = NULL;
705
706 assert(s);
707
708 /* This is called after the session scope and the user service were successfully created, and finishes where
709 * bus_manager_create_session() left off. */
710
711 if (!s->create_message)
712 return 0;
713
714 if (!sd_bus_error_is_set(error) && !session_ready(s))
715 return 0;
716
717 c = TAKE_PTR(s->create_message);
718 if (error)
719 return sd_bus_reply_method_error(c, error);
720
721 fifo_fd = session_create_fifo(s);
722 if (fifo_fd < 0)
723 return fifo_fd;
724
725 /* Update the session state file before we notify the client about the result. */
726 session_save(s);
727
728 p = session_bus_path(s);
729 if (!p)
730 return -ENOMEM;
731
732 log_debug("Sending reply about created session: "
733 "id=%s object_path=%s uid=%u runtime_path=%s "
734 "session_fd=%d seat=%s vtnr=%u",
735 s->id,
736 p,
737 (uint32_t) s->user->uid,
738 s->user->runtime_path,
739 fifo_fd,
740 s->seat ? s->seat->id : "",
741 (uint32_t) s->vtnr);
742
743 return sd_bus_reply_method_return(
744 c, "soshusub",
745 s->id,
746 p,
747 s->user->runtime_path,
748 fifo_fd,
749 (uint32_t) s->user->uid,
750 s->seat ? s->seat->id : "",
751 (uint32_t) s->vtnr,
752 false);
753 }