]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-control.c
sd-bus: rename sd_bus_get_owner_uid(), sd_bus_get_owner_machine_id() and sd_bus_get_p...
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-control.c
CommitLineData
de1c301e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
75722f1d
LP
22#ifdef HAVE_VALGRIND_MEMCHECK_H
23#include <valgrind/memcheck.h>
24#endif
25
de1c301e
LP
26#include <stddef.h>
27#include <errno.h>
28
29#include "strv.h"
de1c301e
LP
30#include "sd-bus.h"
31#include "bus-internal.h"
32#include "bus-message.h"
392d5b37 33#include "bus-control.h"
c7819669 34#include "bus-bloom.h"
40ca29a1 35#include "bus-util.h"
751bc6ac 36#include "cgroup-util.h"
de1c301e 37
d9f644e2 38_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
20902f3e
LP
39 int r;
40
9bb058a1
LS
41 assert_return(bus, -EINVAL);
42 assert_return(unique, -EINVAL);
43 assert_return(!bus_pid_changed(bus), -ECHILD);
20902f3e
LP
44
45 r = bus_ensure_running(bus);
46 if (r < 0)
47 return r;
de1c301e 48
20902f3e
LP
49 *unique = bus->unique_name;
50 return 0;
de1c301e
LP
51}
52
29a07cdb 53static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
e7176abb 54 struct kdbus_cmd_name *n;
45fd5e4d 55 size_t size, l;
de1c301e
LP
56 int r;
57
e7176abb
LP
58 assert(bus);
59 assert(name);
f08838da 60
f0c5e28e
DM
61 l = strlen(name) + 1;
62 size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
7f3d3ba1 63 n = alloca0_align(size, 8);
45fd5e4d 64 n->size = size;
e7176abb 65 kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
f8c24252 66
f0c5e28e 67 n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
f8c24252 68 n->items[0].type = KDBUS_ITEM_NAME;
f0c5e28e 69 memcpy(n->items[0].str, name, l);
f08838da 70
75722f1d 71#ifdef HAVE_VALGRIND_MEMCHECK_H
e7176abb 72 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
75722f1d
LP
73#endif
74
e7176abb
LP
75 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
76 if (r < 0)
77 return -errno;
f08838da 78
e7176abb
LP
79 if (n->flags & KDBUS_NAME_IN_QUEUE)
80 return 0;
f08838da 81
e7176abb 82 return 1;
de1c301e
LP
83}
84
29a07cdb 85static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
d4100e24 86 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
29a07cdb 87 uint32_t ret, param = 0;
de1c301e
LP
88 int r;
89
e7176abb
LP
90 assert(bus);
91 assert(name);
92
29a07cdb
LP
93 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
94 param |= BUS_NAME_ALLOW_REPLACEMENT;
95 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
96 param |= BUS_NAME_REPLACE_EXISTING;
97 if (!(flags & SD_BUS_NAME_QUEUE))
98 param |= BUS_NAME_DO_NOT_QUEUE;
99
e7176abb
LP
100 r = sd_bus_call_method(
101 bus,
102 "org.freedesktop.DBus",
cd789fdf 103 "/org/freedesktop/DBus",
e7176abb
LP
104 "org.freedesktop.DBus",
105 "RequestName",
106 NULL,
107 &reply,
108 "su",
109 name,
29a07cdb 110 param);
e7176abb
LP
111 if (r < 0)
112 return r;
113
114 r = sd_bus_message_read(reply, "u", &ret);
115 if (r < 0)
116 return r;
117
0461f8cd 118 if (ret == BUS_NAME_ALREADY_OWNER)
e7176abb 119 return -EALREADY;
0461f8cd 120 else if (ret == BUS_NAME_EXISTS)
e7176abb 121 return -EEXIST;
0461f8cd 122 else if (ret == BUS_NAME_IN_QUEUE)
e7176abb 123 return 0;
c0a09132
LP
124 else if (ret == BUS_NAME_PRIMARY_OWNER)
125 return 1;
e7176abb 126
c0a09132 127 return -EIO;
e7176abb
LP
128}
129
29a07cdb 130_public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
9bb058a1
LS
131 assert_return(bus, -EINVAL);
132 assert_return(name, -EINVAL);
133 assert_return(bus->bus_client, -EINVAL);
9bb058a1 134 assert_return(!bus_pid_changed(bus), -ECHILD);
29a07cdb 135 assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
45fd5e4d
LP
136 assert_return(service_name_is_valid(name), -EINVAL);
137 assert_return(name[0] != ':', -EINVAL);
de1c301e 138
a3d59cd1
LP
139 if (!BUS_IS_OPEN(bus->state))
140 return -ENOTCONN;
141
e7176abb
LP
142 if (bus->is_kernel)
143 return bus_request_name_kernel(bus, name, flags);
144 else
145 return bus_request_name_dbus1(bus, name, flags);
146}
f08838da 147
e7176abb
LP
148static int bus_release_name_kernel(sd_bus *bus, const char *name) {
149 struct kdbus_cmd_name *n;
f8c24252 150 size_t size, l;
e7176abb 151 int r;
f08838da 152
e7176abb
LP
153 assert(bus);
154 assert(name);
f08838da 155
f0c5e28e
DM
156 l = strlen(name) + 1;
157 size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
f8c24252
DM
158 n = alloca0_align(size, 8);
159 n->size = size;
160
f0c5e28e 161 n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
f8c24252 162 n->items[0].type = KDBUS_ITEM_NAME;
f0c5e28e 163 memcpy(n->items[0].str, name, l);
f08838da 164
e7176abb
LP
165#ifdef HAVE_VALGRIND_MEMCHECK_H
166 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
167#endif
168 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
169 if (r < 0)
170 return -errno;
de1c301e 171
4a3e79e1 172 return 0;
de1c301e
LP
173}
174
e7176abb
LP
175static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
176 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
177 uint32_t ret;
de1c301e
LP
178 int r;
179
e7176abb
LP
180 assert(bus);
181 assert(name);
182
183 r = sd_bus_call_method(
184 bus,
185 "org.freedesktop.DBus",
cd789fdf 186 "/org/freedesktop/DBus",
e7176abb
LP
187 "org.freedesktop.DBus",
188 "ReleaseName",
189 NULL,
190 &reply,
191 "s",
192 name);
193 if (r < 0)
194 return r;
195
196 r = sd_bus_message_read(reply, "u", &ret);
197 if (r < 0)
198 return r;
0461f8cd 199 if (ret == BUS_NAME_NON_EXISTENT)
043ccd83 200 return -ESRCH;
0461f8cd 201 if (ret == BUS_NAME_NOT_OWNER)
043ccd83 202 return -EADDRINUSE;
0461f8cd 203 if (ret == BUS_NAME_RELEASED)
e7176abb
LP
204 return 0;
205
206 return -EINVAL;
207}
208
209_public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
9bb058a1 210 assert_return(bus, -EINVAL);
e7176abb
LP
211 assert_return(name, -EINVAL);
212 assert_return(bus->bus_client, -EINVAL);
9bb058a1 213 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d
LP
214 assert_return(service_name_is_valid(name), -EINVAL);
215 assert_return(name[0] != ':', -EINVAL);
de1c301e 216
a3d59cd1
LP
217 if (!BUS_IS_OPEN(bus->state))
218 return -ENOTCONN;
219
e7176abb
LP
220 if (bus->is_kernel)
221 return bus_release_name_kernel(bus, name);
222 else
223 return bus_release_name_dbus1(bus, name);
224}
de1c301e 225
d663f1b1
DM
226static int kernel_cmd_free(sd_bus *bus, uint64_t offset)
227{
228 struct kdbus_cmd_free cmd;
229 int r;
230
231 assert(bus);
232
233 cmd.flags = 0;
234 cmd.offset = offset;
235
236 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd);
237 if (r < 0)
238 return -errno;
239
240 return 0;
241}
242
71f2ab46
LP
243static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
244 struct kdbus_cmd_name_list cmd = {};
e7176abb 245 struct kdbus_name_list *name_list;
bc75205c 246 struct kdbus_name_info *name;
7f7030e2 247 uint64_t previous_id = 0;
e7176abb 248 int r;
b1473984 249
71f2ab46 250 /* Caller will free half-constructed list on failure... */
b1473984 251
71f2ab46 252 cmd.flags = flags;
b1473984 253
71f2ab46 254 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
e7176abb
LP
255 if (r < 0)
256 return -errno;
b1473984 257
71f2ab46 258 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
b6bd53c1 259
a8d4cac5 260 KDBUS_ITEM_FOREACH(name, name_list, names) {
b6bd53c1 261
f8c24252
DM
262 struct kdbus_item *item;
263 const char *entry_name = NULL;
264
98531b57 265 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
71f2ab46
LP
266 char *n;
267
659b937e
LS
268 if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
269 r = -ENOMEM;
270 goto fail;
271 }
71f2ab46 272
6e18964d
ZJS
273 r = strv_consume(x, n);
274 if (r < 0)
659b937e 275 goto fail;
7f7030e2 276
98531b57 277 previous_id = name->owner_id;
71f2ab46 278 }
b1473984 279
f8c24252
DM
280 KDBUS_ITEM_FOREACH(item, name, items)
281 if (item->type == KDBUS_ITEM_NAME)
282 entry_name = item->str;
283
284 if (entry_name && service_name_is_valid(entry_name)) {
285 r = strv_extend(x, entry_name);
659b937e
LS
286 if (r < 0) {
287 r = -ENOMEM;
288 goto fail;
289 }
7f7030e2 290 }
89ffcd2a 291 }
de1c301e 292
659b937e 293 r = 0;
e7176abb 294
659b937e
LS
295fail:
296 kernel_cmd_free(bus, cmd.offset);
297 return r;
de1c301e
LP
298}
299
71f2ab46
LP
300static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
301 _cleanup_strv_free_ char **x = NULL, **y = NULL;
de1c301e
LP
302 int r;
303
71f2ab46
LP
304 if (acquired) {
305 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
306 if (r < 0)
307 return r;
308 }
a4297f08 309
71f2ab46 310 if (activatable) {
07442eff 311 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
71f2ab46
LP
312 if (r < 0)
313 return r;
5b12334d 314
71f2ab46
LP
315 *activatable = y;
316 y = NULL;
5b12334d 317 }
de1c301e 318
71f2ab46
LP
319 if (acquired) {
320 *acquired = x;
321 x = NULL;
322 }
323
324 return 0;
325}
326
327static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
328 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
329 _cleanup_strv_free_ char **x = NULL, **y = NULL;
330 int r;
331
332 if (acquired) {
333 r = sd_bus_call_method(
334 bus,
335 "org.freedesktop.DBus",
cd789fdf 336 "/org/freedesktop/DBus",
71f2ab46
LP
337 "org.freedesktop.DBus",
338 "ListNames",
339 NULL,
340 &reply,
341 NULL);
342 if (r < 0)
343 return r;
344
345 r = sd_bus_message_read_strv(reply, &x);
346 if (r < 0)
347 return r;
348
349 reply = sd_bus_message_unref(reply);
350 }
351
352 if (activatable) {
353 r = sd_bus_call_method(
354 bus,
355 "org.freedesktop.DBus",
cd789fdf 356 "/org/freedesktop/DBus",
71f2ab46
LP
357 "org.freedesktop.DBus",
358 "ListActivatableNames",
359 NULL,
360 &reply,
361 NULL);
362 if (r < 0)
363 return r;
364
365 r = sd_bus_message_read_strv(reply, &y);
366 if (r < 0)
367 return r;
368
369 *activatable = y;
370 y = NULL;
371 }
372
373 if (acquired) {
374 *acquired = x;
375 x = NULL;
a4297f08 376 }
de1c301e 377
49b832c5
LP
378 return 0;
379}
380
71f2ab46 381_public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
e7176abb 382 assert_return(bus, -EINVAL);
71f2ab46 383 assert_return(acquired || activatable, -EINVAL);
e7176abb
LP
384 assert_return(!bus_pid_changed(bus), -ECHILD);
385
a3d59cd1
LP
386 if (!BUS_IS_OPEN(bus->state))
387 return -ENOTCONN;
388
e7176abb 389 if (bus->is_kernel)
71f2ab46 390 return bus_list_names_kernel(bus, acquired, activatable);
e7176abb 391 else
71f2ab46 392 return bus_list_names_dbus1(bus, acquired, activatable);
e7176abb
LP
393}
394
370d7a9c
DM
395static int bus_populate_creds_from_items(sd_bus *bus,
396 struct kdbus_info *info,
397 uint64_t mask,
398 sd_bus_creds *c) {
49b832c5 399
49b832c5 400 struct kdbus_item *item;
370d7a9c 401 uint64_t m;
49b832c5
LP
402 int r;
403
370d7a9c 404 KDBUS_ITEM_FOREACH(item, info, items) {
49b832c5
LP
405
406 switch (item->type) {
407
408 case KDBUS_ITEM_CREDS:
2dc9970b 409 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
49b832c5
LP
410
411 if (m) {
693eb9a2
LP
412 c->uid = (uid_t) item->creds.uid;
413 c->pid = (pid_t) item->creds.pid;
414 c->gid = (gid_t) item->creds.gid;
2dc9970b
LP
415 c->mask |= m;
416 }
417
418 if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
693eb9a2 419 c->tid = (pid_t) item->creds.tid;
2dc9970b
LP
420 c->mask |= SD_BUS_CREDS_TID;
421 }
422
423 if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
49b832c5 424 c->pid_starttime = item->creds.starttime;
2dc9970b 425 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
49b832c5 426 }
2dc9970b 427
49b832c5
LP
428 break;
429
430 case KDBUS_ITEM_PID_COMM:
431 if (mask & SD_BUS_CREDS_COMM) {
432 c->comm = strdup(item->str);
370d7a9c
DM
433 if (!c->comm)
434 return -ENOMEM;
49b832c5
LP
435
436 c->mask |= SD_BUS_CREDS_COMM;
437 }
438 break;
439
440 case KDBUS_ITEM_TID_COMM:
441 if (mask & SD_BUS_CREDS_TID_COMM) {
442 c->tid_comm = strdup(item->str);
370d7a9c
DM
443 if (!c->tid_comm)
444 return -ENOMEM;
49b832c5
LP
445
446 c->mask |= SD_BUS_CREDS_TID_COMM;
447 }
448 break;
449
450 case KDBUS_ITEM_EXE:
451 if (mask & SD_BUS_CREDS_EXE) {
452 c->exe = strdup(item->str);
370d7a9c
DM
453 if (!c->exe)
454 return -ENOMEM;
49b832c5
LP
455
456 c->mask |= SD_BUS_CREDS_EXE;
457 }
458 break;
459
460 case KDBUS_ITEM_CMDLINE:
461 if (mask & SD_BUS_CREDS_CMDLINE) {
a8d4cac5 462 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
49b832c5 463 c->cmdline = memdup(item->data, c->cmdline_size);
370d7a9c
DM
464 if (!c->cmdline)
465 return -ENOMEM;
49b832c5 466
e7176abb
LP
467 c->mask |= SD_BUS_CREDS_CMDLINE;
468 }
469 break;
470
471 case KDBUS_ITEM_CGROUP:
472 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
473 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
474 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
475
476 if (m) {
477 c->cgroup = strdup(item->str);
370d7a9c
DM
478 if (!c->cgroup)
479 return -ENOMEM;
e7176abb 480
fe3f22d1
DK
481 r = bus_get_root_path(bus);
482 if (r < 0)
370d7a9c 483 return r;
751bc6ac
LP
484
485 c->cgroup_root = strdup(bus->cgroup_root);
370d7a9c
DM
486 if (!c->cgroup_root)
487 return -ENOMEM;
751bc6ac 488
e7176abb
LP
489 c->mask |= m;
490 }
491 break;
492
493 case KDBUS_ITEM_CAPS:
494 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
495 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
496
497 if (m) {
a8d4cac5 498 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
e7176abb 499 c->capability = memdup(item->data, c->capability_size);
370d7a9c
DM
500 if (!c->capability)
501 return -ENOMEM;
e7176abb
LP
502
503 c->mask |= m;
504 }
505 break;
506
507 case KDBUS_ITEM_SECLABEL:
508 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
509 c->label = strdup(item->str);
370d7a9c
DM
510 if (!c->label)
511 return -ENOMEM;
e7176abb
LP
512
513 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
514 }
515 break;
516
517 case KDBUS_ITEM_AUDIT:
518 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
519
520 if (m) {
521 c->audit_session_id = item->audit.sessionid;
522 c->audit_login_uid = item->audit.loginuid;
523 c->mask |= m;
524 }
525 break;
526
65dae17a 527 case KDBUS_ITEM_NAME:
45fd5e4d 528 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
65dae17a
KS
529 r = strv_extend(&c->well_known_names, item->name.name);
530 if (r < 0)
370d7a9c 531 return r;
e7176abb
LP
532
533 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
534 }
535 break;
cccb0b2c
LP
536
537 case KDBUS_ITEM_CONN_NAME:
538 if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
539 c->conn_name = strdup(item->str);
370d7a9c
DM
540 if (!c->conn_name)
541 return -ENOMEM;
cccb0b2c
LP
542
543 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
544 }
545 break;
e7176abb
LP
546 }
547 }
548
370d7a9c
DM
549 return 0;
550}
551
056f95d0 552static int bus_get_name_creds_kdbus(
370d7a9c
DM
553 sd_bus *bus,
554 const char *name,
555 uint64_t mask,
556 sd_bus_creds **creds) {
557
558 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
559 struct kdbus_cmd_info *cmd;
560 struct kdbus_info *conn_info;
561 size_t size, l;
562 uint64_t id;
563 int r;
564
565 r = bus_kernel_parse_unique_name(name, &id);
566 if (r < 0)
567 return r;
568 if (r > 0) {
569 size = offsetof(struct kdbus_cmd_info, items);
570 cmd = alloca0_align(size, 8);
571 cmd->id = id;
572 } else {
573 l = strlen(name) + 1;
574 size = offsetof(struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(l);
575 cmd = alloca0_align(size, 8);
576 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
577 cmd->items[0].type = KDBUS_ITEM_NAME;
578 memcpy(cmd->items[0].str, name, l);
579 }
580
581 cmd->size = size;
582 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
583
584 r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
585 if (r < 0)
586 return -errno;
587
588 conn_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
589
590 /* Non-activated names are considered not available */
591 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR) {
592 if (name[0] == ':')
593 r = -ENXIO;
594 else
595 r = -ESRCH;
596 goto fail;
597 }
598
599 c = bus_creds_new();
600 if (!c) {
601 r = -ENOMEM;
602 goto fail;
603 }
604
605 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
606 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0) {
607 r = -ENOMEM;
608 goto fail;
609 }
610
611 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
612 }
613
614 r = bus_populate_creds_from_items(bus, conn_info, mask, c);
615 if (r < 0)
616 goto fail;
617
e7176abb
LP
618 if (creds) {
619 *creds = c;
620 c = NULL;
621 }
622
623 r = 0;
624
625fail:
d663f1b1 626 kernel_cmd_free(bus, cmd->offset);
e7176abb
LP
627 return r;
628}
629
056f95d0 630static int bus_get_name_creds_dbus1(
e7176abb
LP
631 sd_bus *bus,
632 const char *name,
633 uint64_t mask,
634 sd_bus_creds **creds) {
635
636 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
637 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
638 const char *unique = NULL;
639 pid_t pid = 0;
640 int r;
641
642 /* Only query the owner if the caller wants to know it or if
643 * the caller just wants to check whether a name exists */
644 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
645 r = sd_bus_call_method(
646 bus,
647 "org.freedesktop.DBus",
cd789fdf 648 "/org/freedesktop/DBus",
e7176abb
LP
649 "org.freedesktop.DBus",
650 "GetNameOwner",
651 NULL,
652 &reply_unique,
653 "s",
654 name);
655 if (r < 0)
656 return r;
657
658 r = sd_bus_message_read(reply_unique, "s", &unique);
659 if (r < 0)
660 return r;
661 }
662
663 if (mask != 0) {
664 c = bus_creds_new();
665 if (!c)
666 return -ENOMEM;
667
668 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
669 c->unique_name = strdup(unique);
670 if (!c->unique_name)
671 return -ENOMEM;
672
673 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
674 }
49b832c5 675
e7176abb
LP
676 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
677 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
678 SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
679 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
680 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
681 uint32_t u;
49b832c5 682
e7176abb
LP
683 r = sd_bus_call_method(
684 bus,
685 "org.freedesktop.DBus",
cd789fdf 686 "/org/freedesktop/DBus",
e7176abb
LP
687 "org.freedesktop.DBus",
688 "GetConnectionUnixProcessID",
689 NULL,
690 &reply,
691 "s",
692 unique ? unique : name);
693 if (r < 0)
694 return r;
49b832c5 695
e7176abb
LP
696 r = sd_bus_message_read(reply, "u", &u);
697 if (r < 0)
698 return r;
699
700 pid = u;
701 if (mask & SD_BUS_CREDS_PID) {
702 c->pid = u;
703 c->mask |= SD_BUS_CREDS_PID;
49b832c5 704 }
49b832c5 705
e7176abb
LP
706 reply = sd_bus_message_unref(reply);
707 }
49b832c5 708
e7176abb
LP
709 if (mask & SD_BUS_CREDS_UID) {
710 uint32_t u;
49b832c5 711
e7176abb
LP
712 r = sd_bus_call_method(
713 bus,
714 "org.freedesktop.DBus",
cd789fdf 715 "/org/freedesktop/DBus",
e7176abb
LP
716 "org.freedesktop.DBus",
717 "GetConnectionUnixUser",
718 NULL,
719 &reply,
720 "s",
721 unique ? unique : name);
722 if (r < 0)
723 return r;
49b832c5 724
e7176abb
LP
725 r = sd_bus_message_read(reply, "u", &u);
726 if (r < 0)
727 return r;
49b832c5 728
e7176abb
LP
729 c->uid = u;
730 c->mask |= SD_BUS_CREDS_UID;
49b832c5 731
e7176abb
LP
732 reply = sd_bus_message_unref(reply);
733 }
49b832c5 734
e7176abb 735 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
39883f62
LP
736 const void *p = NULL;
737 size_t sz = 0;
49b832c5 738
e7176abb
LP
739 r = sd_bus_call_method(
740 bus,
741 "org.freedesktop.DBus",
cd789fdf 742 "/org/freedesktop/DBus",
e7176abb
LP
743 "org.freedesktop.DBus",
744 "GetConnectionSELinuxSecurityContext",
745 NULL,
746 &reply,
747 "s",
748 unique ? unique : name);
749 if (r < 0)
750 return r;
49b832c5 751
e7176abb
LP
752 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
753 if (r < 0)
754 return r;
755
756 c->label = strndup(p, sz);
757 if (!c->label)
758 return -ENOMEM;
759
760 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
49b832c5 761 }
e7176abb
LP
762
763 r = bus_creds_add_more(c, mask, pid, 0);
764 if (r < 0)
765 return r;
49b832c5
LP
766 }
767
768 if (creds) {
769 *creds = c;
770 c = NULL;
771 }
772
e7176abb 773 return 0;
49b832c5
LP
774}
775
056f95d0 776_public_ int sd_bus_get_name_creds(
49b832c5
LP
777 sd_bus *bus,
778 const char *name,
779 uint64_t mask,
780 sd_bus_creds **creds) {
781
782 assert_return(bus, -EINVAL);
783 assert_return(name, -EINVAL);
95c4fe82 784 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
49b832c5 785 assert_return(mask == 0 || creds, -EINVAL);
49b832c5 786 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d 787 assert_return(service_name_is_valid(name), -EINVAL);
0721804f 788 assert_return(bus->bus_client, -ENODATA);
49b832c5 789
a3d59cd1
LP
790 if (!BUS_IS_OPEN(bus->state))
791 return -ENOTCONN;
792
49b832c5 793 if (bus->is_kernel)
056f95d0 794 return bus_get_name_creds_kdbus(bus, name, mask, creds);
49b832c5 795 else
056f95d0 796 return bus_get_name_creds_dbus1(bus, name, mask, creds);
de1c301e
LP
797}
798
777d7a61
LP
799static int add_name_change_match(sd_bus *bus,
800 uint64_t cookie,
801 const char *name,
802 const char *old_owner,
803 const char *new_owner) {
804
5a884f93 805 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
777d7a61
LP
806 int is_name_id = -1, r;
807 struct kdbus_item *item;
808
809 assert(bus);
810
811 /* If we encounter a match that could match against
812 * NameOwnerChanged messages, then we need to create
73842d62
DM
813 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
814 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
777d7a61
LP
815 * multiple if the match is underspecified.
816 *
817 * The NameOwnerChanged signals take three parameters with
818 * unique or well-known names, but only some forms actually
819 * exist:
820 *
73842d62
DM
821 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
822 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
823 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
824 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
825 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
777d7a61
LP
826 *
827 * For the latter two the two unique names must be identical.
828 *
829 * */
830
831 if (name) {
832 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
833 if (is_name_id < 0)
834 return 0;
835 }
836
33cb6e79 837 if (!isempty(old_owner)) {
777d7a61
LP
838 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
839 if (r < 0)
840 return 0;
841 if (r == 0)
842 return 0;
843 if (is_name_id > 0 && old_owner_id != name_id)
844 return 0;
73842d62
DM
845 } else
846 old_owner_id = KDBUS_MATCH_ID_ANY;
777d7a61 847
33cb6e79 848 if (!isempty(new_owner)) {
777d7a61
LP
849 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
850 if (r < 0)
851 return r;
852 if (r == 0)
853 return 0;
854 if (is_name_id > 0 && new_owner_id != name_id)
855 return 0;
73842d62
DM
856 } else
857 new_owner_id = KDBUS_MATCH_ID_ANY;
777d7a61
LP
858
859 if (is_name_id <= 0) {
006a0b87 860 struct kdbus_cmd_match *m;
777d7a61
LP
861 size_t sz, l;
862
863 /* If the name argument is missing or is a well-known
73842d62 864 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
777d7a61
LP
865 * matches for it */
866
8da4de03 867 l = name ? strlen(name) + 1 : 0;
777d7a61
LP
868
869 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
870 offsetof(struct kdbus_item, name_change) +
871 offsetof(struct kdbus_notify_name_change, name) +
8da4de03 872 l);
777d7a61 873
7f3d3ba1 874 m = alloca0_align(sz, 8);
006a0b87
LP
875 m->size = sz;
876 m->cookie = cookie;
777d7a61 877
006a0b87
LP
878 item = m->items;
879 item->size =
880 offsetof(struct kdbus_item, name_change) +
881 offsetof(struct kdbus_notify_name_change, name) +
8da4de03 882 l;
777d7a61 883
619d7a03
DM
884 item->name_change.old_id.id = old_owner_id;
885 item->name_change.new_id.id = new_owner_id;
777d7a61 886
006a0b87 887 if (name)
dff91e8b 888 memcpy(item->name_change.name, name, l);
777d7a61 889
006a0b87
LP
890 /* If the old name is unset or empty, then
891 * this can match against added names */
892 if (!old_owner || old_owner[0] == 0) {
73842d62 893 item->type = KDBUS_ITEM_NAME_ADD;
777d7a61 894
006a0b87
LP
895 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
896 if (r < 0)
897 return -errno;
898 }
777d7a61 899
006a0b87
LP
900 /* If the new name is unset or empty, then
901 * this can match against removed names */
902 if (!new_owner || new_owner[0] == 0) {
73842d62 903 item->type = KDBUS_ITEM_NAME_REMOVE;
777d7a61 904
006a0b87
LP
905 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
906 if (r < 0)
907 return -errno;
908 }
777d7a61 909
85a0aa17
LP
910 /* The CHANGE match we need in either case, because
911 * what is reported as a name change by the kernel
912 * might just be an owner change between starter and
913 * normal clients. For userspace such a change should
914 * be considered a removal/addition, hence let's
915 * subscribe to this unconditionally. */
916 item->type = KDBUS_ITEM_NAME_CHANGE;
917 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
918 if (r < 0)
919 return -errno;
777d7a61
LP
920 }
921
922 if (is_name_id != 0) {
006a0b87
LP
923 struct kdbus_cmd_match *m;
924 uint64_t sz;
777d7a61
LP
925
926 /* If the name argument is missing or is a unique
73842d62 927 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
777d7a61
LP
928 * for it */
929
006a0b87
LP
930 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
931 offsetof(struct kdbus_item, id_change) +
932 sizeof(struct kdbus_notify_id_change));
777d7a61 933
7f3d3ba1 934 m = alloca0_align(sz, 8);
006a0b87
LP
935 m->size = sz;
936 m->cookie = cookie;
777d7a61 937
006a0b87 938 item = m->items;
dff91e8b
LP
939 item->size =
940 offsetof(struct kdbus_item, id_change) +
941 sizeof(struct kdbus_notify_id_change);
ff2ea192 942 item->id_change.id = name_id;
777d7a61
LP
943
944 /* If the old name is unset or empty, then this can
945 * match against added ids */
946 if (!old_owner || old_owner[0] == 0) {
73842d62 947 item->type = KDBUS_ITEM_ID_ADD;
777d7a61
LP
948
949 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
950 if (r < 0)
951 return -errno;
952 }
953
954 /* If thew new name is unset or empty, then this can
73842d62 955 * match against removed ids */
777d7a61 956 if (!new_owner || new_owner[0] == 0) {
73842d62 957 item->type = KDBUS_ITEM_ID_REMOVE;
777d7a61
LP
958
959 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
960 if (r < 0)
961 return -errno;
962 }
963 }
964
965 return 0;
966}
967
53461b74 968int bus_add_match_internal_kernel(
c7819669 969 sd_bus *bus,
c7819669
LP
970 struct bus_match_component *components,
971 unsigned n_components,
972 uint64_t cookie) {
973
e7176abb
LP
974 struct kdbus_cmd_match *m;
975 struct kdbus_item *item;
b28ff39f 976 uint64_t *bloom;
e7176abb
LP
977 size_t sz;
978 const char *sender = NULL;
979 size_t sender_length = 0;
73842d62 980 uint64_t src_id = KDBUS_MATCH_ID_ANY;
e7176abb
LP
981 bool using_bloom = false;
982 unsigned i;
983 bool matches_name_change = true;
984 const char *name_change_arg[3] = {};
c7819669
LP
985 int r;
986
392d5b37 987 assert(bus);
de1c301e 988
b28ff39f 989 bloom = alloca0(bus->bloom_size);
c7819669 990
85feb8e4 991 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
c7819669 992
e7176abb
LP
993 for (i = 0; i < n_components; i++) {
994 struct bus_match_component *c = &components[i];
777d7a61 995
e7176abb 996 switch (c->type) {
c7819669 997
e7176abb
LP
998 case BUS_MATCH_SENDER:
999 if (!streq(c->value_str, "org.freedesktop.DBus"))
1000 matches_name_change = false;
777d7a61 1001
e7176abb
LP
1002 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
1003 if (r < 0)
1004 return r;
85feb8e4
LP
1005 else if (r > 0)
1006 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
1007 else {
e7176abb
LP
1008 sender = c->value_str;
1009 sender_length = strlen(sender);
1010 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
1011 }
777d7a61 1012
e7176abb 1013 break;
c7819669 1014
e7176abb
LP
1015 case BUS_MATCH_MESSAGE_TYPE:
1016 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
1017 matches_name_change = false;
777d7a61 1018
b28ff39f 1019 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
e7176abb
LP
1020 using_bloom = true;
1021 break;
c7819669 1022
e7176abb
LP
1023 case BUS_MATCH_INTERFACE:
1024 if (!streq(c->value_str, "org.freedesktop.DBus"))
1025 matches_name_change = false;
c7819669 1026
b28ff39f 1027 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
e7176abb
LP
1028 using_bloom = true;
1029 break;
86312ab8 1030
e7176abb
LP
1031 case BUS_MATCH_MEMBER:
1032 if (!streq(c->value_str, "NameOwnerChanged"))
1033 matches_name_change = false;
777d7a61 1034
b28ff39f 1035 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
e7176abb
LP
1036 using_bloom = true;
1037 break;
86312ab8 1038
e7176abb
LP
1039 case BUS_MATCH_PATH:
1040 if (!streq(c->value_str, "/org/freedesktop/DBus"))
1041 matches_name_change = false;
86312ab8 1042
b28ff39f 1043 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
e7176abb
LP
1044 using_bloom = true;
1045 break;
1046
1047 case BUS_MATCH_PATH_NAMESPACE:
1048 if (!streq(c->value_str, "/")) {
b28ff39f 1049 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
86312ab8 1050 using_bloom = true;
86312ab8 1051 }
e7176abb 1052 break;
86312ab8 1053
e7176abb
LP
1054 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1055 char buf[sizeof("arg")-1 + 2 + 1];
86312ab8 1056
e7176abb
LP
1057 if (c->type - BUS_MATCH_ARG < 3)
1058 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
86312ab8 1059
e7176abb 1060 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
b28ff39f 1061 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
e7176abb
LP
1062 using_bloom = true;
1063 break;
c7819669
LP
1064 }
1065
e7176abb
LP
1066 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1067 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
c7819669 1068
e7176abb 1069 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
b28ff39f 1070 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
e7176abb
LP
1071 using_bloom = true;
1072 break;
1073 }
c7819669 1074
e7176abb
LP
1075 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1076 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
c7819669 1077
e7176abb 1078 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
b28ff39f 1079 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
e7176abb
LP
1080 using_bloom = true;
1081 break;
c7819669
LP
1082 }
1083
e7176abb
LP
1084 case BUS_MATCH_DESTINATION:
1085 /* The bloom filter does not include
1086 the destination, since it is only
1087 available for broadcast messages
1088 which do not carry a destination
1089 since they are undirected. */
1090 break;
1091
1092 case BUS_MATCH_ROOT:
1093 case BUS_MATCH_VALUE:
1094 case BUS_MATCH_LEAF:
1095 case _BUS_MATCH_NODE_TYPE_MAX:
1096 case _BUS_MATCH_NODE_TYPE_INVALID:
1097 assert_not_reached("Invalid match type?");
c7819669 1098 }
e7176abb
LP
1099 }
1100
1101 if (using_bloom)
b28ff39f 1102 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
e7176abb 1103
7f3d3ba1 1104 m = alloca0_align(sz, 8);
e7176abb
LP
1105 m->size = sz;
1106 m->cookie = cookie;
e7176abb
LP
1107
1108 item = m->items;
1109
85feb8e4
LP
1110 if (src_id != KDBUS_MATCH_ID_ANY) {
1111 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1112 item->type = KDBUS_ITEM_ID;
1113 item->id = src_id;
73842d62 1114 item = KDBUS_ITEM_NEXT(item);
85feb8e4
LP
1115 }
1116
1117 if (using_bloom) {
b28ff39f 1118 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
18a28147 1119 item->type = KDBUS_ITEM_BLOOM_MASK;
b28ff39f 1120 memcpy(item->data64, bloom, bus->bloom_size);
85feb8e4 1121 item = KDBUS_ITEM_NEXT(item);
e7176abb
LP
1122 }
1123
1124 if (sender) {
1125 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
73842d62 1126 item->type = KDBUS_ITEM_NAME;
e7176abb
LP
1127 memcpy(item->str, sender, sender_length + 1);
1128 }
1129
1130 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1131 if (r < 0)
1132 return -errno;
1133
1134 if (matches_name_change) {
1135
1136 /* If this match could theoretically match
1137 * NameOwnerChanged messages, we need to
1138 * install a second non-bloom filter explitly
1139 * for it */
c7819669 1140
e7176abb 1141 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
c7819669 1142 if (r < 0)
e7176abb
LP
1143 return r;
1144 }
c7819669 1145
e7176abb
LP
1146 return 0;
1147}
777d7a61 1148
09365592
LP
1149#define internal_match(bus, m) \
1150 ((bus)->hello_flags & KDBUS_HELLO_MONITOR \
1151 ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1152 : (m))
1153
e7176abb
LP
1154static int bus_add_match_internal_dbus1(
1155 sd_bus *bus,
1156 const char *match) {
777d7a61 1157
09365592
LP
1158 const char *e;
1159
e7176abb
LP
1160 assert(bus);
1161 assert(match);
777d7a61 1162
09365592
LP
1163 e = internal_match(bus, match);
1164
e7176abb
LP
1165 return sd_bus_call_method(
1166 bus,
1167 "org.freedesktop.DBus",
cd789fdf 1168 "/org/freedesktop/DBus",
e7176abb
LP
1169 "org.freedesktop.DBus",
1170 "AddMatch",
1171 NULL,
1172 NULL,
1173 "s",
09365592 1174 e);
de1c301e
LP
1175}
1176
e7176abb
LP
1177int bus_add_match_internal(
1178 sd_bus *bus,
1179 const char *match,
1180 struct bus_match_component *components,
1181 unsigned n_components,
1182 uint64_t cookie) {
1183
1184 assert(bus);
e7176abb
LP
1185
1186 if (bus->is_kernel)
26e376bf 1187 return bus_add_match_internal_kernel(bus, components, n_components, cookie);
e7176abb
LP
1188 else
1189 return bus_add_match_internal_dbus1(bus, match);
1190}
1191
53461b74 1192int bus_remove_match_internal_kernel(
c7819669 1193 sd_bus *bus,
c7819669
LP
1194 uint64_t cookie) {
1195
e7176abb 1196 struct kdbus_cmd_match m;
c7819669
LP
1197 int r;
1198
392d5b37 1199 assert(bus);
de1c301e 1200
e7176abb
LP
1201 zero(m);
1202 m.size = offsetof(struct kdbus_cmd_match, items);
1203 m.cookie = cookie;
c7819669 1204
e7176abb
LP
1205 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1206 if (r < 0)
1207 return -errno;
c7819669 1208
e7176abb
LP
1209 return 0;
1210}
c7819669 1211
e7176abb
LP
1212static int bus_remove_match_internal_dbus1(
1213 sd_bus *bus,
1214 const char *match) {
777d7a61 1215
09365592
LP
1216 const char *e;
1217
e7176abb
LP
1218 assert(bus);
1219 assert(match);
1220
09365592
LP
1221 e = internal_match(bus, match);
1222
e7176abb
LP
1223 return sd_bus_call_method(
1224 bus,
1225 "org.freedesktop.DBus",
cd789fdf 1226 "/org/freedesktop/DBus",
e7176abb
LP
1227 "org.freedesktop.DBus",
1228 "RemoveMatch",
1229 NULL,
1230 NULL,
1231 "s",
09365592 1232 e);
e7176abb
LP
1233}
1234
1235int bus_remove_match_internal(
1236 sd_bus *bus,
1237 const char *match,
1238 uint64_t cookie) {
1239
1240 assert(bus);
e7176abb
LP
1241
1242 if (bus->is_kernel)
26e376bf 1243 return bus_remove_match_internal_kernel(bus, cookie);
e7176abb
LP
1244 else
1245 return bus_remove_match_internal_dbus1(bus, match);
de1c301e 1246}
70666185 1247
056f95d0 1248_public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
8d162091 1249 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
70666185
LP
1250 const char *mid;
1251 int r;
1252
8d162091
LP
1253 assert_return(bus, -EINVAL);
1254 assert_return(name, -EINVAL);
1255 assert_return(machine, -EINVAL);
8d162091 1256 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d 1257 assert_return(service_name_is_valid(name), -EINVAL);
70666185 1258
a3d59cd1
LP
1259 if (!BUS_IS_OPEN(bus->state))
1260 return -ENOTCONN;
1261
70666185
LP
1262 if (streq_ptr(name, bus->unique_name))
1263 return sd_id128_get_machine(machine);
1264
8d162091
LP
1265 r = sd_bus_message_new_method_call(
1266 bus,
151b9b96 1267 &m,
8d162091
LP
1268 name,
1269 "/",
1270 "org.freedesktop.DBus.Peer",
151b9b96 1271 "GetMachineId");
8d162091
LP
1272 if (r < 0)
1273 return r;
1274
eee9ec0e 1275 r = sd_bus_message_set_auto_start(m, false);
8d162091
LP
1276 if (r < 0)
1277 return r;
70666185 1278
8d162091 1279 r = sd_bus_call(bus, m, 0, NULL, &reply);
70666185
LP
1280 if (r < 0)
1281 return r;
1282
1283 r = sd_bus_message_read(reply, "s", &mid);
1284 if (r < 0)
1285 return r;
1286
1287 return sd_id128_from_string(mid, machine);
1288}