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