]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-control.c
sd-bus: when showing brief message info show error name in debug out put too
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-control.c
CommitLineData
de1c301e
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2013 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
75722f1d
LP
20#ifdef HAVE_VALGRIND_MEMCHECK_H
21#include <valgrind/memcheck.h>
22#endif
23
de1c301e 24#include <errno.h>
cf0fbc49 25#include <stddef.h>
de1c301e 26
de1c301e 27#include "sd-bus.h"
07630cea 28
b5efdb8a 29#include "alloc-util.h"
07630cea 30#include "bus-bloom.h"
ee104e11 31#include "bus-control.h"
de1c301e
LP
32#include "bus-internal.h"
33#include "bus-message.h"
057171ef 34#include "bus-util.h"
430f0182 35#include "capability-util.h"
15a5e950 36#include "stdio-util.h"
07630cea
LP
37#include "string-util.h"
38#include "strv.h"
ee104e11 39#include "user-util.h"
de1c301e 40
d9f644e2 41_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
20902f3e
LP
42 int r;
43
9bb058a1
LS
44 assert_return(bus, -EINVAL);
45 assert_return(unique, -EINVAL);
46 assert_return(!bus_pid_changed(bus), -ECHILD);
20902f3e 47
33c62dcb
LP
48 if (!bus->bus_client)
49 return -EINVAL;
50
20902f3e
LP
51 r = bus_ensure_running(bus);
52 if (r < 0)
53 return r;
de1c301e 54
20902f3e
LP
55 *unique = bus->unique_name;
56 return 0;
de1c301e
LP
57}
58
29a07cdb 59static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
4afd3348 60 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
29a07cdb 61 uint32_t ret, param = 0;
de1c301e
LP
62 int r;
63
e7176abb
LP
64 assert(bus);
65 assert(name);
66
29a07cdb
LP
67 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
68 param |= BUS_NAME_ALLOW_REPLACEMENT;
69 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
70 param |= BUS_NAME_REPLACE_EXISTING;
71 if (!(flags & SD_BUS_NAME_QUEUE))
72 param |= BUS_NAME_DO_NOT_QUEUE;
73
e7176abb
LP
74 r = sd_bus_call_method(
75 bus,
76 "org.freedesktop.DBus",
cd789fdf 77 "/org/freedesktop/DBus",
e7176abb
LP
78 "org.freedesktop.DBus",
79 "RequestName",
80 NULL,
81 &reply,
82 "su",
83 name,
29a07cdb 84 param);
e7176abb
LP
85 if (r < 0)
86 return r;
87
88 r = sd_bus_message_read(reply, "u", &ret);
89 if (r < 0)
90 return r;
91
0461f8cd 92 if (ret == BUS_NAME_ALREADY_OWNER)
e7176abb 93 return -EALREADY;
0461f8cd 94 else if (ret == BUS_NAME_EXISTS)
e7176abb 95 return -EEXIST;
0461f8cd 96 else if (ret == BUS_NAME_IN_QUEUE)
e7176abb 97 return 0;
c0a09132
LP
98 else if (ret == BUS_NAME_PRIMARY_OWNER)
99 return 1;
e7176abb 100
c0a09132 101 return -EIO;
e7176abb
LP
102}
103
29a07cdb 104_public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
9bb058a1
LS
105 assert_return(bus, -EINVAL);
106 assert_return(name, -EINVAL);
9bb058a1 107 assert_return(!bus_pid_changed(bus), -ECHILD);
29a07cdb 108 assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
45fd5e4d
LP
109 assert_return(service_name_is_valid(name), -EINVAL);
110 assert_return(name[0] != ':', -EINVAL);
de1c301e 111
33c62dcb
LP
112 if (!bus->bus_client)
113 return -EINVAL;
114
210a6882
LP
115 /* Don't allow requesting the special driver and local names */
116 if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
117 return -EINVAL;
118
a3d59cd1
LP
119 if (!BUS_IS_OPEN(bus->state))
120 return -ENOTCONN;
121
a132bef0 122 return bus_request_name_dbus1(bus, name, flags);
de1c301e
LP
123}
124
e7176abb 125static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
4afd3348 126 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
e7176abb 127 uint32_t ret;
de1c301e
LP
128 int r;
129
e7176abb
LP
130 assert(bus);
131 assert(name);
132
133 r = sd_bus_call_method(
134 bus,
135 "org.freedesktop.DBus",
cd789fdf 136 "/org/freedesktop/DBus",
e7176abb
LP
137 "org.freedesktop.DBus",
138 "ReleaseName",
139 NULL,
140 &reply,
141 "s",
142 name);
143 if (r < 0)
144 return r;
145
146 r = sd_bus_message_read(reply, "u", &ret);
147 if (r < 0)
148 return r;
0461f8cd 149 if (ret == BUS_NAME_NON_EXISTENT)
043ccd83 150 return -ESRCH;
0461f8cd 151 if (ret == BUS_NAME_NOT_OWNER)
043ccd83 152 return -EADDRINUSE;
0461f8cd 153 if (ret == BUS_NAME_RELEASED)
e7176abb
LP
154 return 0;
155
156 return -EINVAL;
157}
158
159_public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
9bb058a1 160 assert_return(bus, -EINVAL);
e7176abb 161 assert_return(name, -EINVAL);
9bb058a1 162 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d
LP
163 assert_return(service_name_is_valid(name), -EINVAL);
164 assert_return(name[0] != ':', -EINVAL);
de1c301e 165
33c62dcb
LP
166 if (!bus->bus_client)
167 return -EINVAL;
168
23539f67 169 /* Don't allow releasing the special driver and local names */
210a6882
LP
170 if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
171 return -EINVAL;
172
a3d59cd1
LP
173 if (!BUS_IS_OPEN(bus->state))
174 return -ENOTCONN;
175
a132bef0 176 return bus_release_name_dbus1(bus, name);
71f2ab46
LP
177}
178
179static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
4afd3348 180 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
71f2ab46
LP
181 _cleanup_strv_free_ char **x = NULL, **y = NULL;
182 int r;
183
184 if (acquired) {
185 r = sd_bus_call_method(
186 bus,
187 "org.freedesktop.DBus",
cd789fdf 188 "/org/freedesktop/DBus",
71f2ab46
LP
189 "org.freedesktop.DBus",
190 "ListNames",
191 NULL,
192 &reply,
193 NULL);
194 if (r < 0)
195 return r;
196
197 r = sd_bus_message_read_strv(reply, &x);
198 if (r < 0)
199 return r;
200
201 reply = sd_bus_message_unref(reply);
202 }
203
204 if (activatable) {
205 r = sd_bus_call_method(
206 bus,
207 "org.freedesktop.DBus",
cd789fdf 208 "/org/freedesktop/DBus",
71f2ab46
LP
209 "org.freedesktop.DBus",
210 "ListActivatableNames",
211 NULL,
212 &reply,
213 NULL);
214 if (r < 0)
215 return r;
216
217 r = sd_bus_message_read_strv(reply, &y);
218 if (r < 0)
219 return r;
220
221 *activatable = y;
222 y = NULL;
223 }
224
225 if (acquired) {
226 *acquired = x;
227 x = NULL;
a4297f08 228 }
de1c301e 229
49b832c5
LP
230 return 0;
231}
232
71f2ab46 233_public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
e7176abb 234 assert_return(bus, -EINVAL);
71f2ab46 235 assert_return(acquired || activatable, -EINVAL);
e7176abb
LP
236 assert_return(!bus_pid_changed(bus), -ECHILD);
237
33c62dcb
LP
238 if (!bus->bus_client)
239 return -EINVAL;
240
a3d59cd1
LP
241 if (!BUS_IS_OPEN(bus->state))
242 return -ENOTCONN;
243
a132bef0 244 return bus_list_names_dbus1(bus, acquired, activatable);
e7176abb
LP
245}
246
056f95d0 247static int bus_get_name_creds_dbus1(
e7176abb
LP
248 sd_bus *bus,
249 const char *name,
250 uint64_t mask,
251 sd_bus_creds **creds) {
252
4afd3348
LP
253 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_unique = NULL, *reply = NULL;
254 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
e7176abb
LP
255 const char *unique = NULL;
256 pid_t pid = 0;
257 int r;
258
259 /* Only query the owner if the caller wants to know it or if
260 * the caller just wants to check whether a name exists */
261 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
262 r = sd_bus_call_method(
263 bus,
264 "org.freedesktop.DBus",
cd789fdf 265 "/org/freedesktop/DBus",
e7176abb
LP
266 "org.freedesktop.DBus",
267 "GetNameOwner",
268 NULL,
269 &reply_unique,
270 "s",
271 name);
272 if (r < 0)
273 return r;
274
275 r = sd_bus_message_read(reply_unique, "s", &unique);
276 if (r < 0)
277 return r;
278 }
279
280 if (mask != 0) {
40f35505
LP
281 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
282 bool need_pid, need_uid, need_selinux, need_separate_calls;
e7176abb
LP
283 c = bus_creds_new();
284 if (!c)
285 return -ENOMEM;
286
287 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
288 c->unique_name = strdup(unique);
289 if (!c->unique_name)
290 return -ENOMEM;
291
292 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
293 }
49b832c5 294
40f35505
LP
295 need_pid = (mask & SD_BUS_CREDS_PID) ||
296 ((mask & SD_BUS_CREDS_AUGMENT) &&
297 (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
298 SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
299 SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
300 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
301 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|
302 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
303 SD_BUS_CREDS_SELINUX_CONTEXT|
304 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
305 need_uid = mask & SD_BUS_CREDS_EUID;
306 need_selinux = mask & SD_BUS_CREDS_SELINUX_CONTEXT;
705a415f 307
40f35505
LP
308 if (need_pid + need_uid + need_selinux > 1) {
309
310 /* If we need more than one of the credentials, then use GetConnectionCredentials() */
49b832c5 311
e7176abb
LP
312 r = sd_bus_call_method(
313 bus,
314 "org.freedesktop.DBus",
cd789fdf 315 "/org/freedesktop/DBus",
e7176abb 316 "org.freedesktop.DBus",
40f35505
LP
317 "GetConnectionCredentials",
318 &error,
e7176abb
LP
319 &reply,
320 "s",
40f35505 321 unique ?: name);
49b832c5 322
40f35505 323 if (r < 0) {
e7176abb 324
40f35505
LP
325 if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
326 return r;
49b832c5 327
40f35505
LP
328 /* If we got an unknown method error, fall back to the invidual calls... */
329 need_separate_calls = true;
330 sd_bus_error_free(&error);
49b832c5 331
40f35505
LP
332 } else {
333 need_separate_calls = false;
49b832c5 334
40f35505
LP
335 r = sd_bus_message_enter_container(reply, 'a', "{sv}");
336 if (r < 0)
337 return r;
49b832c5 338
40f35505
LP
339 for (;;) {
340 const char *m;
49b832c5 341
40f35505
LP
342 r = sd_bus_message_enter_container(reply, 'e', "sv");
343 if (r < 0)
344 return r;
345 if (r == 0)
346 break;
49b832c5 347
40f35505
LP
348 r = sd_bus_message_read(reply, "s", &m);
349 if (r < 0)
350 return r;
49b832c5 351
40f35505
LP
352 if (need_uid && streq(m, "UnixUserID")) {
353 uint32_t u;
49b832c5 354
40f35505
LP
355 r = sd_bus_message_read(reply, "v", "u", &u);
356 if (r < 0)
357 return r;
358
359 c->euid = u;
360 c->mask |= SD_BUS_CREDS_EUID;
361
362 } else if (need_pid && streq(m, "ProcessID")) {
363 uint32_t p;
364
365 r = sd_bus_message_read(reply, "v", "u", &p);
366 if (r < 0)
367 return r;
368
369 pid = p;
370 if (mask & SD_BUS_CREDS_PID) {
371 c->pid = p;
372 c->mask |= SD_BUS_CREDS_PID;
373 }
374
375 } else if (need_selinux && streq(m, "LinuxSecurityLabel")) {
376 const void *p = NULL;
377 size_t sz = 0;
378
379 r = sd_bus_message_enter_container(reply, 'v', "ay");
380 if (r < 0)
381 return r;
382
383 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
384 if (r < 0)
385 return r;
386
387 free(c->label);
388 c->label = strndup(p, sz);
389 if (!c->label)
390 return -ENOMEM;
391
392 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
393
394 r = sd_bus_message_exit_container(reply);
395 if (r < 0)
396 return r;
397 } else {
398 r = sd_bus_message_skip(reply, "v");
399 if (r < 0)
400 return r;
401 }
402
403 r = sd_bus_message_exit_container(reply);
404 if (r < 0)
405 return r;
406 }
407
408 r = sd_bus_message_exit_container(reply);
409 if (r < 0)
359c09b1 410 return r;
40f35505
LP
411
412 if (need_pid && pid == 0)
413 return -EPROTO;
414 }
415
416 } else /* When we only need a single field, then let's use separate calls */
417 need_separate_calls = true;
418
419 if (need_separate_calls) {
420 if (need_pid) {
421 uint32_t u;
422
423 r = sd_bus_call_method(
424 bus,
425 "org.freedesktop.DBus",
426 "/org/freedesktop/DBus",
427 "org.freedesktop.DBus",
428 "GetConnectionUnixProcessID",
429 NULL,
430 &reply,
431 "s",
432 unique ?: name);
359c09b1
LP
433 if (r < 0)
434 return r;
e7176abb 435
40f35505
LP
436 r = sd_bus_message_read(reply, "u", &u);
437 if (r < 0)
438 return r;
e7176abb 439
40f35505
LP
440 pid = u;
441 if (mask & SD_BUS_CREDS_PID) {
442 c->pid = u;
443 c->mask |= SD_BUS_CREDS_PID;
444 }
445
446 reply = sd_bus_message_unref(reply);
447 }
448
449 if (need_uid) {
450 uint32_t u;
451
452 r = sd_bus_call_method(
453 bus,
454 "org.freedesktop.DBus",
455 "/org/freedesktop/DBus",
456 "org.freedesktop.DBus",
457 "GetConnectionUnixUser",
458 NULL,
459 &reply,
460 "s",
461 unique ? unique : name);
462 if (r < 0)
463 return r;
464
465 r = sd_bus_message_read(reply, "u", &u);
466 if (r < 0)
467 return r;
468
469 c->euid = u;
470 c->mask |= SD_BUS_CREDS_EUID;
471
472 reply = sd_bus_message_unref(reply);
473 }
474
475 if (need_selinux) {
476 const void *p = NULL;
477 size_t sz = 0;
478
479 r = sd_bus_call_method(
480 bus,
481 "org.freedesktop.DBus",
482 "/org/freedesktop/DBus",
483 "org.freedesktop.DBus",
484 "GetConnectionSELinuxSecurityContext",
485 &error,
486 &reply,
487 "s",
488 unique ? unique : name);
489 if (r < 0) {
490 if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
491 return r;
492
493 /* no data is fine */
494 } else {
495 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
496 if (r < 0)
497 return r;
498
499 c->label = strndup(p, sz);
500 if (!c->label)
501 return -ENOMEM;
502
503 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
504 }
359c09b1 505 }
49b832c5 506 }
e7176abb
LP
507
508 r = bus_creds_add_more(c, mask, pid, 0);
509 if (r < 0)
510 return r;
49b832c5
LP
511 }
512
513 if (creds) {
514 *creds = c;
515 c = NULL;
516 }
517
e7176abb 518 return 0;
49b832c5
LP
519}
520
056f95d0 521_public_ int sd_bus_get_name_creds(
49b832c5
LP
522 sd_bus *bus,
523 const char *name,
524 uint64_t mask,
525 sd_bus_creds **creds) {
526
527 assert_return(bus, -EINVAL);
528 assert_return(name, -EINVAL);
15411c0c 529 assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
49b832c5 530 assert_return(mask == 0 || creds, -EINVAL);
49b832c5 531 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d 532 assert_return(service_name_is_valid(name), -EINVAL);
33c62dcb
LP
533
534 if (!bus->bus_client)
535 return -EINVAL;
49b832c5 536
694859b5
LP
537 /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not
538 * going to match. */
539 if (!bus->is_local)
540 mask &= ~SD_BUS_CREDS_AUGMENT;
541
210a6882
LP
542 if (streq(name, "org.freedesktop.DBus.Local"))
543 return -EINVAL;
544
51c7d5aa
LP
545 if (streq(name, "org.freedesktop.DBus"))
546 return sd_bus_get_owner_creds(bus, mask, creds);
547
a3d59cd1
LP
548 if (!BUS_IS_OPEN(bus->state))
549 return -ENOTCONN;
550
a132bef0 551 return bus_get_name_creds_dbus1(bus, name, mask, creds);
52cfc037
LP
552}
553
554static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
4afd3348 555 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
52cfc037 556 pid_t pid = 0;
7fc04b12 557 bool do_label;
52cfc037 558 int r;
7fc04b12
LP
559
560 assert(bus);
561
562 do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT);
8f44e3ea 563
c4e6556c
ZJS
564 /* Avoid allocating anything if we have no chance of returning useful data */
565 if (!bus->ucred_valid && !do_label)
8f44e3ea
DM
566 return -ENODATA;
567
568 c = bus_creds_new();
569 if (!c)
570 return -ENOMEM;
571
572 if (bus->ucred_valid) {
52cfc037
LP
573 if (bus->ucred.pid > 0) {
574 pid = c->pid = bus->ucred.pid;
575 c->mask |= SD_BUS_CREDS_PID & mask;
576 }
8f44e3ea 577
fed1e721 578 if (bus->ucred.uid != UID_INVALID) {
05bae4a6
DH
579 c->euid = bus->ucred.uid;
580 c->mask |= SD_BUS_CREDS_EUID & mask;
52cfc037
LP
581 }
582
fed1e721 583 if (bus->ucred.gid != GID_INVALID) {
05bae4a6
DH
584 c->egid = bus->ucred.gid;
585 c->mask |= SD_BUS_CREDS_EGID & mask;
52cfc037 586 }
8f44e3ea
DM
587 }
588
c4e6556c 589 if (do_label) {
8f44e3ea 590 c->label = strdup(bus->label);
505e77ca 591 if (!c->label)
8f44e3ea 592 return -ENOMEM;
8f44e3ea
DM
593
594 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
595 }
596
705a415f
LP
597 r = bus_creds_add_more(c, mask, pid, 0);
598 if (r < 0)
599 return r;
600
8f44e3ea 601 *ret = c;
505e77ca 602 c = NULL;
8f44e3ea
DM
603 return 0;
604}
605
52cfc037
LP
606_public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
607 assert_return(bus, -EINVAL);
15411c0c 608 assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
52cfc037
LP
609 assert_return(ret, -EINVAL);
610 assert_return(!bus_pid_changed(bus), -ECHILD);
611
612 if (!BUS_IS_OPEN(bus->state))
613 return -ENOTCONN;
614
694859b5
LP
615 if (!bus->is_local)
616 mask &= ~SD_BUS_CREDS_AUGMENT;
617
a132bef0 618 return bus_get_owner_creds_dbus1(bus, mask, ret);
e7176abb 619}
777d7a61 620
09365592
LP
621#define internal_match(bus, m) \
622 ((bus)->hello_flags & KDBUS_HELLO_MONITOR \
63c372cb 623 ? (isempty(m) ? "eavesdrop='true'" : strjoina((m), ",eavesdrop='true'")) \
09365592
LP
624 : (m))
625
e7176abb
LP
626static int bus_add_match_internal_dbus1(
627 sd_bus *bus,
628 const char *match) {
777d7a61 629
09365592
LP
630 const char *e;
631
e7176abb
LP
632 assert(bus);
633 assert(match);
777d7a61 634
09365592
LP
635 e = internal_match(bus, match);
636
e7176abb
LP
637 return sd_bus_call_method(
638 bus,
639 "org.freedesktop.DBus",
cd789fdf 640 "/org/freedesktop/DBus",
e7176abb
LP
641 "org.freedesktop.DBus",
642 "AddMatch",
643 NULL,
644 NULL,
645 "s",
09365592 646 e);
de1c301e
LP
647}
648
e7176abb
LP
649int bus_add_match_internal(
650 sd_bus *bus,
651 const char *match,
652 struct bus_match_component *components,
653 unsigned n_components,
654 uint64_t cookie) {
655
656 assert(bus);
e7176abb 657
33c62dcb
LP
658 if (!bus->bus_client)
659 return -EINVAL;
660
a132bef0 661 return bus_add_match_internal_dbus1(bus, match);
e7176abb 662}
c7819669 663
e7176abb
LP
664static int bus_remove_match_internal_dbus1(
665 sd_bus *bus,
666 const char *match) {
777d7a61 667
09365592
LP
668 const char *e;
669
e7176abb
LP
670 assert(bus);
671 assert(match);
672
09365592
LP
673 e = internal_match(bus, match);
674
e7176abb
LP
675 return sd_bus_call_method(
676 bus,
677 "org.freedesktop.DBus",
cd789fdf 678 "/org/freedesktop/DBus",
e7176abb
LP
679 "org.freedesktop.DBus",
680 "RemoveMatch",
681 NULL,
682 NULL,
683 "s",
09365592 684 e);
e7176abb
LP
685}
686
687int bus_remove_match_internal(
688 sd_bus *bus,
689 const char *match,
690 uint64_t cookie) {
691
692 assert(bus);
e7176abb 693
33c62dcb
LP
694 if (!bus->bus_client)
695 return -EINVAL;
696
a132bef0 697 return bus_remove_match_internal_dbus1(bus, match);
de1c301e 698}
70666185 699
056f95d0 700_public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
4afd3348 701 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
70666185
LP
702 const char *mid;
703 int r;
704
8d162091
LP
705 assert_return(bus, -EINVAL);
706 assert_return(name, -EINVAL);
707 assert_return(machine, -EINVAL);
8d162091 708 assert_return(!bus_pid_changed(bus), -ECHILD);
45fd5e4d 709 assert_return(service_name_is_valid(name), -EINVAL);
70666185 710
33c62dcb
LP
711 if (!bus->bus_client)
712 return -EINVAL;
713
a3d59cd1
LP
714 if (!BUS_IS_OPEN(bus->state))
715 return -ENOTCONN;
716
70666185
LP
717 if (streq_ptr(name, bus->unique_name))
718 return sd_id128_get_machine(machine);
719
8d162091
LP
720 r = sd_bus_message_new_method_call(
721 bus,
151b9b96 722 &m,
8d162091
LP
723 name,
724 "/",
725 "org.freedesktop.DBus.Peer",
151b9b96 726 "GetMachineId");
8d162091
LP
727 if (r < 0)
728 return r;
729
eee9ec0e 730 r = sd_bus_message_set_auto_start(m, false);
8d162091
LP
731 if (r < 0)
732 return r;
70666185 733
8d162091 734 r = sd_bus_call(bus, m, 0, NULL, &reply);
70666185
LP
735 if (r < 0)
736 return r;
737
738 r = sd_bus_message_read(reply, "s", &mid);
739 if (r < 0)
740 return r;
741
742 return sd_id128_from_string(mid, machine);
743}