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