chiark / gitweb /
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PI...
[elogind.git] / src / libsystemd / sd-bus / bus-control.c
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
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
24 #endif
25
26 #include <stddef.h>
27 #include <errno.h>
28
29 #include "strv.h"
30 #include "sd-bus.h"
31 #include "bus-internal.h"
32 #include "bus-message.h"
33 #include "bus-control.h"
34 #include "bus-bloom.h"
35 #include "bus-util.h"
36 #include "cgroup-util.h"
37
38 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
39         int r;
40
41         assert_return(bus, -EINVAL);
42         assert_return(unique, -EINVAL);
43         assert_return(!bus_pid_changed(bus), -ECHILD);
44
45         r = bus_ensure_running(bus);
46         if (r < 0)
47                 return r;
48
49         *unique = bus->unique_name;
50         return 0;
51 }
52
53 static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
54         struct kdbus_cmd_name *n;
55         size_t size, l;
56         int r;
57
58         assert(bus);
59         assert(name);
60
61         l = strlen(name) + 1;
62         size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
63         n = alloca0_align(size, 8);
64         n->size = size;
65         kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
66
67         n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
68         n->items[0].type = KDBUS_ITEM_NAME;
69         memcpy(n->items[0].str, name, l);
70
71 #ifdef HAVE_VALGRIND_MEMCHECK_H
72         VALGRIND_MAKE_MEM_DEFINED(n, n->size);
73 #endif
74
75         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
76         if (r < 0)
77                 return -errno;
78
79         if (n->flags & KDBUS_NAME_IN_QUEUE)
80                 return 0;
81
82         return 1;
83 }
84
85 static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
86         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
87         uint32_t ret, param = 0;
88         int r;
89
90         assert(bus);
91         assert(name);
92
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
100         r = sd_bus_call_method(
101                         bus,
102                         "org.freedesktop.DBus",
103                         "/org/freedesktop/DBus",
104                         "org.freedesktop.DBus",
105                         "RequestName",
106                         NULL,
107                         &reply,
108                         "su",
109                         name,
110                         param);
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
118         if (ret == BUS_NAME_ALREADY_OWNER)
119                 return -EALREADY;
120         else if (ret == BUS_NAME_EXISTS)
121                 return -EEXIST;
122         else if (ret == BUS_NAME_IN_QUEUE)
123                 return 0;
124         else if (ret == BUS_NAME_PRIMARY_OWNER)
125                 return 1;
126
127         return -EIO;
128 }
129
130 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
131         assert_return(bus, -EINVAL);
132         assert_return(name, -EINVAL);
133         assert_return(bus->bus_client, -EINVAL);
134         assert_return(!bus_pid_changed(bus), -ECHILD);
135         assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
136         assert_return(service_name_is_valid(name), -EINVAL);
137         assert_return(name[0] != ':', -EINVAL);
138
139         if (!BUS_IS_OPEN(bus->state))
140                 return -ENOTCONN;
141
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 }
147
148 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
149         struct kdbus_cmd_name *n;
150         size_t size, l;
151         int r;
152
153         assert(bus);
154         assert(name);
155
156         l = strlen(name) + 1;
157         size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
158         n = alloca0_align(size, 8);
159         n->size = size;
160
161         n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
162         n->items[0].type = KDBUS_ITEM_NAME;
163         memcpy(n->items[0].str, name, l);
164
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;
171
172         return 0;
173 }
174
175 static 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;
178         int r;
179
180         assert(bus);
181         assert(name);
182
183         r = sd_bus_call_method(
184                         bus,
185                         "org.freedesktop.DBus",
186                         "/org/freedesktop/DBus",
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;
199         if (ret == BUS_NAME_NON_EXISTENT)
200                 return -ESRCH;
201         if (ret == BUS_NAME_NOT_OWNER)
202                 return -EADDRINUSE;
203         if (ret == BUS_NAME_RELEASED)
204                 return 0;
205
206         return -EINVAL;
207 }
208
209 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
210         assert_return(bus, -EINVAL);
211         assert_return(name, -EINVAL);
212         assert_return(bus->bus_client, -EINVAL);
213         assert_return(!bus_pid_changed(bus), -ECHILD);
214         assert_return(service_name_is_valid(name), -EINVAL);
215         assert_return(name[0] != ':', -EINVAL);
216
217         if (!BUS_IS_OPEN(bus->state))
218                 return -ENOTCONN;
219
220         if (bus->is_kernel)
221                 return bus_release_name_kernel(bus, name);
222         else
223                 return bus_release_name_dbus1(bus, name);
224 }
225
226 static 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
243 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
244         struct kdbus_cmd_name_list cmd = {};
245         struct kdbus_name_list *name_list;
246         struct kdbus_name_info *name;
247         uint64_t previous_id = 0;
248         int r;
249
250         /* Caller will free half-constructed list on failure... */
251
252         cmd.flags = flags;
253
254         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
255         if (r < 0)
256                 return -errno;
257
258         name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
259
260         KDBUS_ITEM_FOREACH(name, name_list, names) {
261
262                 struct kdbus_item *item;
263                 const char *entry_name = NULL;
264
265                 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
266                         char *n;
267
268                         if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
269                                 r = -ENOMEM;
270                                 goto fail;
271                         }
272
273                         r = strv_consume(x, n);
274                         if (r < 0)
275                                 goto fail;
276
277                         previous_id = name->owner_id;
278                 }
279
280                 KDBUS_ITEM_FOREACH(item, name, items)
281                         if (item->type == KDBUS_ITEM_OWNED_NAME)
282                                 entry_name = item->name.name;
283
284                 if (entry_name && service_name_is_valid(entry_name)) {
285                         r = strv_extend(x, entry_name);
286                         if (r < 0) {
287                                 r = -ENOMEM;
288                                 goto fail;
289                         }
290                 }
291         }
292
293         r = 0;
294
295 fail:
296         kernel_cmd_free(bus, cmd.offset);
297         return r;
298 }
299
300 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
301         _cleanup_strv_free_ char **x = NULL, **y = NULL;
302         int r;
303
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         }
309
310         if (activatable) {
311                 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
312                 if (r < 0)
313                         return r;
314
315                 *activatable = y;
316                 y = NULL;
317         }
318
319         if (acquired) {
320                 *acquired = x;
321                 x = NULL;
322         }
323
324         return 0;
325 }
326
327 static 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",
336                                 "/org/freedesktop/DBus",
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",
356                                 "/org/freedesktop/DBus",
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;
376         }
377
378         return 0;
379 }
380
381 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
382         assert_return(bus, -EINVAL);
383         assert_return(acquired || activatable, -EINVAL);
384         assert_return(!bus_pid_changed(bus), -ECHILD);
385
386         if (!BUS_IS_OPEN(bus->state))
387                 return -ENOTCONN;
388
389         if (bus->is_kernel)
390                 return bus_list_names_kernel(bus, acquired, activatable);
391         else
392                 return bus_list_names_dbus1(bus, acquired, activatable);
393 }
394
395 static int bus_populate_creds_from_items(sd_bus *bus,
396                                          struct kdbus_info *info,
397                                          uint64_t mask,
398                                          sd_bus_creds *c) {
399
400         struct kdbus_item *item;
401         uint64_t m;
402         int r;
403
404         KDBUS_ITEM_FOREACH(item, info, items) {
405
406                 switch (item->type) {
407
408                 case KDBUS_ITEM_PIDS:
409
410                         if (mask & SD_BUS_CREDS_PID && item->pids.pid > 0) {
411                                 c->pid = (pid_t) item->pids.pid;
412                                 c->mask |= SD_BUS_CREDS_PID;
413                         }
414
415                         if (mask & SD_BUS_CREDS_TID && item->pids.tid > 0) {
416                                 c->tid = (pid_t) item->pids.tid;
417                                 c->mask |= SD_BUS_CREDS_TID;
418                         }
419
420                         if (mask & SD_BUS_CREDS_PID_STARTTIME && item->pids.starttime > 0) {
421                                 c->pid_starttime = item->pids.starttime;
422                                 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
423                         }
424
425                         break;
426
427                 case KDBUS_ITEM_CREDS:
428
429                         if (mask & SD_BUS_CREDS_UID && (uid_t) item->creds.uid != (uid_t) -1) {
430                                 c->uid = (uid_t) item->creds.uid;
431                                 c->mask |= SD_BUS_CREDS_UID;
432                         }
433
434                         if (mask & SD_BUS_CREDS_EUID && (uid_t) item->creds.euid != (uid_t) -1) {
435                                 c->euid = (uid_t) item->creds.euid;
436                                 c->mask |= SD_BUS_CREDS_EUID;
437                         }
438
439                         if (mask & SD_BUS_CREDS_SUID && (uid_t) item->creds.suid != (uid_t) -1) {
440                                 c->suid = (uid_t) item->creds.suid;
441                                 c->mask |= SD_BUS_CREDS_SUID;
442                         }
443
444                         if (mask & SD_BUS_CREDS_FSUID && (uid_t) item->creds.fsuid != (uid_t) -1) {
445                                 c->fsuid = (uid_t) item->creds.fsuid;
446                                 c->mask |= SD_BUS_CREDS_FSUID;
447                         }
448
449                         if (mask & SD_BUS_CREDS_GID && (gid_t) item->creds.gid != (gid_t) -1) {
450                                 c->gid = (gid_t) item->creds.gid;
451                                 c->mask |= SD_BUS_CREDS_GID;
452                         }
453
454                         if (mask & SD_BUS_CREDS_EGID && (gid_t) item->creds.egid != (gid_t) -1) {
455                                 c->egid = (gid_t) item->creds.egid;
456                                 c->mask |= SD_BUS_CREDS_EGID;
457                         }
458
459                         if (mask & SD_BUS_CREDS_SGID && (gid_t) item->creds.sgid != (gid_t) -1) {
460                                 c->sgid = (gid_t) item->creds.sgid;
461                                 c->mask |= SD_BUS_CREDS_SGID;
462                         }
463
464                         if (mask & SD_BUS_CREDS_FSGID && (gid_t) item->creds.fsgid != (gid_t) -1) {
465                                 c->fsgid = (gid_t) item->creds.fsgid;
466                                 c->mask |= SD_BUS_CREDS_FSGID;
467                         }
468
469                         break;
470
471                 case KDBUS_ITEM_PID_COMM:
472                         if (mask & SD_BUS_CREDS_COMM) {
473                                 c->comm = strdup(item->str);
474                                 if (!c->comm)
475                                         return -ENOMEM;
476
477                                 c->mask |= SD_BUS_CREDS_COMM;
478                         }
479                         break;
480
481                 case KDBUS_ITEM_TID_COMM:
482                         if (mask & SD_BUS_CREDS_TID_COMM) {
483                                 c->tid_comm = strdup(item->str);
484                                 if (!c->tid_comm)
485                                         return -ENOMEM;
486
487                                 c->mask |= SD_BUS_CREDS_TID_COMM;
488                         }
489                         break;
490
491                 case KDBUS_ITEM_EXE:
492                         if (mask & SD_BUS_CREDS_EXE) {
493                                 c->exe = strdup(item->str);
494                                 if (!c->exe)
495                                         return -ENOMEM;
496
497                                 c->mask |= SD_BUS_CREDS_EXE;
498                         }
499                         break;
500
501                 case KDBUS_ITEM_CMDLINE:
502                         if (mask & SD_BUS_CREDS_CMDLINE) {
503                                 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
504                                 c->cmdline = memdup(item->data, c->cmdline_size);
505                                 if (!c->cmdline)
506                                         return -ENOMEM;
507
508                                 c->mask |= SD_BUS_CREDS_CMDLINE;
509                         }
510                         break;
511
512                 case KDBUS_ITEM_CGROUP:
513                         m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
514                              SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
515                              SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
516
517                         if (m) {
518                                 c->cgroup = strdup(item->str);
519                                 if (!c->cgroup)
520                                         return -ENOMEM;
521
522                                 r = bus_get_root_path(bus);
523                                 if (r < 0)
524                                         return r;
525
526                                 c->cgroup_root = strdup(bus->cgroup_root);
527                                 if (!c->cgroup_root)
528                                         return -ENOMEM;
529
530                                 c->mask |= m;
531                         }
532                         break;
533
534                 case KDBUS_ITEM_CAPS:
535                         m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
536                              SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
537
538                         if (m) {
539                                 c->capability_size = item->size - offsetof(struct kdbus_item, caps.caps);
540                                 c->capability = memdup(item->caps.caps, c->capability_size);
541                                 if (!c->capability)
542                                         return -ENOMEM;
543
544                                 c->mask |= m;
545                         }
546                         break;
547
548                 case KDBUS_ITEM_SECLABEL:
549                         if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
550                                 c->label = strdup(item->str);
551                                 if (!c->label)
552                                         return -ENOMEM;
553
554                                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
555                         }
556                         break;
557
558                 case KDBUS_ITEM_AUDIT:
559                         m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
560
561                         if (m) {
562                                 c->audit_session_id = item->audit.sessionid;
563                                 c->audit_login_uid = item->audit.loginuid;
564                                 c->mask |= m;
565                         }
566                         break;
567
568                 case KDBUS_ITEM_OWNED_NAME:
569                         if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
570                                 r = strv_extend(&c->well_known_names, item->name.name);
571                                 if (r < 0)
572                                         return r;
573
574                                 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
575                         }
576                         break;
577
578                 case KDBUS_ITEM_CONN_DESCRIPTION:
579                         if ((mask & SD_BUS_CREDS_DESCRIPTION)) {
580                                 c->description = strdup(item->str);
581                                 if (!c->description)
582                                         return -ENOMEM;
583
584                                 c->mask |= SD_BUS_CREDS_DESCRIPTION;
585                         }
586                         break;
587                 }
588         }
589
590         return 0;
591 }
592
593 static int bus_get_name_creds_kdbus(
594                 sd_bus *bus,
595                 const char *name,
596                 uint64_t mask,
597                 sd_bus_creds **creds) {
598
599         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
600         struct kdbus_cmd_info *cmd;
601         struct kdbus_info *conn_info;
602         size_t size, l;
603         uint64_t id;
604         int r;
605
606         r = bus_kernel_parse_unique_name(name, &id);
607         if (r < 0)
608                 return r;
609         if (r > 0) {
610                 size = offsetof(struct kdbus_cmd_info, items);
611                 cmd = alloca0_align(size, 8);
612                 cmd->id = id;
613         } else {
614                 l = strlen(name) + 1;
615                 size = offsetof(struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(l);
616                 cmd = alloca0_align(size, 8);
617                 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
618                 cmd->items[0].type = KDBUS_ITEM_NAME;
619                 memcpy(cmd->items[0].str, name, l);
620         }
621
622         cmd->size = size;
623         kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
624
625         /* If augmentation is on, and the bus doesn't didn't allow us
626          * to get the bits we want, then ask for the PID/TID so that we
627          * can read the rest from /proc. */
628         if ((mask & SD_BUS_CREDS_AUGMENT) &&
629             (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
630                      SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
631                      SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
632                      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|
633                      SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
634                      SD_BUS_CREDS_SELINUX_CONTEXT|
635                      SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
636                 cmd->flags |= KDBUS_ATTACH_PIDS;
637
638         r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
639         if (r < 0)
640                 return -errno;
641
642         conn_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
643
644         /* Non-activated names are considered not available */
645         if (conn_info->flags & KDBUS_HELLO_ACTIVATOR) {
646                 if (name[0] == ':')
647                         r = -ENXIO;
648                 else
649                         r = -ESRCH;
650                 goto fail;
651         }
652
653         c = bus_creds_new();
654         if (!c) {
655                 r = -ENOMEM;
656                 goto fail;
657         }
658
659         if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
660                 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0) {
661                         r = -ENOMEM;
662                         goto fail;
663                 }
664
665                 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
666         }
667
668         r = bus_populate_creds_from_items(bus, conn_info, mask, c);
669         if (r < 0)
670                 goto fail;
671
672         r = bus_creds_add_more(c, mask, 0, 0);
673         if (r < 0)
674                 goto fail;
675
676         if (creds) {
677                 *creds = c;
678                 c = NULL;
679         }
680
681         r = 0;
682
683 fail:
684         kernel_cmd_free(bus, cmd->offset);
685         return r;
686 }
687
688 static int bus_get_name_creds_dbus1(
689                 sd_bus *bus,
690                 const char *name,
691                 uint64_t mask,
692                 sd_bus_creds **creds) {
693
694         _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
695         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
696         const char *unique = NULL;
697         pid_t pid = 0;
698         int r;
699
700         /* Only query the owner if the caller wants to know it or if
701          * the caller just wants to check whether a name exists */
702         if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
703                 r = sd_bus_call_method(
704                                 bus,
705                                 "org.freedesktop.DBus",
706                                 "/org/freedesktop/DBus",
707                                 "org.freedesktop.DBus",
708                                 "GetNameOwner",
709                                 NULL,
710                                 &reply_unique,
711                                 "s",
712                                 name);
713                 if (r < 0)
714                         return r;
715
716                 r = sd_bus_message_read(reply_unique, "s", &unique);
717                 if (r < 0)
718                         return r;
719         }
720
721         if (mask != 0) {
722                 c = bus_creds_new();
723                 if (!c)
724                         return -ENOMEM;
725
726                 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
727                         c->unique_name = strdup(unique);
728                         if (!c->unique_name)
729                                 return -ENOMEM;
730
731                         c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
732                 }
733
734                 if ((mask & SD_BUS_CREDS_PID) ||
735                     ((mask & SD_BUS_CREDS_AUGMENT) &&
736                      (mask & (SD_BUS_CREDS_PID_STARTTIME|
737                               SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
738                               SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
739                               SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
740                               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|
741                               SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
742                               SD_BUS_CREDS_SELINUX_CONTEXT|
743                               SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
744
745                         uint32_t u;
746
747                         r = sd_bus_call_method(
748                                         bus,
749                                         "org.freedesktop.DBus",
750                                         "/org/freedesktop/DBus",
751                                         "org.freedesktop.DBus",
752                                         "GetConnectionUnixProcessID",
753                                         NULL,
754                                         &reply,
755                                         "s",
756                                         unique ? unique : name);
757                         if (r < 0)
758                                 return r;
759
760                         r = sd_bus_message_read(reply, "u", &u);
761                         if (r < 0)
762                                 return r;
763
764                         pid = u;
765                         if (mask & SD_BUS_CREDS_PID) {
766                                 c->pid = u;
767                                 c->mask |= SD_BUS_CREDS_PID;
768                         }
769
770                         reply = sd_bus_message_unref(reply);
771                 }
772
773                 if (mask & SD_BUS_CREDS_UID) {
774                         uint32_t u;
775
776                         r = sd_bus_call_method(
777                                         bus,
778                                         "org.freedesktop.DBus",
779                                         "/org/freedesktop/DBus",
780                                         "org.freedesktop.DBus",
781                                         "GetConnectionUnixUser",
782                                         NULL,
783                                         &reply,
784                                         "s",
785                                         unique ? unique : name);
786                         if (r < 0)
787                                 return r;
788
789                         r = sd_bus_message_read(reply, "u", &u);
790                         if (r < 0)
791                                 return r;
792
793                         c->uid = u;
794                         c->mask |= SD_BUS_CREDS_UID;
795
796                         reply = sd_bus_message_unref(reply);
797                 }
798
799                 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
800                         const void *p = NULL;
801                         size_t sz = 0;
802
803                         r = sd_bus_call_method(
804                                         bus,
805                                         "org.freedesktop.DBus",
806                                         "/org/freedesktop/DBus",
807                                         "org.freedesktop.DBus",
808                                         "GetConnectionSELinuxSecurityContext",
809                                         NULL,
810                                         &reply,
811                                         "s",
812                                         unique ? unique : name);
813                         if (r < 0)
814                                 return r;
815
816                         r = sd_bus_message_read_array(reply, 'y', &p, &sz);
817                         if (r < 0)
818                                 return r;
819
820                         c->label = strndup(p, sz);
821                         if (!c->label)
822                                 return -ENOMEM;
823
824                         c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
825                 }
826
827                 r = bus_creds_add_more(c, mask, pid, 0);
828                 if (r < 0)
829                         return r;
830         }
831
832         if (creds) {
833                 *creds = c;
834                 c = NULL;
835         }
836
837         return 0;
838 }
839
840 _public_ int sd_bus_get_name_creds(
841                 sd_bus *bus,
842                 const char *name,
843                 uint64_t mask,
844                 sd_bus_creds **creds) {
845
846         assert_return(bus, -EINVAL);
847         assert_return(name, -EINVAL);
848         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
849         assert_return(mask == 0 || creds, -EINVAL);
850         assert_return(!bus_pid_changed(bus), -ECHILD);
851         assert_return(service_name_is_valid(name), -EINVAL);
852         assert_return(bus->bus_client, -ENODATA);
853
854         if (!BUS_IS_OPEN(bus->state))
855                 return -ENOTCONN;
856
857         if (bus->is_kernel)
858                 return bus_get_name_creds_kdbus(bus, name, mask, creds);
859         else
860                 return bus_get_name_creds_dbus1(bus, name, mask, creds);
861 }
862
863 _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
864         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
865         pid_t pid = 0;
866         int r;
867
868         assert_return(bus, -EINVAL);
869         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
870         assert_return(ret, -EINVAL);
871         assert_return(!bus_pid_changed(bus), -ECHILD);
872
873         if (!BUS_IS_OPEN(bus->state))
874                 return -ENOTCONN;
875
876         if (!bus->ucred_valid && !isempty(bus->label))
877                 return -ENODATA;
878
879         c = bus_creds_new();
880         if (!c)
881                 return -ENOMEM;
882
883         if (bus->ucred_valid) {
884                 pid = c->pid = bus->ucred.pid;
885                 c->uid = bus->ucred.uid;
886                 c->gid = bus->ucred.gid;
887
888                 c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
889         }
890
891         if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
892                 c->label = strdup(bus->label);
893                 if (!c->label)
894                         return -ENOMEM;
895
896                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
897         }
898
899         if (bus->is_kernel) {
900                 struct kdbus_cmd_info cmd = {};
901                 struct kdbus_info *creator_info;
902
903                 cmd.size = sizeof(cmd);
904                 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd.flags);
905
906                 /* If augmentation is on, and the bus doesn't didn't allow us
907                  * to get the bits we want, then ask for the PID/TID so that we
908                  * can read the rest from /proc. */
909                 if ((mask & SD_BUS_CREDS_AUGMENT) &&
910                     (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
911                              SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
912                              SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
913                              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|
914                              SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
915                              SD_BUS_CREDS_SELINUX_CONTEXT|
916                              SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
917                         cmd.flags |= KDBUS_ATTACH_PIDS;
918
919                 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
920                 if (r < 0)
921                         return -errno;
922
923                 creator_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
924
925                 r = bus_populate_creds_from_items(bus, creator_info, mask, c);
926                 kernel_cmd_free(bus, cmd.offset);
927
928                 if (r < 0)
929                         return r;
930         }
931
932         r = bus_creds_add_more(c, mask, pid, 0);
933         if (r < 0)
934                 return r;
935
936         *ret = c;
937         c = NULL;
938         return 0;
939 }
940
941 static int add_name_change_match(sd_bus *bus,
942                                  uint64_t cookie,
943                                  const char *name,
944                                  const char *old_owner,
945                                  const char *new_owner) {
946
947         uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
948         int is_name_id = -1, r;
949         struct kdbus_item *item;
950
951         assert(bus);
952
953         /* If we encounter a match that could match against
954          * NameOwnerChanged messages, then we need to create
955          * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
956          * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
957          * multiple if the match is underspecified.
958          *
959          * The NameOwnerChanged signals take three parameters with
960          * unique or well-known names, but only some forms actually
961          * exist:
962          *
963          * WELLKNOWN, "", UNIQUE       → KDBUS_ITEM_NAME_ADD
964          * WELLKNOWN, UNIQUE, ""       → KDBUS_ITEM_NAME_REMOVE
965          * WELLKNOWN, UNIQUE, UNIQUE   → KDBUS_ITEM_NAME_CHANGE
966          * UNIQUE, "", UNIQUE          → KDBUS_ITEM_ID_ADD
967          * UNIQUE, UNIQUE, ""          → KDBUS_ITEM_ID_REMOVE
968          *
969          * For the latter two the two unique names must be identical.
970          *
971          * */
972
973         if (name) {
974                 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
975                 if (is_name_id < 0)
976                         return 0;
977         }
978
979         if (!isempty(old_owner)) {
980                 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
981                 if (r < 0)
982                         return 0;
983                 if (r == 0)
984                         return 0;
985                 if (is_name_id > 0 && old_owner_id != name_id)
986                         return 0;
987         } else
988                 old_owner_id = KDBUS_MATCH_ID_ANY;
989
990         if (!isempty(new_owner)) {
991                 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
992                 if (r < 0)
993                         return r;
994                 if (r == 0)
995                         return 0;
996                 if (is_name_id > 0 && new_owner_id != name_id)
997                         return 0;
998         } else
999                 new_owner_id = KDBUS_MATCH_ID_ANY;
1000
1001         if (is_name_id <= 0) {
1002                 struct kdbus_cmd_match *m;
1003                 size_t sz, l;
1004
1005                 /* If the name argument is missing or is a well-known
1006                  * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
1007                  * matches for it */
1008
1009                 l = name ? strlen(name) + 1 : 0;
1010
1011                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1012                             offsetof(struct kdbus_item, name_change) +
1013                             offsetof(struct kdbus_notify_name_change, name) +
1014                             l);
1015
1016                 m = alloca0_align(sz, 8);
1017                 m->size = sz;
1018                 m->cookie = cookie;
1019
1020                 item = m->items;
1021                 item->size =
1022                         offsetof(struct kdbus_item, name_change) +
1023                         offsetof(struct kdbus_notify_name_change, name) +
1024                         l;
1025
1026                 item->name_change.old_id.id = old_owner_id;
1027                 item->name_change.new_id.id = new_owner_id;
1028
1029                 if (name)
1030                         memcpy(item->name_change.name, name, l);
1031
1032                 /* If the old name is unset or empty, then
1033                  * this can match against added names */
1034                 if (!old_owner || old_owner[0] == 0) {
1035                         item->type = KDBUS_ITEM_NAME_ADD;
1036
1037                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1038                         if (r < 0)
1039                                 return -errno;
1040                 }
1041
1042                 /* If the new name is unset or empty, then
1043                  * this can match against removed names */
1044                 if (!new_owner || new_owner[0] == 0) {
1045                         item->type = KDBUS_ITEM_NAME_REMOVE;
1046
1047                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1048                         if (r < 0)
1049                                 return -errno;
1050                 }
1051
1052                 /* The CHANGE match we need in either case, because
1053                  * what is reported as a name change by the kernel
1054                  * might just be an owner change between starter and
1055                  * normal clients. For userspace such a change should
1056                  * be considered a removal/addition, hence let's
1057                  * subscribe to this unconditionally. */
1058                 item->type = KDBUS_ITEM_NAME_CHANGE;
1059                 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1060                 if (r < 0)
1061                         return -errno;
1062         }
1063
1064         if (is_name_id != 0) {
1065                 struct kdbus_cmd_match *m;
1066                 uint64_t sz;
1067
1068                 /* If the name argument is missing or is a unique
1069                  * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
1070                  * for it */
1071
1072                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1073                             offsetof(struct kdbus_item, id_change) +
1074                             sizeof(struct kdbus_notify_id_change));
1075
1076                 m = alloca0_align(sz, 8);
1077                 m->size = sz;
1078                 m->cookie = cookie;
1079
1080                 item = m->items;
1081                 item->size =
1082                         offsetof(struct kdbus_item, id_change) +
1083                         sizeof(struct kdbus_notify_id_change);
1084                 item->id_change.id = name_id;
1085
1086                 /* If the old name is unset or empty, then this can
1087                  * match against added ids */
1088                 if (!old_owner || old_owner[0] == 0) {
1089                         item->type = KDBUS_ITEM_ID_ADD;
1090
1091                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1092                         if (r < 0)
1093                                 return -errno;
1094                 }
1095
1096                 /* If thew new name is unset or empty, then this can
1097                  * match against removed ids */
1098                 if (!new_owner || new_owner[0] == 0) {
1099                         item->type = KDBUS_ITEM_ID_REMOVE;
1100
1101                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1102                         if (r < 0)
1103                                 return -errno;
1104                 }
1105         }
1106
1107         return 0;
1108 }
1109
1110 int bus_add_match_internal_kernel(
1111                 sd_bus *bus,
1112                 struct bus_match_component *components,
1113                 unsigned n_components,
1114                 uint64_t cookie) {
1115
1116         struct kdbus_cmd_match *m;
1117         struct kdbus_item *item;
1118         uint64_t *bloom;
1119         size_t sz;
1120         const char *sender = NULL;
1121         size_t sender_length = 0;
1122         uint64_t src_id = KDBUS_MATCH_ID_ANY;
1123         bool using_bloom = false;
1124         unsigned i;
1125         bool matches_name_change = true;
1126         const char *name_change_arg[3] = {};
1127         int r;
1128
1129         assert(bus);
1130
1131         bloom = alloca0(bus->bloom_size);
1132
1133         sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
1134
1135         for (i = 0; i < n_components; i++) {
1136                 struct bus_match_component *c = &components[i];
1137
1138                 switch (c->type) {
1139
1140                 case BUS_MATCH_SENDER:
1141                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1142                                 matches_name_change = false;
1143
1144                         r = bus_kernel_parse_unique_name(c->value_str, &src_id);
1145                         if (r < 0)
1146                                 return r;
1147                         else if (r > 0)
1148                                 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
1149                         else  {
1150                                 sender = c->value_str;
1151                                 sender_length = strlen(sender);
1152                                 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
1153                         }
1154
1155                         break;
1156
1157                 case BUS_MATCH_MESSAGE_TYPE:
1158                         if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
1159                                 matches_name_change = false;
1160
1161                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
1162                         using_bloom = true;
1163                         break;
1164
1165                 case BUS_MATCH_INTERFACE:
1166                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1167                                 matches_name_change = false;
1168
1169                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
1170                         using_bloom = true;
1171                         break;
1172
1173                 case BUS_MATCH_MEMBER:
1174                         if (!streq(c->value_str, "NameOwnerChanged"))
1175                                 matches_name_change = false;
1176
1177                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
1178                         using_bloom = true;
1179                         break;
1180
1181                 case BUS_MATCH_PATH:
1182                         if (!streq(c->value_str, "/org/freedesktop/DBus"))
1183                                 matches_name_change = false;
1184
1185                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1186                         using_bloom = true;
1187                         break;
1188
1189                 case BUS_MATCH_PATH_NAMESPACE:
1190                         if (!streq(c->value_str, "/")) {
1191                                 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1192                                 using_bloom = true;
1193                         }
1194                         break;
1195
1196                 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1197                         char buf[sizeof("arg")-1 + 2 + 1];
1198
1199                         if (c->type - BUS_MATCH_ARG < 3)
1200                                 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1201
1202                         snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1203                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1204                         using_bloom = true;
1205                         break;
1206                 }
1207
1208                 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1209                         char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1210
1211                         snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1212                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1213                         using_bloom = true;
1214                         break;
1215                 }
1216
1217                 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1218                         char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1219
1220                         snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1221                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1222                         using_bloom = true;
1223                         break;
1224                 }
1225
1226                 case BUS_MATCH_DESTINATION:
1227                         /* The bloom filter does not include
1228                            the destination, since it is only
1229                            available for broadcast messages
1230                            which do not carry a destination
1231                            since they are undirected. */
1232                         break;
1233
1234                 case BUS_MATCH_ROOT:
1235                 case BUS_MATCH_VALUE:
1236                 case BUS_MATCH_LEAF:
1237                 case _BUS_MATCH_NODE_TYPE_MAX:
1238                 case _BUS_MATCH_NODE_TYPE_INVALID:
1239                         assert_not_reached("Invalid match type?");
1240                 }
1241         }
1242
1243         if (using_bloom)
1244                 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1245
1246         m = alloca0_align(sz, 8);
1247         m->size = sz;
1248         m->cookie = cookie;
1249
1250         item = m->items;
1251
1252         if (src_id != KDBUS_MATCH_ID_ANY) {
1253                 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1254                 item->type = KDBUS_ITEM_ID;
1255                 item->id = src_id;
1256                 item = KDBUS_ITEM_NEXT(item);
1257         }
1258
1259         if (using_bloom) {
1260                 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1261                 item->type = KDBUS_ITEM_BLOOM_MASK;
1262                 memcpy(item->data64, bloom, bus->bloom_size);
1263                 item = KDBUS_ITEM_NEXT(item);
1264         }
1265
1266         if (sender) {
1267                 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1268                 item->type = KDBUS_ITEM_NAME;
1269                 memcpy(item->str, sender, sender_length + 1);
1270         }
1271
1272         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1273         if (r < 0)
1274                 return -errno;
1275
1276         if (matches_name_change) {
1277
1278                 /* If this match could theoretically match
1279                  * NameOwnerChanged messages, we need to
1280                  * install a second non-bloom filter explitly
1281                  * for it */
1282
1283                 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1284                 if (r < 0)
1285                         return r;
1286         }
1287
1288         return 0;
1289 }
1290
1291 #define internal_match(bus, m)                                          \
1292         ((bus)->hello_flags & KDBUS_HELLO_MONITOR                       \
1293          ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1294          : (m))
1295
1296 static int bus_add_match_internal_dbus1(
1297                 sd_bus *bus,
1298                 const char *match) {
1299
1300         const char *e;
1301
1302         assert(bus);
1303         assert(match);
1304
1305         e = internal_match(bus, match);
1306
1307         return sd_bus_call_method(
1308                         bus,
1309                         "org.freedesktop.DBus",
1310                         "/org/freedesktop/DBus",
1311                         "org.freedesktop.DBus",
1312                         "AddMatch",
1313                         NULL,
1314                         NULL,
1315                         "s",
1316                         e);
1317 }
1318
1319 int bus_add_match_internal(
1320                 sd_bus *bus,
1321                 const char *match,
1322                 struct bus_match_component *components,
1323                 unsigned n_components,
1324                 uint64_t cookie) {
1325
1326         assert(bus);
1327
1328         if (bus->is_kernel)
1329                 return bus_add_match_internal_kernel(bus, components, n_components, cookie);
1330         else
1331                 return bus_add_match_internal_dbus1(bus, match);
1332 }
1333
1334 int bus_remove_match_internal_kernel(
1335                 sd_bus *bus,
1336                 uint64_t cookie) {
1337
1338         struct kdbus_cmd_match m;
1339         int r;
1340
1341         assert(bus);
1342
1343         zero(m);
1344         m.size = offsetof(struct kdbus_cmd_match, items);
1345         m.cookie = cookie;
1346
1347         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1348         if (r < 0)
1349                 return -errno;
1350
1351         return 0;
1352 }
1353
1354 static int bus_remove_match_internal_dbus1(
1355                 sd_bus *bus,
1356                 const char *match) {
1357
1358         const char *e;
1359
1360         assert(bus);
1361         assert(match);
1362
1363         e = internal_match(bus, match);
1364
1365         return sd_bus_call_method(
1366                         bus,
1367                         "org.freedesktop.DBus",
1368                         "/org/freedesktop/DBus",
1369                         "org.freedesktop.DBus",
1370                         "RemoveMatch",
1371                         NULL,
1372                         NULL,
1373                         "s",
1374                         e);
1375 }
1376
1377 int bus_remove_match_internal(
1378                 sd_bus *bus,
1379                 const char *match,
1380                 uint64_t cookie) {
1381
1382         assert(bus);
1383
1384         if (bus->is_kernel)
1385                 return bus_remove_match_internal_kernel(bus, cookie);
1386         else
1387                 return bus_remove_match_internal_dbus1(bus, match);
1388 }
1389
1390 _public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1391         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1392         const char *mid;
1393         int r;
1394
1395         assert_return(bus, -EINVAL);
1396         assert_return(name, -EINVAL);
1397         assert_return(machine, -EINVAL);
1398         assert_return(!bus_pid_changed(bus), -ECHILD);
1399         assert_return(service_name_is_valid(name), -EINVAL);
1400
1401         if (!BUS_IS_OPEN(bus->state))
1402                 return -ENOTCONN;
1403
1404         if (streq_ptr(name, bus->unique_name))
1405                 return sd_id128_get_machine(machine);
1406
1407         r = sd_bus_message_new_method_call(
1408                         bus,
1409                         &m,
1410                         name,
1411                         "/",
1412                         "org.freedesktop.DBus.Peer",
1413                         "GetMachineId");
1414         if (r < 0)
1415                 return r;
1416
1417         r = sd_bus_message_set_auto_start(m, false);
1418         if (r < 0)
1419                 return r;
1420
1421         r = sd_bus_call(bus, m, 0, NULL, &reply);
1422         if (r < 0)
1423                 return r;
1424
1425         r = sd_bus_message_read(reply, "s", &mid);
1426         if (r < 0)
1427                 return r;
1428
1429         return sd_id128_from_string(mid, machine);
1430 }