chiark / gitweb /
sd-bus: properly handle uninitialized audit creds from kdbus
[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                         if (mask & SD_BUS_CREDS_AUDIT_SESSION_ID && (uint32_t) item->audit.sessionid != (uint32_t) -1) {
560                                 c->audit_session_id = (uint32_t) item->audit.sessionid;
561                                 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
562                         }
563
564                         if (mask & SD_BUS_CREDS_AUDIT_LOGIN_UID && (uid_t) item->audit.loginuid != (uid_t) -1) {
565                                 c->audit_login_uid = (uid_t) item->audit.loginuid;
566                                 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
567                         }
568                         break;
569
570                 case KDBUS_ITEM_OWNED_NAME:
571                         if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
572                                 r = strv_extend(&c->well_known_names, item->name.name);
573                                 if (r < 0)
574                                         return r;
575
576                                 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
577                         }
578                         break;
579
580                 case KDBUS_ITEM_CONN_DESCRIPTION:
581                         if ((mask & SD_BUS_CREDS_DESCRIPTION)) {
582                                 c->description = strdup(item->str);
583                                 if (!c->description)
584                                         return -ENOMEM;
585
586                                 c->mask |= SD_BUS_CREDS_DESCRIPTION;
587                         }
588                         break;
589                 }
590         }
591
592         return 0;
593 }
594
595 static int bus_get_name_creds_kdbus(
596                 sd_bus *bus,
597                 const char *name,
598                 uint64_t mask,
599                 sd_bus_creds **creds) {
600
601         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
602         struct kdbus_cmd_info *cmd;
603         struct kdbus_info *conn_info;
604         size_t size, l;
605         uint64_t id;
606         int r;
607
608         r = bus_kernel_parse_unique_name(name, &id);
609         if (r < 0)
610                 return r;
611         if (r > 0) {
612                 size = offsetof(struct kdbus_cmd_info, items);
613                 cmd = alloca0_align(size, 8);
614                 cmd->id = id;
615         } else {
616                 l = strlen(name) + 1;
617                 size = offsetof(struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(l);
618                 cmd = alloca0_align(size, 8);
619                 cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
620                 cmd->items[0].type = KDBUS_ITEM_NAME;
621                 memcpy(cmd->items[0].str, name, l);
622         }
623
624         cmd->size = size;
625         kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
626
627         /* If augmentation is on, and the bus doesn't didn't allow us
628          * to get the bits we want, then ask for the PID/TID so that we
629          * can read the rest from /proc. */
630         if ((mask & SD_BUS_CREDS_AUGMENT) &&
631             (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
632                      SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
633                      SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
634                      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|
635                      SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
636                      SD_BUS_CREDS_SELINUX_CONTEXT|
637                      SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
638                 cmd->flags |= KDBUS_ATTACH_PIDS;
639
640         r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
641         if (r < 0)
642                 return -errno;
643
644         conn_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
645
646         /* Non-activated names are considered not available */
647         if (conn_info->flags & KDBUS_HELLO_ACTIVATOR) {
648                 if (name[0] == ':')
649                         r = -ENXIO;
650                 else
651                         r = -ESRCH;
652                 goto fail;
653         }
654
655         c = bus_creds_new();
656         if (!c) {
657                 r = -ENOMEM;
658                 goto fail;
659         }
660
661         if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
662                 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0) {
663                         r = -ENOMEM;
664                         goto fail;
665                 }
666
667                 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
668         }
669
670         r = bus_populate_creds_from_items(bus, conn_info, mask, c);
671         if (r < 0)
672                 goto fail;
673
674         r = bus_creds_add_more(c, mask, 0, 0);
675         if (r < 0)
676                 goto fail;
677
678         if (creds) {
679                 *creds = c;
680                 c = NULL;
681         }
682
683         r = 0;
684
685 fail:
686         kernel_cmd_free(bus, cmd->offset);
687         return r;
688 }
689
690 static int bus_get_name_creds_dbus1(
691                 sd_bus *bus,
692                 const char *name,
693                 uint64_t mask,
694                 sd_bus_creds **creds) {
695
696         _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
697         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
698         const char *unique = NULL;
699         pid_t pid = 0;
700         int r;
701
702         /* Only query the owner if the caller wants to know it or if
703          * the caller just wants to check whether a name exists */
704         if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
705                 r = sd_bus_call_method(
706                                 bus,
707                                 "org.freedesktop.DBus",
708                                 "/org/freedesktop/DBus",
709                                 "org.freedesktop.DBus",
710                                 "GetNameOwner",
711                                 NULL,
712                                 &reply_unique,
713                                 "s",
714                                 name);
715                 if (r < 0)
716                         return r;
717
718                 r = sd_bus_message_read(reply_unique, "s", &unique);
719                 if (r < 0)
720                         return r;
721         }
722
723         if (mask != 0) {
724                 c = bus_creds_new();
725                 if (!c)
726                         return -ENOMEM;
727
728                 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
729                         c->unique_name = strdup(unique);
730                         if (!c->unique_name)
731                                 return -ENOMEM;
732
733                         c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
734                 }
735
736                 if ((mask & SD_BUS_CREDS_PID) ||
737                     ((mask & SD_BUS_CREDS_AUGMENT) &&
738                      (mask & (SD_BUS_CREDS_PID_STARTTIME|
739                               SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
740                               SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
741                               SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
742                               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|
743                               SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
744                               SD_BUS_CREDS_SELINUX_CONTEXT|
745                               SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
746
747                         uint32_t u;
748
749                         r = sd_bus_call_method(
750                                         bus,
751                                         "org.freedesktop.DBus",
752                                         "/org/freedesktop/DBus",
753                                         "org.freedesktop.DBus",
754                                         "GetConnectionUnixProcessID",
755                                         NULL,
756                                         &reply,
757                                         "s",
758                                         unique ? unique : name);
759                         if (r < 0)
760                                 return r;
761
762                         r = sd_bus_message_read(reply, "u", &u);
763                         if (r < 0)
764                                 return r;
765
766                         pid = u;
767                         if (mask & SD_BUS_CREDS_PID) {
768                                 c->pid = u;
769                                 c->mask |= SD_BUS_CREDS_PID;
770                         }
771
772                         reply = sd_bus_message_unref(reply);
773                 }
774
775                 if (mask & SD_BUS_CREDS_UID) {
776                         uint32_t u;
777
778                         r = sd_bus_call_method(
779                                         bus,
780                                         "org.freedesktop.DBus",
781                                         "/org/freedesktop/DBus",
782                                         "org.freedesktop.DBus",
783                                         "GetConnectionUnixUser",
784                                         NULL,
785                                         &reply,
786                                         "s",
787                                         unique ? unique : name);
788                         if (r < 0)
789                                 return r;
790
791                         r = sd_bus_message_read(reply, "u", &u);
792                         if (r < 0)
793                                 return r;
794
795                         c->uid = u;
796                         c->mask |= SD_BUS_CREDS_UID;
797
798                         reply = sd_bus_message_unref(reply);
799                 }
800
801                 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
802                         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
803                         const void *p = NULL;
804                         size_t sz = 0;
805
806                         r = sd_bus_call_method(
807                                         bus,
808                                         "org.freedesktop.DBus",
809                                         "/org/freedesktop/DBus",
810                                         "org.freedesktop.DBus",
811                                         "GetConnectionSELinuxSecurityContext",
812                                         &error,
813                                         &reply,
814                                         "s",
815                                         unique ? unique : name);
816                         if (r < 0) {
817                                 if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
818                                         return r;
819                         } else {
820                                 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
821                                 if (r < 0)
822                                         return r;
823
824                                 c->label = strndup(p, sz);
825                                 if (!c->label)
826                                         return -ENOMEM;
827
828                                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
829                         }
830                 }
831
832                 r = bus_creds_add_more(c, mask, pid, 0);
833                 if (r < 0)
834                         return r;
835         }
836
837         if (creds) {
838                 *creds = c;
839                 c = NULL;
840         }
841
842         return 0;
843 }
844
845 _public_ int sd_bus_get_name_creds(
846                 sd_bus *bus,
847                 const char *name,
848                 uint64_t mask,
849                 sd_bus_creds **creds) {
850
851         assert_return(bus, -EINVAL);
852         assert_return(name, -EINVAL);
853         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
854         assert_return(mask == 0 || creds, -EINVAL);
855         assert_return(!bus_pid_changed(bus), -ECHILD);
856         assert_return(service_name_is_valid(name), -EINVAL);
857         assert_return(bus->bus_client, -ENODATA);
858
859         if (!BUS_IS_OPEN(bus->state))
860                 return -ENOTCONN;
861
862         if (bus->is_kernel)
863                 return bus_get_name_creds_kdbus(bus, name, mask, creds);
864         else
865                 return bus_get_name_creds_dbus1(bus, name, mask, creds);
866 }
867
868 _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
869         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
870         pid_t pid = 0;
871         int r;
872
873         assert_return(bus, -EINVAL);
874         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
875         assert_return(ret, -EINVAL);
876         assert_return(!bus_pid_changed(bus), -ECHILD);
877
878         if (!BUS_IS_OPEN(bus->state))
879                 return -ENOTCONN;
880
881         if (!bus->ucred_valid && !isempty(bus->label))
882                 return -ENODATA;
883
884         c = bus_creds_new();
885         if (!c)
886                 return -ENOMEM;
887
888         if (bus->ucred_valid) {
889                 pid = c->pid = bus->ucred.pid;
890                 c->uid = bus->ucred.uid;
891                 c->gid = bus->ucred.gid;
892
893                 c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
894         }
895
896         if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
897                 c->label = strdup(bus->label);
898                 if (!c->label)
899                         return -ENOMEM;
900
901                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
902         }
903
904         if (bus->is_kernel) {
905                 struct kdbus_cmd_info cmd = {};
906                 struct kdbus_info *creator_info;
907
908                 cmd.size = sizeof(cmd);
909                 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd.flags);
910
911                 /* If augmentation is on, and the bus doesn't didn't allow us
912                  * to get the bits we want, then ask for the PID/TID so that we
913                  * can read the rest from /proc. */
914                 if ((mask & SD_BUS_CREDS_AUGMENT) &&
915                     (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
916                              SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
917                              SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
918                              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|
919                              SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
920                              SD_BUS_CREDS_SELINUX_CONTEXT|
921                              SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
922                         cmd.flags |= KDBUS_ATTACH_PIDS;
923
924                 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
925                 if (r < 0)
926                         return -errno;
927
928                 creator_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
929
930                 r = bus_populate_creds_from_items(bus, creator_info, mask, c);
931                 kernel_cmd_free(bus, cmd.offset);
932
933                 if (r < 0)
934                         return r;
935         }
936
937         r = bus_creds_add_more(c, mask, pid, 0);
938         if (r < 0)
939                 return r;
940
941         *ret = c;
942         c = NULL;
943         return 0;
944 }
945
946 static int add_name_change_match(sd_bus *bus,
947                                  uint64_t cookie,
948                                  const char *name,
949                                  const char *old_owner,
950                                  const char *new_owner) {
951
952         uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
953         int is_name_id = -1, r;
954         struct kdbus_item *item;
955
956         assert(bus);
957
958         /* If we encounter a match that could match against
959          * NameOwnerChanged messages, then we need to create
960          * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
961          * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
962          * multiple if the match is underspecified.
963          *
964          * The NameOwnerChanged signals take three parameters with
965          * unique or well-known names, but only some forms actually
966          * exist:
967          *
968          * WELLKNOWN, "", UNIQUE       → KDBUS_ITEM_NAME_ADD
969          * WELLKNOWN, UNIQUE, ""       → KDBUS_ITEM_NAME_REMOVE
970          * WELLKNOWN, UNIQUE, UNIQUE   → KDBUS_ITEM_NAME_CHANGE
971          * UNIQUE, "", UNIQUE          → KDBUS_ITEM_ID_ADD
972          * UNIQUE, UNIQUE, ""          → KDBUS_ITEM_ID_REMOVE
973          *
974          * For the latter two the two unique names must be identical.
975          *
976          * */
977
978         if (name) {
979                 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
980                 if (is_name_id < 0)
981                         return 0;
982         }
983
984         if (!isempty(old_owner)) {
985                 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
986                 if (r < 0)
987                         return 0;
988                 if (r == 0)
989                         return 0;
990                 if (is_name_id > 0 && old_owner_id != name_id)
991                         return 0;
992         } else
993                 old_owner_id = KDBUS_MATCH_ID_ANY;
994
995         if (!isempty(new_owner)) {
996                 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
997                 if (r < 0)
998                         return r;
999                 if (r == 0)
1000                         return 0;
1001                 if (is_name_id > 0 && new_owner_id != name_id)
1002                         return 0;
1003         } else
1004                 new_owner_id = KDBUS_MATCH_ID_ANY;
1005
1006         if (is_name_id <= 0) {
1007                 struct kdbus_cmd_match *m;
1008                 size_t sz, l;
1009
1010                 /* If the name argument is missing or is a well-known
1011                  * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
1012                  * matches for it */
1013
1014                 l = name ? strlen(name) + 1 : 0;
1015
1016                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1017                             offsetof(struct kdbus_item, name_change) +
1018                             offsetof(struct kdbus_notify_name_change, name) +
1019                             l);
1020
1021                 m = alloca0_align(sz, 8);
1022                 m->size = sz;
1023                 m->cookie = cookie;
1024
1025                 item = m->items;
1026                 item->size =
1027                         offsetof(struct kdbus_item, name_change) +
1028                         offsetof(struct kdbus_notify_name_change, name) +
1029                         l;
1030
1031                 item->name_change.old_id.id = old_owner_id;
1032                 item->name_change.new_id.id = new_owner_id;
1033
1034                 if (name)
1035                         memcpy(item->name_change.name, name, l);
1036
1037                 /* If the old name is unset or empty, then
1038                  * this can match against added names */
1039                 if (!old_owner || old_owner[0] == 0) {
1040                         item->type = KDBUS_ITEM_NAME_ADD;
1041
1042                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1043                         if (r < 0)
1044                                 return -errno;
1045                 }
1046
1047                 /* If the new name is unset or empty, then
1048                  * this can match against removed names */
1049                 if (!new_owner || new_owner[0] == 0) {
1050                         item->type = KDBUS_ITEM_NAME_REMOVE;
1051
1052                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1053                         if (r < 0)
1054                                 return -errno;
1055                 }
1056
1057                 /* The CHANGE match we need in either case, because
1058                  * what is reported as a name change by the kernel
1059                  * might just be an owner change between starter and
1060                  * normal clients. For userspace such a change should
1061                  * be considered a removal/addition, hence let's
1062                  * subscribe to this unconditionally. */
1063                 item->type = KDBUS_ITEM_NAME_CHANGE;
1064                 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1065                 if (r < 0)
1066                         return -errno;
1067         }
1068
1069         if (is_name_id != 0) {
1070                 struct kdbus_cmd_match *m;
1071                 uint64_t sz;
1072
1073                 /* If the name argument is missing or is a unique
1074                  * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
1075                  * for it */
1076
1077                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1078                             offsetof(struct kdbus_item, id_change) +
1079                             sizeof(struct kdbus_notify_id_change));
1080
1081                 m = alloca0_align(sz, 8);
1082                 m->size = sz;
1083                 m->cookie = cookie;
1084
1085                 item = m->items;
1086                 item->size =
1087                         offsetof(struct kdbus_item, id_change) +
1088                         sizeof(struct kdbus_notify_id_change);
1089                 item->id_change.id = name_id;
1090
1091                 /* If the old name is unset or empty, then this can
1092                  * match against added ids */
1093                 if (!old_owner || old_owner[0] == 0) {
1094                         item->type = KDBUS_ITEM_ID_ADD;
1095
1096                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1097                         if (r < 0)
1098                                 return -errno;
1099                 }
1100
1101                 /* If thew new name is unset or empty, then this can
1102                  * match against removed ids */
1103                 if (!new_owner || new_owner[0] == 0) {
1104                         item->type = KDBUS_ITEM_ID_REMOVE;
1105
1106                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1107                         if (r < 0)
1108                                 return -errno;
1109                 }
1110         }
1111
1112         return 0;
1113 }
1114
1115 int bus_add_match_internal_kernel(
1116                 sd_bus *bus,
1117                 struct bus_match_component *components,
1118                 unsigned n_components,
1119                 uint64_t cookie) {
1120
1121         struct kdbus_cmd_match *m;
1122         struct kdbus_item *item;
1123         uint64_t *bloom;
1124         size_t sz;
1125         const char *sender = NULL;
1126         size_t sender_length = 0;
1127         uint64_t src_id = KDBUS_MATCH_ID_ANY;
1128         bool using_bloom = false;
1129         unsigned i;
1130         bool matches_name_change = true;
1131         const char *name_change_arg[3] = {};
1132         int r;
1133
1134         assert(bus);
1135
1136         bloom = alloca0(bus->bloom_size);
1137
1138         sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
1139
1140         for (i = 0; i < n_components; i++) {
1141                 struct bus_match_component *c = &components[i];
1142
1143                 switch (c->type) {
1144
1145                 case BUS_MATCH_SENDER:
1146                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1147                                 matches_name_change = false;
1148
1149                         r = bus_kernel_parse_unique_name(c->value_str, &src_id);
1150                         if (r < 0)
1151                                 return r;
1152                         else if (r > 0)
1153                                 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
1154                         else  {
1155                                 sender = c->value_str;
1156                                 sender_length = strlen(sender);
1157                                 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
1158                         }
1159
1160                         break;
1161
1162                 case BUS_MATCH_MESSAGE_TYPE:
1163                         if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
1164                                 matches_name_change = false;
1165
1166                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
1167                         using_bloom = true;
1168                         break;
1169
1170                 case BUS_MATCH_INTERFACE:
1171                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1172                                 matches_name_change = false;
1173
1174                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
1175                         using_bloom = true;
1176                         break;
1177
1178                 case BUS_MATCH_MEMBER:
1179                         if (!streq(c->value_str, "NameOwnerChanged"))
1180                                 matches_name_change = false;
1181
1182                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
1183                         using_bloom = true;
1184                         break;
1185
1186                 case BUS_MATCH_PATH:
1187                         if (!streq(c->value_str, "/org/freedesktop/DBus"))
1188                                 matches_name_change = false;
1189
1190                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1191                         using_bloom = true;
1192                         break;
1193
1194                 case BUS_MATCH_PATH_NAMESPACE:
1195                         if (!streq(c->value_str, "/")) {
1196                                 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1197                                 using_bloom = true;
1198                         }
1199                         break;
1200
1201                 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1202                         char buf[sizeof("arg")-1 + 2 + 1];
1203
1204                         if (c->type - BUS_MATCH_ARG < 3)
1205                                 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1206
1207                         snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1208                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1209                         using_bloom = true;
1210                         break;
1211                 }
1212
1213                 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1214                         char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1215
1216                         snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1217                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1218                         using_bloom = true;
1219                         break;
1220                 }
1221
1222                 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1223                         char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1224
1225                         snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1226                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1227                         using_bloom = true;
1228                         break;
1229                 }
1230
1231                 case BUS_MATCH_DESTINATION:
1232                         /* The bloom filter does not include
1233                            the destination, since it is only
1234                            available for broadcast messages
1235                            which do not carry a destination
1236                            since they are undirected. */
1237                         break;
1238
1239                 case BUS_MATCH_ROOT:
1240                 case BUS_MATCH_VALUE:
1241                 case BUS_MATCH_LEAF:
1242                 case _BUS_MATCH_NODE_TYPE_MAX:
1243                 case _BUS_MATCH_NODE_TYPE_INVALID:
1244                         assert_not_reached("Invalid match type?");
1245                 }
1246         }
1247
1248         if (using_bloom)
1249                 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1250
1251         m = alloca0_align(sz, 8);
1252         m->size = sz;
1253         m->cookie = cookie;
1254
1255         item = m->items;
1256
1257         if (src_id != KDBUS_MATCH_ID_ANY) {
1258                 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1259                 item->type = KDBUS_ITEM_ID;
1260                 item->id = src_id;
1261                 item = KDBUS_ITEM_NEXT(item);
1262         }
1263
1264         if (using_bloom) {
1265                 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1266                 item->type = KDBUS_ITEM_BLOOM_MASK;
1267                 memcpy(item->data64, bloom, bus->bloom_size);
1268                 item = KDBUS_ITEM_NEXT(item);
1269         }
1270
1271         if (sender) {
1272                 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1273                 item->type = KDBUS_ITEM_NAME;
1274                 memcpy(item->str, sender, sender_length + 1);
1275         }
1276
1277         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1278         if (r < 0)
1279                 return -errno;
1280
1281         if (matches_name_change) {
1282
1283                 /* If this match could theoretically match
1284                  * NameOwnerChanged messages, we need to
1285                  * install a second non-bloom filter explitly
1286                  * for it */
1287
1288                 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1289                 if (r < 0)
1290                         return r;
1291         }
1292
1293         return 0;
1294 }
1295
1296 #define internal_match(bus, m)                                          \
1297         ((bus)->hello_flags & KDBUS_HELLO_MONITOR                       \
1298          ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1299          : (m))
1300
1301 static int bus_add_match_internal_dbus1(
1302                 sd_bus *bus,
1303                 const char *match) {
1304
1305         const char *e;
1306
1307         assert(bus);
1308         assert(match);
1309
1310         e = internal_match(bus, match);
1311
1312         return sd_bus_call_method(
1313                         bus,
1314                         "org.freedesktop.DBus",
1315                         "/org/freedesktop/DBus",
1316                         "org.freedesktop.DBus",
1317                         "AddMatch",
1318                         NULL,
1319                         NULL,
1320                         "s",
1321                         e);
1322 }
1323
1324 int bus_add_match_internal(
1325                 sd_bus *bus,
1326                 const char *match,
1327                 struct bus_match_component *components,
1328                 unsigned n_components,
1329                 uint64_t cookie) {
1330
1331         assert(bus);
1332
1333         if (bus->is_kernel)
1334                 return bus_add_match_internal_kernel(bus, components, n_components, cookie);
1335         else
1336                 return bus_add_match_internal_dbus1(bus, match);
1337 }
1338
1339 int bus_remove_match_internal_kernel(
1340                 sd_bus *bus,
1341                 uint64_t cookie) {
1342
1343         struct kdbus_cmd_match m;
1344         int r;
1345
1346         assert(bus);
1347
1348         zero(m);
1349         m.size = offsetof(struct kdbus_cmd_match, items);
1350         m.cookie = cookie;
1351
1352         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1353         if (r < 0)
1354                 return -errno;
1355
1356         return 0;
1357 }
1358
1359 static int bus_remove_match_internal_dbus1(
1360                 sd_bus *bus,
1361                 const char *match) {
1362
1363         const char *e;
1364
1365         assert(bus);
1366         assert(match);
1367
1368         e = internal_match(bus, match);
1369
1370         return sd_bus_call_method(
1371                         bus,
1372                         "org.freedesktop.DBus",
1373                         "/org/freedesktop/DBus",
1374                         "org.freedesktop.DBus",
1375                         "RemoveMatch",
1376                         NULL,
1377                         NULL,
1378                         "s",
1379                         e);
1380 }
1381
1382 int bus_remove_match_internal(
1383                 sd_bus *bus,
1384                 const char *match,
1385                 uint64_t cookie) {
1386
1387         assert(bus);
1388
1389         if (bus->is_kernel)
1390                 return bus_remove_match_internal_kernel(bus, cookie);
1391         else
1392                 return bus_remove_match_internal_dbus1(bus, match);
1393 }
1394
1395 _public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1396         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1397         const char *mid;
1398         int r;
1399
1400         assert_return(bus, -EINVAL);
1401         assert_return(name, -EINVAL);
1402         assert_return(machine, -EINVAL);
1403         assert_return(!bus_pid_changed(bus), -ECHILD);
1404         assert_return(service_name_is_valid(name), -EINVAL);
1405
1406         if (!BUS_IS_OPEN(bus->state))
1407                 return -ENOTCONN;
1408
1409         if (streq_ptr(name, bus->unique_name))
1410                 return sd_id128_get_machine(machine);
1411
1412         r = sd_bus_message_new_method_call(
1413                         bus,
1414                         &m,
1415                         name,
1416                         "/",
1417                         "org.freedesktop.DBus.Peer",
1418                         "GetMachineId");
1419         if (r < 0)
1420                 return r;
1421
1422         r = sd_bus_message_set_auto_start(m, false);
1423         if (r < 0)
1424                 return r;
1425
1426         r = sd_bus_call(bus, m, 0, NULL, &reply);
1427         if (r < 0)
1428                 return r;
1429
1430         r = sd_bus_message_read(reply, "s", &mid);
1431         if (r < 0)
1432                 return r;
1433
1434         return sd_id128_from_string(mid, machine);
1435 }