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