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