]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/logind-session-dbus.c
Merge pull request #1668 from ssahani/net1
[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
96aad8d1 25#include "bus-common-errors.h"
a6278b88 26#include "bus-label.h"
3ffd4af2
LP
27#include "bus-util.h"
28#include "fd-util.h"
118ecf32 29#include "logind-session-device.h"
3ffd4af2
LP
30#include "logind-session.h"
31#include "logind.h"
32#include "strv.h"
33#include "util.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;
5cb14b37 166 dual_timestamp t = DUAL_TIMESTAMP_NULL;
a185c5aa 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
19070062 183int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
184 Session *s = userdata;
185 int r;
0604381b 186
cc377381 187 assert(message);
0604381b
LP
188 assert(s);
189
c529695e
LP
190 r = bus_verify_polkit_async(
191 message,
192 CAP_KILL,
193 "org.freedesktop.login1.manage",
403ed0e5 194 NULL,
c529695e
LP
195 false,
196 s->user->uid,
197 &s->manager->polkit_registry,
198 error);
199 if (r < 0)
200 return r;
201 if (r == 0)
202 return 1; /* Will call us back */
203
9bb69af4 204 r = session_stop(s, true);
cc377381 205 if (r < 0)
ebcf1f97 206 return r;
0604381b 207
df2d202e 208 return sd_bus_reply_method_return(message, NULL);
0604381b
LP
209}
210
19070062 211int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
212 Session *s = userdata;
213 int r;
3f49d45a 214
cc377381
LP
215 assert(message);
216 assert(s);
3f49d45a 217
cc377381
LP
218 r = session_activate(s);
219 if (r < 0)
ebcf1f97 220 return r;
3f49d45a 221
df2d202e 222 return sd_bus_reply_method_return(message, NULL);
cc377381
LP
223}
224
19070062 225int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
226 Session *s = userdata;
227 int r;
228
cc377381
LP
229 assert(message);
230 assert(s);
3f49d45a 231
c529695e
LP
232 r = bus_verify_polkit_async(
233 message,
234 CAP_SYS_ADMIN,
235 "org.freedesktop.login1.lock-sessions",
403ed0e5 236 NULL,
c529695e
LP
237 false,
238 s->user->uid,
239 &s->manager->polkit_registry,
240 error);
241 if (r < 0)
242 return r;
243 if (r == 0)
244 return 1; /* Will call us back */
245
246 r = session_send_lock(s, strstr(sd_bus_message_get_member(message), "Lock"));
cc377381 247 if (r < 0)
ebcf1f97 248 return r;
3f49d45a 249
df2d202e 250 return sd_bus_reply_method_return(message, NULL);
3f49d45a
LP
251}
252
19070062 253static int method_set_idle_hint(sd_bus_message *message, void *userdata, sd_bus_error *error) {
5b12334d 254 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
cc377381
LP
255 Session *s = userdata;
256 uid_t uid;
257 int r, b;
d200735e 258
cc377381
LP
259 assert(message);
260 assert(s);
261
262 r = sd_bus_message_read(message, "b", &b);
263 if (r < 0)
ebcf1f97 264 return r;
d200735e 265
05bae4a6 266 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
5b12334d
LP
267 if (r < 0)
268 return r;
269
05bae4a6 270 r = sd_bus_creds_get_euid(creds, &uid);
cc377381 271 if (r < 0)
ebcf1f97 272 return r;
cc377381
LP
273
274 if (uid != 0 && uid != s->user->uid)
2b233285 275 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set idle hint");
cc377381
LP
276
277 session_set_idle_hint(s, b);
3f49d45a 278
df2d202e 279 return sd_bus_reply_method_return(message, NULL);
cc377381
LP
280}
281
19070062 282int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
283 Session *s = userdata;
284 const char *swho;
285 int32_t signo;
286 KillWho who;
bef422ae
LP
287 int r;
288
3f49d45a 289 assert(message);
cc377381 290 assert(s);
3f49d45a 291
cc377381
LP
292 r = sd_bus_message_read(message, "si", &swho, &signo);
293 if (r < 0)
ebcf1f97 294 return r;
cc377381
LP
295
296 if (isempty(swho))
297 who = KILL_ALL;
298 else {
299 who = kill_who_from_string(swho);
300 if (who < 0)
ebcf1f97 301 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
cc377381 302 }
bef422ae 303
cc377381 304 if (signo <= 0 || signo >= _NSIG)
ebcf1f97 305 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
bef422ae 306
c529695e
LP
307 r = bus_verify_polkit_async(
308 message,
309 CAP_KILL,
310 "org.freedesktop.login1.manage",
403ed0e5 311 NULL,
c529695e
LP
312 false,
313 s->user->uid,
314 &s->manager->polkit_registry,
315 error);
316 if (r < 0)
317 return r;
318 if (r == 0)
319 return 1; /* Will call us back */
320
cc377381
LP
321 r = session_kill(s, who, signo);
322 if (r < 0)
ebcf1f97 323 return r;
bef422ae 324
df2d202e 325 return sd_bus_reply_method_return(message, NULL);
cc377381 326}
bef422ae 327
19070062 328static int method_take_control(sd_bus_message *message, void *userdata, sd_bus_error *error) {
5b12334d 329 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
cc377381
LP
330 Session *s = userdata;
331 int r, force;
332 uid_t uid;
bef422ae 333
cc377381
LP
334 assert(message);
335 assert(s);
bef422ae 336
cc377381
LP
337 r = sd_bus_message_read(message, "b", &force);
338 if (r < 0)
ebcf1f97 339 return r;
bef422ae 340
05bae4a6 341 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
5b12334d
LP
342 if (r < 0)
343 return r;
344
05bae4a6 345 r = sd_bus_creds_get_euid(creds, &uid);
cc377381 346 if (r < 0)
ebcf1f97 347 return r;
bef422ae 348
cc377381 349 if (uid != 0 && (force || uid != s->user->uid))
ebcf1f97 350 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
bef422ae 351
cc377381
LP
352 r = session_set_controller(s, sd_bus_message_get_sender(message), force);
353 if (r < 0)
ebcf1f97 354 return r;
bef422ae 355
df2d202e 356 return sd_bus_reply_method_return(message, NULL);
cc377381 357}
bef422ae 358
19070062 359static int method_release_control(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381 360 Session *s = userdata;
bef422ae 361
cc377381
LP
362 assert(message);
363 assert(s);
5bc849fd 364
cc377381 365 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
ebcf1f97 366 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
5bc849fd 367
cc377381 368 session_drop_controller(s);
bef422ae 369
df2d202e 370 return sd_bus_reply_method_return(message, NULL);
cc377381 371}
bef422ae 372
19070062 373static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
374 Session *s = userdata;
375 uint32_t major, minor;
376 SessionDevice *sd;
377 dev_t dev;
378 int r;
de07ab16 379
cc377381
LP
380 assert(message);
381 assert(s);
de07ab16 382
cc377381
LP
383 r = sd_bus_message_read(message, "uu", &major, &minor);
384 if (r < 0)
ebcf1f97 385 return r;
cc377381
LP
386
387 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
ebcf1f97 388 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
cc377381
LP
389
390 dev = makedev(major, minor);
391 sd = hashmap_get(s->devices, &dev);
392 if (sd)
393 /* We don't allow retrieving a device multiple times.
394 * The related ReleaseDevice call is not ref-counted.
395 * The caller should use dup() if it requires more
396 * than one fd (it would be functionally
397 * equivalent). */
ebcf1f97 398 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
cc377381
LP
399
400 r = session_device_new(s, dev, &sd);
401 if (r < 0)
ebcf1f97 402 return r;
de07ab16 403
df2d202e 404 r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
cc377381
LP
405 if (r < 0)
406 session_device_free(sd);
118ecf32 407
cc377381
LP
408 return r;
409}
118ecf32 410
19070062 411static int method_release_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
412 Session *s = userdata;
413 uint32_t major, minor;
414 SessionDevice *sd;
415 dev_t dev;
416 int r;
118ecf32 417
cc377381
LP
418 assert(message);
419 assert(s);
118ecf32 420
cc377381
LP
421 r = sd_bus_message_read(message, "uu", &major, &minor);
422 if (r < 0)
ebcf1f97 423 return r;
118ecf32 424
cc377381 425 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
ebcf1f97 426 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
118ecf32 427
cc377381
LP
428 dev = makedev(major, minor);
429 sd = hashmap_get(s->devices, &dev);
430 if (!sd)
ebcf1f97 431 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
118ecf32 432
cc377381 433 session_device_free(sd);
df2d202e 434 return sd_bus_reply_method_return(message, NULL);
cc377381 435}
118ecf32 436
19070062 437static int method_pause_device_complete(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cc377381
LP
438 Session *s = userdata;
439 uint32_t major, minor;
440 SessionDevice *sd;
441 dev_t dev;
442 int r;
118ecf32 443
cc377381
LP
444 assert(message);
445 assert(s);
bef422ae 446
cc377381
LP
447 r = sd_bus_message_read(message, "uu", &major, &minor);
448 if (r < 0)
ebcf1f97 449 return r;
cc377381
LP
450
451 if (!session_is_controller(s, sd_bus_message_get_sender(message)))
ebcf1f97 452 return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
bef422ae 453
cc377381
LP
454 dev = makedev(major, minor);
455 sd = hashmap_get(s->devices, &dev);
456 if (!sd)
ebcf1f97 457 return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
bef422ae 458
cc377381 459 session_device_complete_pause(sd);
bef422ae 460
df2d202e 461 return sd_bus_reply_method_return(message, NULL);
3f49d45a
LP
462}
463
cc377381
LP
464const sd_bus_vtable session_vtable[] = {
465 SD_BUS_VTABLE_START(0),
466
556089dc
LP
467 SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
468 SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
469 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
470 BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
471 SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
472 SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
473 SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
474 SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
475 SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
476 SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
477 SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
478 SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
a4cd87e9 479 SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
480 SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
481 SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
482 SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
483 SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_CONST),
484 SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
cc377381
LP
485 SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
486 SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
487 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
488 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
489 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
490
c529695e
LP
491 SD_BUS_METHOD("Terminate", NULL, NULL, bus_session_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
492 SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
493 SD_BUS_METHOD("Lock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
494 SD_BUS_METHOD("Unlock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 495 SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
c529695e 496 SD_BUS_METHOD("Kill", "si", NULL, bus_session_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957
LP
497 SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, SD_BUS_VTABLE_UNPRIVILEGED),
498 SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED),
499 SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED),
500 SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED),
501 SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
cc377381
LP
502
503 SD_BUS_SIGNAL("PauseDevice", "uus", 0),
504 SD_BUS_SIGNAL("ResumeDevice", "uuh", 0),
505 SD_BUS_SIGNAL("Lock", NULL, 0),
506 SD_BUS_SIGNAL("Unlock", NULL, 0),
507
508 SD_BUS_VTABLE_END
509};
3f49d45a 510
f00c3121 511int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
3f49d45a 512 Manager *m = userdata;
cc377381 513 Session *session;
927b1649 514 int r;
3f49d45a 515
cc377381
LP
516 assert(bus);
517 assert(path);
518 assert(interface);
519 assert(found);
520 assert(m);
3f49d45a 521
927b1649 522 if (streq(path, "/org/freedesktop/login1/session/self")) {
5b12334d 523 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
927b1649 524 sd_bus_message *message;
309a29df 525 const char *name;
3f49d45a 526
19befb2d 527 message = sd_bus_get_current_message(bus);
927b1649
LP
528 if (!message)
529 return 0;
530
309a29df 531 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
927b1649 532 if (r < 0)
5b12334d
LP
533 return r;
534
309a29df 535 r = sd_bus_creds_get_session(creds, &name);
5b12334d
LP
536 if (r < 0)
537 return r;
927b1649 538
309a29df 539 session = hashmap_get(m->sessions, name);
927b1649
LP
540 } else {
541 _cleanup_free_ char *e = NULL;
542 const char *p;
3f49d45a 543
927b1649
LP
544 p = startswith(path, "/org/freedesktop/login1/session/");
545 if (!p)
546 return 0;
547
a6278b88 548 e = bus_label_unescape(p);
927b1649
LP
549 if (!e)
550 return -ENOMEM;
551
552 session = hashmap_get(m->sessions, e);
927b1649 553 }
3f49d45a 554
309a29df
LP
555 if (!session)
556 return 0;
557
cc377381
LP
558 *found = session;
559 return 1;
3f49d45a
LP
560}
561
3f49d45a 562char *session_bus_path(Session *s) {
9444b1f2 563 _cleanup_free_ char *t = NULL;
3f49d45a
LP
564
565 assert(s);
566
a6278b88 567 t = bus_label_escape(s->id);
3f49d45a
LP
568 if (!t)
569 return NULL;
570
4654e558 571 return strappend("/org/freedesktop/login1/session/", t);
3f49d45a 572}
da119395 573
f00c3121 574int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
cc377381 575 _cleanup_strv_free_ char **l = NULL;
ca56b0a6 576 sd_bus_message *message;
cc377381
LP
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
6e18964d
ZJS
593 r = strv_consume(&l, p);
594 if (r < 0)
cc377381 595 return r;
cc377381
LP
596 }
597
ca56b0a6
DH
598 message = sd_bus_get_current_message(bus);
599 if (message) {
600 _cleanup_bus_creds_unref_ 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 }
b298e984 616
cc377381
LP
617 *nodes = l;
618 l = NULL;
619
620 return 1;
621}
622
da119395 623int session_send_signal(Session *s, bool new_session) {
ce0fc5f5 624 _cleanup_free_ char *p = NULL;
da119395
LP
625
626 assert(s);
627
da119395
LP
628 p = session_bus_path(s);
629 if (!p)
4654e558 630 return -ENOMEM;
da119395 631
cc377381
LP
632 return sd_bus_emit_signal(
633 s->manager->bus,
634 "/org/freedesktop/login1",
635 "org.freedesktop.login1.Manager",
636 new_session ? "SessionNew" : "SessionRemoved",
637 "so", s->id, p);
da119395 638}
9418f147 639
cc377381 640int session_send_changed(Session *s, const char *properties, ...) {
ce0fc5f5 641 _cleanup_free_ char *p = NULL;
cc377381 642 char **l;
9418f147
LP
643
644 assert(s);
645
ed18b08b
LP
646 if (!s->started)
647 return 0;
648
9418f147
LP
649 p = session_bus_path(s);
650 if (!p)
651 return -ENOMEM;
652
cc377381 653 l = strv_from_stdarg_alloca(properties);
9418f147 654
cc377381 655 return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Session", l);
9418f147 656}
88e3dc90
LP
657
658int session_send_lock(Session *s, bool lock) {
ce0fc5f5 659 _cleanup_free_ char *p = NULL;
88e3dc90
LP
660
661 assert(s);
662
663 p = session_bus_path(s);
664 if (!p)
665 return -ENOMEM;
666
cc377381
LP
667 return sd_bus_emit_signal(
668 s->manager->bus,
669 p,
670 "org.freedesktop.login1.Session",
671 lock ? "Lock" : "Unlock",
672 NULL);
88e3dc90 673}
7ba64386
LP
674
675int session_send_lock_all(Manager *m, bool lock) {
676 Session *session;
677 Iterator i;
678 int r = 0;
679
680 assert(m);
681
682 HASHMAP_FOREACH(session, m->sessions, i) {
683 int k;
684
685 k = session_send_lock(session, lock);
686 if (k < 0)
687 r = k;
688 }
689
690 return r;
691}
fb6becb4 692
cc377381
LP
693int session_send_create_reply(Session *s, sd_bus_error *error) {
694 _cleanup_bus_message_unref_ sd_bus_message *c = NULL;
695 _cleanup_close_ int fifo_fd = -1;
696 _cleanup_free_ char *p = NULL;
fb6becb4
LP
697
698 assert(s);
699
dd9b67aa
LP
700 /* This is called after the session scope and the user service
701 * were successfully created, and finishes where
702 * bus_manager_create_session() left off. */
cba38758 703
cc377381
LP
704 if (!s->create_message)
705 return 0;
fb6becb4 706
dd9b67aa
LP
707 if (!sd_bus_error_is_set(error) && (s->scope_job || s->user->service_job))
708 return 0;
709
cc377381
LP
710 c = s->create_message;
711 s->create_message = NULL;
fb6becb4 712
cc377381 713 if (error)
df2d202e 714 return sd_bus_reply_method_error(c, error);
fb6becb4 715
cc377381
LP
716 fifo_fd = session_create_fifo(s);
717 if (fifo_fd < 0)
718 return fifo_fd;
fb6becb4 719
38fdcbed
TA
720 /* Update the session state file before we notify the client
721 * about the result. */
722 session_save(s);
723
cc377381
LP
724 p = session_bus_path(s);
725 if (!p)
726 return -ENOMEM;
fb6becb4 727
5a330cda 728 log_debug("Sending reply about created session: "
236af516
DH
729 "id=%s object_path=%s uid=%u runtime_path=%s "
730 "session_fd=%d seat=%s vtnr=%u",
5a330cda
ZJS
731 s->id,
732 p,
236af516 733 (uint32_t) s->user->uid,
5a330cda
ZJS
734 s->user->runtime_path,
735 fifo_fd,
736 s->seat ? s->seat->id : "",
737 (uint32_t) s->vtnr);
738
cc377381 739 return sd_bus_reply_method_return(
baae0358 740 c, "soshusub",
cc377381
LP
741 s->id,
742 p,
743 s->user->runtime_path,
744 fifo_fd,
baae0358 745 (uint32_t) s->user->uid,
cc377381
LP
746 s->seat ? s->seat->id : "",
747 (uint32_t) s->vtnr,
748 false);
fb6becb4 749}