chiark / gitweb /
bus: add sd_bus_emit_object_{added/removed}()
[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 "capability.h"
37 #include "cgroup-util.h"
38
39 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
40         int r;
41
42         assert_return(bus, -EINVAL);
43         assert_return(unique, -EINVAL);
44         assert_return(!bus_pid_changed(bus), -ECHILD);
45
46         r = bus_ensure_running(bus);
47         if (r < 0)
48                 return r;
49
50         *unique = bus->unique_name;
51         return 0;
52 }
53
54 static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
55         struct kdbus_cmd_name *n;
56         size_t size, l;
57         int r;
58
59         assert(bus);
60         assert(name);
61
62         l = strlen(name) + 1;
63         size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
64         n = alloca0_align(size, 8);
65         n->size = size;
66         n->flags = request_name_flags_to_kdbus(flags);
67
68         n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
69         n->items[0].type = KDBUS_ITEM_NAME;
70         memcpy(n->items[0].str, name, l);
71
72 #ifdef HAVE_VALGRIND_MEMCHECK_H
73         VALGRIND_MAKE_MEM_DEFINED(n, n->size);
74 #endif
75
76         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
77         if (r < 0)
78                 return -errno;
79
80         if (n->flags & KDBUS_NAME_IN_QUEUE)
81                 return 0;
82
83         return 1;
84 }
85
86 static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
87         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
88         uint32_t ret, param = 0;
89         int r;
90
91         assert(bus);
92         assert(name);
93
94         if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
95                 param |= BUS_NAME_ALLOW_REPLACEMENT;
96         if (flags & SD_BUS_NAME_REPLACE_EXISTING)
97                 param |= BUS_NAME_REPLACE_EXISTING;
98         if (!(flags & SD_BUS_NAME_QUEUE))
99                 param |= BUS_NAME_DO_NOT_QUEUE;
100
101         r = sd_bus_call_method(
102                         bus,
103                         "org.freedesktop.DBus",
104                         "/org/freedesktop/DBus",
105                         "org.freedesktop.DBus",
106                         "RequestName",
107                         NULL,
108                         &reply,
109                         "su",
110                         name,
111                         param);
112         if (r < 0)
113                 return r;
114
115         r = sd_bus_message_read(reply, "u", &ret);
116         if (r < 0)
117                 return r;
118
119         if (ret == BUS_NAME_ALREADY_OWNER)
120                 return -EALREADY;
121         else if (ret == BUS_NAME_EXISTS)
122                 return -EEXIST;
123         else if (ret == BUS_NAME_IN_QUEUE)
124                 return 0;
125         else if (ret == BUS_NAME_PRIMARY_OWNER)
126                 return 1;
127
128         return -EIO;
129 }
130
131 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
132         assert_return(bus, -EINVAL);
133         assert_return(name, -EINVAL);
134         assert_return(bus->bus_client, -EINVAL);
135         assert_return(!bus_pid_changed(bus), -ECHILD);
136         assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
137         assert_return(service_name_is_valid(name), -EINVAL);
138         assert_return(name[0] != ':', -EINVAL);
139
140         if (!BUS_IS_OPEN(bus->state))
141                 return -ENOTCONN;
142
143         if (bus->is_kernel)
144                 return bus_request_name_kernel(bus, name, flags);
145         else
146                 return bus_request_name_dbus1(bus, name, flags);
147 }
148
149 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
150         struct kdbus_cmd_name *n;
151         size_t size, l;
152         int r;
153
154         assert(bus);
155         assert(name);
156
157         l = strlen(name) + 1;
158         size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l);
159         n = alloca0_align(size, 8);
160         n->size = size;
161
162         n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
163         n->items[0].type = KDBUS_ITEM_NAME;
164         memcpy(n->items[0].str, name, l);
165
166 #ifdef HAVE_VALGRIND_MEMCHECK_H
167         VALGRIND_MAKE_MEM_DEFINED(n, n->size);
168 #endif
169         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
170         if (r < 0)
171                 return -errno;
172
173         return 0;
174 }
175
176 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
177         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
178         uint32_t ret;
179         int r;
180
181         assert(bus);
182         assert(name);
183
184         r = sd_bus_call_method(
185                         bus,
186                         "org.freedesktop.DBus",
187                         "/org/freedesktop/DBus",
188                         "org.freedesktop.DBus",
189                         "ReleaseName",
190                         NULL,
191                         &reply,
192                         "s",
193                         name);
194         if (r < 0)
195                 return r;
196
197         r = sd_bus_message_read(reply, "u", &ret);
198         if (r < 0)
199                 return r;
200         if (ret == BUS_NAME_NON_EXISTENT)
201                 return -ESRCH;
202         if (ret == BUS_NAME_NOT_OWNER)
203                 return -EADDRINUSE;
204         if (ret == BUS_NAME_RELEASED)
205                 return 0;
206
207         return -EINVAL;
208 }
209
210 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
211         assert_return(bus, -EINVAL);
212         assert_return(name, -EINVAL);
213         assert_return(bus->bus_client, -EINVAL);
214         assert_return(!bus_pid_changed(bus), -ECHILD);
215         assert_return(service_name_is_valid(name), -EINVAL);
216         assert_return(name[0] != ':', -EINVAL);
217
218         if (!BUS_IS_OPEN(bus->state))
219                 return -ENOTCONN;
220
221         if (bus->is_kernel)
222                 return bus_release_name_kernel(bus, name);
223         else
224                 return bus_release_name_dbus1(bus, name);
225 }
226
227 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
228         struct kdbus_cmd_name_list cmd = {};
229         struct kdbus_name_list *name_list;
230         struct kdbus_name_info *name;
231         uint64_t previous_id = 0;
232         int r;
233
234         /* Caller will free half-constructed list on failure... */
235
236         cmd.size = sizeof(cmd);
237         cmd.flags = flags;
238
239         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
240         if (r < 0)
241                 return -errno;
242
243         name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
244
245         KDBUS_ITEM_FOREACH(name, name_list, names) {
246
247                 struct kdbus_item *item;
248                 const char *entry_name = NULL;
249
250                 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
251                         char *n;
252
253                         if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
254                                 r = -ENOMEM;
255                                 goto fail;
256                         }
257
258                         r = strv_consume(x, n);
259                         if (r < 0)
260                                 goto fail;
261
262                         previous_id = name->owner_id;
263                 }
264
265                 KDBUS_ITEM_FOREACH(item, name, items)
266                         if (item->type == KDBUS_ITEM_OWNED_NAME)
267                                 entry_name = item->name.name;
268
269                 if (entry_name && service_name_is_valid(entry_name)) {
270                         r = strv_extend(x, entry_name);
271                         if (r < 0) {
272                                 r = -ENOMEM;
273                                 goto fail;
274                         }
275                 }
276         }
277
278         r = 0;
279
280 fail:
281         bus_kernel_cmd_free(bus, cmd.offset);
282         return r;
283 }
284
285 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
286         _cleanup_strv_free_ char **x = NULL, **y = NULL;
287         int r;
288
289         if (acquired) {
290                 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
291                 if (r < 0)
292                         return r;
293         }
294
295         if (activatable) {
296                 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
297                 if (r < 0)
298                         return r;
299
300                 *activatable = y;
301                 y = NULL;
302         }
303
304         if (acquired) {
305                 *acquired = x;
306                 x = NULL;
307         }
308
309         return 0;
310 }
311
312 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
313         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
314         _cleanup_strv_free_ char **x = NULL, **y = NULL;
315         int r;
316
317         if (acquired) {
318                 r = sd_bus_call_method(
319                                 bus,
320                                 "org.freedesktop.DBus",
321                                 "/org/freedesktop/DBus",
322                                 "org.freedesktop.DBus",
323                                 "ListNames",
324                                 NULL,
325                                 &reply,
326                                 NULL);
327                 if (r < 0)
328                         return r;
329
330                 r = sd_bus_message_read_strv(reply, &x);
331                 if (r < 0)
332                         return r;
333
334                 reply = sd_bus_message_unref(reply);
335         }
336
337         if (activatable) {
338                 r = sd_bus_call_method(
339                                 bus,
340                                 "org.freedesktop.DBus",
341                                 "/org/freedesktop/DBus",
342                                 "org.freedesktop.DBus",
343                                 "ListActivatableNames",
344                                 NULL,
345                                 &reply,
346                                 NULL);
347                 if (r < 0)
348                         return r;
349
350                 r = sd_bus_message_read_strv(reply, &y);
351                 if (r < 0)
352                         return r;
353
354                 *activatable = y;
355                 y = NULL;
356         }
357
358         if (acquired) {
359                 *acquired = x;
360                 x = NULL;
361         }
362
363         return 0;
364 }
365
366 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
367         assert_return(bus, -EINVAL);
368         assert_return(acquired || activatable, -EINVAL);
369         assert_return(!bus_pid_changed(bus), -ECHILD);
370
371         if (!BUS_IS_OPEN(bus->state))
372                 return -ENOTCONN;
373
374         if (bus->is_kernel)
375                 return bus_list_names_kernel(bus, acquired, activatable);
376         else
377                 return bus_list_names_dbus1(bus, acquired, activatable);
378 }
379
380 static int bus_populate_creds_from_items(
381                 sd_bus *bus,
382                 struct kdbus_info *info,
383                 uint64_t mask,
384                 sd_bus_creds *c) {
385
386         struct kdbus_item *item;
387         uint64_t m;
388         int r;
389
390         assert(bus);
391         assert(info);
392         assert(c);
393
394         KDBUS_ITEM_FOREACH(item, info, items) {
395
396                 switch (item->type) {
397
398                 case KDBUS_ITEM_PIDS:
399
400                         if (mask & SD_BUS_CREDS_PID && item->pids.pid > 0) {
401                                 c->pid = (pid_t) item->pids.pid;
402                                 c->mask |= SD_BUS_CREDS_PID;
403                         }
404
405                         if (mask & SD_BUS_CREDS_TID && item->pids.tid > 0) {
406                                 c->tid = (pid_t) item->pids.tid;
407                                 c->mask |= SD_BUS_CREDS_TID;
408                         }
409
410                         break;
411
412                 case KDBUS_ITEM_CREDS:
413
414                         if (mask & SD_BUS_CREDS_UID && (uid_t) item->creds.uid != UID_INVALID) {
415                                 c->uid = (uid_t) item->creds.uid;
416                                 c->mask |= SD_BUS_CREDS_UID;
417                         }
418
419                         if (mask & SD_BUS_CREDS_EUID && (uid_t) item->creds.euid != UID_INVALID) {
420                                 c->euid = (uid_t) item->creds.euid;
421                                 c->mask |= SD_BUS_CREDS_EUID;
422                         }
423
424                         if (mask & SD_BUS_CREDS_SUID && (uid_t) item->creds.suid != UID_INVALID) {
425                                 c->suid = (uid_t) item->creds.suid;
426                                 c->mask |= SD_BUS_CREDS_SUID;
427                         }
428
429                         if (mask & SD_BUS_CREDS_FSUID && (uid_t) item->creds.fsuid != UID_INVALID) {
430                                 c->fsuid = (uid_t) item->creds.fsuid;
431                                 c->mask |= SD_BUS_CREDS_FSUID;
432                         }
433
434                         if (mask & SD_BUS_CREDS_GID && (gid_t) item->creds.gid != GID_INVALID) {
435                                 c->gid = (gid_t) item->creds.gid;
436                                 c->mask |= SD_BUS_CREDS_GID;
437                         }
438
439                         if (mask & SD_BUS_CREDS_EGID && (gid_t) item->creds.egid != GID_INVALID) {
440                                 c->egid = (gid_t) item->creds.egid;
441                                 c->mask |= SD_BUS_CREDS_EGID;
442                         }
443
444                         if (mask & SD_BUS_CREDS_SGID && (gid_t) item->creds.sgid != GID_INVALID) {
445                                 c->sgid = (gid_t) item->creds.sgid;
446                                 c->mask |= SD_BUS_CREDS_SGID;
447                         }
448
449                         if (mask & SD_BUS_CREDS_FSGID && (gid_t) item->creds.fsgid != GID_INVALID) {
450                                 c->fsgid = (gid_t) item->creds.fsgid;
451                                 c->mask |= SD_BUS_CREDS_FSGID;
452                         }
453
454                         break;
455
456                 case KDBUS_ITEM_PID_COMM:
457                         if (mask & SD_BUS_CREDS_COMM) {
458                                 r = free_and_strdup(&c->comm, item->str);
459                                 if (r < 0)
460                                         return r;
461
462                                 c->mask |= SD_BUS_CREDS_COMM;
463                         }
464                         break;
465
466                 case KDBUS_ITEM_TID_COMM:
467                         if (mask & SD_BUS_CREDS_TID_COMM) {
468                                 r = free_and_strdup(&c->tid_comm, item->str);
469                                 if (r < 0)
470                                         return r;
471
472                                 c->mask |= SD_BUS_CREDS_TID_COMM;
473                         }
474                         break;
475
476                 case KDBUS_ITEM_EXE:
477                         if (mask & SD_BUS_CREDS_EXE) {
478                                 r = free_and_strdup(&c->exe, item->str);
479                                 if (r < 0)
480                                         return r;
481
482                                 c->mask |= SD_BUS_CREDS_EXE;
483                         }
484                         break;
485
486                 case KDBUS_ITEM_CMDLINE:
487                         if (mask & SD_BUS_CREDS_CMDLINE) {
488                                 c->cmdline_size = item->size - offsetof(struct kdbus_item, data);
489                                 c->cmdline = memdup(item->data, c->cmdline_size);
490                                 if (!c->cmdline)
491                                         return -ENOMEM;
492
493                                 c->mask |= SD_BUS_CREDS_CMDLINE;
494                         }
495                         break;
496
497                 case KDBUS_ITEM_CGROUP:
498                         m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
499                              SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
500                              SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
501
502                         if (m) {
503                                 r = free_and_strdup(&c->cgroup, item->str);
504                                 if (r < 0)
505                                         return r;
506
507                                 r = bus_get_root_path(bus);
508                                 if (r < 0)
509                                         return r;
510
511                                 r = free_and_strdup(&c->cgroup_root, bus->cgroup_root);
512                                 if (r < 0)
513                                         return r;
514
515                                 c->mask |= m;
516                         }
517                         break;
518
519                 case KDBUS_ITEM_CAPS:
520                         m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
521                              SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
522
523                         if (m) {
524                                 if (item->caps.last_cap != cap_last_cap() ||
525                                     item->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(item->caps.last_cap, 32U) * 4 * 4)
526                                         return -EBADMSG;
527
528                                 c->capability = memdup(item->caps.caps, item->size - offsetof(struct kdbus_item, caps.caps));
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_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
755                               SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
756                               SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
757                               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|
758                               SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
759                               SD_BUS_CREDS_SELINUX_CONTEXT|
760                               SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
761
762                         uint32_t u;
763
764                         r = sd_bus_call_method(
765                                         bus,
766                                         "org.freedesktop.DBus",
767                                         "/org/freedesktop/DBus",
768                                         "org.freedesktop.DBus",
769                                         "GetConnectionUnixProcessID",
770                                         NULL,
771                                         &reply,
772                                         "s",
773                                         unique ? unique : name);
774                         if (r < 0)
775                                 return r;
776
777                         r = sd_bus_message_read(reply, "u", &u);
778                         if (r < 0)
779                                 return r;
780
781                         pid = u;
782                         if (mask & SD_BUS_CREDS_PID) {
783                                 c->pid = u;
784                                 c->mask |= SD_BUS_CREDS_PID;
785                         }
786
787                         reply = sd_bus_message_unref(reply);
788                 }
789
790                 if (mask & SD_BUS_CREDS_UID) {
791                         uint32_t u;
792
793                         r = sd_bus_call_method(
794                                         bus,
795                                         "org.freedesktop.DBus",
796                                         "/org/freedesktop/DBus",
797                                         "org.freedesktop.DBus",
798                                         "GetConnectionUnixUser",
799                                         NULL,
800                                         &reply,
801                                         "s",
802                                         unique ? unique : name);
803                         if (r < 0)
804                                 return r;
805
806                         r = sd_bus_message_read(reply, "u", &u);
807                         if (r < 0)
808                                 return r;
809
810                         c->uid = u;
811                         c->mask |= SD_BUS_CREDS_UID;
812
813                         reply = sd_bus_message_unref(reply);
814                 }
815
816                 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
817                         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
818                         const void *p = NULL;
819                         size_t sz = 0;
820
821                         r = sd_bus_call_method(
822                                         bus,
823                                         "org.freedesktop.DBus",
824                                         "/org/freedesktop/DBus",
825                                         "org.freedesktop.DBus",
826                                         "GetConnectionSELinuxSecurityContext",
827                                         &error,
828                                         &reply,
829                                         "s",
830                                         unique ? unique : name);
831                         if (r < 0) {
832                                 if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
833                                         return r;
834                         } else {
835                                 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
836                                 if (r < 0)
837                                         return r;
838
839                                 c->label = strndup(p, sz);
840                                 if (!c->label)
841                                         return -ENOMEM;
842
843                                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
844                         }
845                 }
846
847                 r = bus_creds_add_more(c, mask, pid, 0);
848                 if (r < 0)
849                         return r;
850         }
851
852         if (creds) {
853                 *creds = c;
854                 c = NULL;
855         }
856
857         return 0;
858 }
859
860 _public_ int sd_bus_get_name_creds(
861                 sd_bus *bus,
862                 const char *name,
863                 uint64_t mask,
864                 sd_bus_creds **creds) {
865
866         assert_return(bus, -EINVAL);
867         assert_return(name, -EINVAL);
868         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
869         assert_return(mask == 0 || creds, -EINVAL);
870         assert_return(!bus_pid_changed(bus), -ECHILD);
871         assert_return(service_name_is_valid(name), -EINVAL);
872         assert_return(bus->bus_client, -ENODATA);
873
874         if (!BUS_IS_OPEN(bus->state))
875                 return -ENOTCONN;
876
877         if (bus->is_kernel)
878                 return bus_get_name_creds_kdbus(bus, name, mask, false, creds);
879         else
880                 return bus_get_name_creds_dbus1(bus, name, mask, creds);
881 }
882
883 static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
884         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
885         struct kdbus_cmd_info cmd = {
886                 .size = sizeof(struct kdbus_cmd_info)
887         };
888         struct kdbus_info *creator_info;
889         pid_t pid = 0;
890         int r;
891
892         c = bus_creds_new();
893         if (!c)
894                 return -ENOMEM;
895
896         cmd.flags = attach_flags_to_kdbus(mask);
897
898         /* If augmentation is on, and the bus doesn't didn't allow us
899          * to get the bits we want, then ask for the PID/TID so that we
900          * can read the rest from /proc. */
901         if ((mask & SD_BUS_CREDS_AUGMENT) &&
902             (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
903                      SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
904                      SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
905                      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|
906                      SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
907                      SD_BUS_CREDS_SELINUX_CONTEXT|
908                      SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
909                 cmd.flags |= KDBUS_ATTACH_PIDS;
910
911         r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
912         if (r < 0)
913                 return -errno;
914
915         creator_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
916
917         r = bus_populate_creds_from_items(bus, creator_info, mask, c);
918         bus_kernel_cmd_free(bus, cmd.offset);
919         if (r < 0)
920                 return r;
921
922         r = bus_creds_add_more(c, mask, pid, 0);
923         if (r < 0)
924                 return r;
925
926         *ret = c;
927         c = NULL;
928         return 0;
929 }
930
931 static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
932         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
933         pid_t pid = 0;
934         int r;
935
936         if (!bus->ucred_valid && !isempty(bus->label))
937                 return -ENODATA;
938
939         c = bus_creds_new();
940         if (!c)
941                 return -ENOMEM;
942
943         if (bus->ucred_valid) {
944                 if (bus->ucred.pid > 0) {
945                         pid = c->pid = bus->ucred.pid;
946                         c->mask |= SD_BUS_CREDS_PID & mask;
947                 }
948
949                 if (bus->ucred.uid != UID_INVALID) {
950                         c->uid = bus->ucred.uid;
951                         c->mask |= SD_BUS_CREDS_UID & mask;
952                 }
953
954                 if (bus->ucred.gid != GID_INVALID) {
955                         c->gid = bus->ucred.gid;
956                         c->mask |= SD_BUS_CREDS_GID & mask;
957                 }
958         }
959
960         if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
961                 c->label = strdup(bus->label);
962                 if (!c->label)
963                         return -ENOMEM;
964
965                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
966         }
967
968         r = bus_creds_add_more(c, mask, pid, 0);
969         if (r < 0)
970                 return r;
971
972         *ret = c;
973         c = NULL;
974         return 0;
975 }
976
977 _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
978         assert_return(bus, -EINVAL);
979         assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
980         assert_return(ret, -EINVAL);
981         assert_return(!bus_pid_changed(bus), -ECHILD);
982
983         if (!BUS_IS_OPEN(bus->state))
984                 return -ENOTCONN;
985
986         if (bus->is_kernel)
987                 return bus_get_owner_creds_kdbus(bus, mask, ret);
988         else
989                 return bus_get_owner_creds_dbus1(bus, mask, ret);
990 }
991
992 static int add_name_change_match(sd_bus *bus,
993                                  uint64_t cookie,
994                                  const char *name,
995                                  const char *old_owner,
996                                  const char *new_owner) {
997
998         uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
999         int is_name_id = -1, r;
1000         struct kdbus_item *item;
1001
1002         assert(bus);
1003
1004         /* If we encounter a match that could match against
1005          * NameOwnerChanged messages, then we need to create
1006          * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
1007          * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
1008          * multiple if the match is underspecified.
1009          *
1010          * The NameOwnerChanged signals take three parameters with
1011          * unique or well-known names, but only some forms actually
1012          * exist:
1013          *
1014          * WELLKNOWN, "", UNIQUE       â†’ KDBUS_ITEM_NAME_ADD
1015          * WELLKNOWN, UNIQUE, ""       â†’ KDBUS_ITEM_NAME_REMOVE
1016          * WELLKNOWN, UNIQUE, UNIQUE   â†’ KDBUS_ITEM_NAME_CHANGE
1017          * UNIQUE, "", UNIQUE          â†’ KDBUS_ITEM_ID_ADD
1018          * UNIQUE, UNIQUE, ""          â†’ KDBUS_ITEM_ID_REMOVE
1019          *
1020          * For the latter two the two unique names must be identical.
1021          *
1022          * */
1023
1024         if (name) {
1025                 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
1026                 if (is_name_id < 0)
1027                         return 0;
1028         }
1029
1030         if (!isempty(old_owner)) {
1031                 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
1032                 if (r < 0)
1033                         return 0;
1034                 if (r == 0)
1035                         return 0;
1036                 if (is_name_id > 0 && old_owner_id != name_id)
1037                         return 0;
1038         } else
1039                 old_owner_id = KDBUS_MATCH_ID_ANY;
1040
1041         if (!isempty(new_owner)) {
1042                 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
1043                 if (r < 0)
1044                         return r;
1045                 if (r == 0)
1046                         return 0;
1047                 if (is_name_id > 0 && new_owner_id != name_id)
1048                         return 0;
1049         } else
1050                 new_owner_id = KDBUS_MATCH_ID_ANY;
1051
1052         if (is_name_id <= 0) {
1053                 struct kdbus_cmd_match *m;
1054                 size_t sz, l;
1055
1056                 /* If the name argument is missing or is a well-known
1057                  * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
1058                  * matches for it */
1059
1060                 l = name ? strlen(name) + 1 : 0;
1061
1062                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1063                             offsetof(struct kdbus_item, name_change) +
1064                             offsetof(struct kdbus_notify_name_change, name) +
1065                             l);
1066
1067                 m = alloca0_align(sz, 8);
1068                 m->size = sz;
1069                 m->cookie = cookie;
1070
1071                 item = m->items;
1072                 item->size =
1073                         offsetof(struct kdbus_item, name_change) +
1074                         offsetof(struct kdbus_notify_name_change, name) +
1075                         l;
1076
1077                 item->name_change.old_id.id = old_owner_id;
1078                 item->name_change.new_id.id = new_owner_id;
1079
1080                 if (name)
1081                         memcpy(item->name_change.name, name, l);
1082
1083                 /* If the old name is unset or empty, then
1084                  * this can match against added names */
1085                 if (!old_owner || old_owner[0] == 0) {
1086                         item->type = KDBUS_ITEM_NAME_ADD;
1087
1088                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1089                         if (r < 0)
1090                                 return -errno;
1091                 }
1092
1093                 /* If the new name is unset or empty, then
1094                  * this can match against removed names */
1095                 if (!new_owner || new_owner[0] == 0) {
1096                         item->type = KDBUS_ITEM_NAME_REMOVE;
1097
1098                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1099                         if (r < 0)
1100                                 return -errno;
1101                 }
1102
1103                 /* The CHANGE match we need in either case, because
1104                  * what is reported as a name change by the kernel
1105                  * might just be an owner change between starter and
1106                  * normal clients. For userspace such a change should
1107                  * be considered a removal/addition, hence let's
1108                  * subscribe to this unconditionally. */
1109                 item->type = KDBUS_ITEM_NAME_CHANGE;
1110                 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1111                 if (r < 0)
1112                         return -errno;
1113         }
1114
1115         if (is_name_id != 0) {
1116                 struct kdbus_cmd_match *m;
1117                 uint64_t sz;
1118
1119                 /* If the name argument is missing or is a unique
1120                  * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
1121                  * for it */
1122
1123                 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
1124                             offsetof(struct kdbus_item, id_change) +
1125                             sizeof(struct kdbus_notify_id_change));
1126
1127                 m = alloca0_align(sz, 8);
1128                 m->size = sz;
1129                 m->cookie = cookie;
1130
1131                 item = m->items;
1132                 item->size =
1133                         offsetof(struct kdbus_item, id_change) +
1134                         sizeof(struct kdbus_notify_id_change);
1135                 item->id_change.id = name_id;
1136
1137                 /* If the old name is unset or empty, then this can
1138                  * match against added ids */
1139                 if (!old_owner || old_owner[0] == 0) {
1140                         item->type = KDBUS_ITEM_ID_ADD;
1141
1142                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1143                         if (r < 0)
1144                                 return -errno;
1145                 }
1146
1147                 /* If thew new name is unset or empty, then this can
1148                  * match against removed ids */
1149                 if (!new_owner || new_owner[0] == 0) {
1150                         item->type = KDBUS_ITEM_ID_REMOVE;
1151
1152                         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1153                         if (r < 0)
1154                                 return -errno;
1155                 }
1156         }
1157
1158         return 0;
1159 }
1160
1161 int bus_add_match_internal_kernel(
1162                 sd_bus *bus,
1163                 struct bus_match_component *components,
1164                 unsigned n_components,
1165                 uint64_t cookie) {
1166
1167         struct kdbus_cmd_match *m;
1168         struct kdbus_item *item;
1169         uint64_t *bloom;
1170         size_t sz;
1171         const char *sender = NULL;
1172         size_t sender_length = 0;
1173         uint64_t src_id = KDBUS_MATCH_ID_ANY;
1174         bool using_bloom = false;
1175         unsigned i;
1176         bool matches_name_change = true;
1177         const char *name_change_arg[3] = {};
1178         int r;
1179
1180         assert(bus);
1181
1182         /* Monitor streams don't support matches, make this a NOP */
1183         if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1184                 return 0;
1185
1186         bloom = alloca0(bus->bloom_size);
1187
1188         sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
1189
1190         for (i = 0; i < n_components; i++) {
1191                 struct bus_match_component *c = &components[i];
1192
1193                 switch (c->type) {
1194
1195                 case BUS_MATCH_SENDER:
1196                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1197                                 matches_name_change = false;
1198
1199                         r = bus_kernel_parse_unique_name(c->value_str, &src_id);
1200                         if (r < 0)
1201                                 return r;
1202                         else if (r > 0)
1203                                 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
1204                         else  {
1205                                 sender = c->value_str;
1206                                 sender_length = strlen(sender);
1207                                 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
1208                         }
1209
1210                         break;
1211
1212                 case BUS_MATCH_MESSAGE_TYPE:
1213                         if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
1214                                 matches_name_change = false;
1215
1216                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
1217                         using_bloom = true;
1218                         break;
1219
1220                 case BUS_MATCH_INTERFACE:
1221                         if (!streq(c->value_str, "org.freedesktop.DBus"))
1222                                 matches_name_change = false;
1223
1224                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
1225                         using_bloom = true;
1226                         break;
1227
1228                 case BUS_MATCH_MEMBER:
1229                         if (!streq(c->value_str, "NameOwnerChanged"))
1230                                 matches_name_change = false;
1231
1232                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
1233                         using_bloom = true;
1234                         break;
1235
1236                 case BUS_MATCH_PATH:
1237                         if (!streq(c->value_str, "/org/freedesktop/DBus"))
1238                                 matches_name_change = false;
1239
1240                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1241                         using_bloom = true;
1242                         break;
1243
1244                 case BUS_MATCH_PATH_NAMESPACE:
1245                         if (!streq(c->value_str, "/")) {
1246                                 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1247                                 using_bloom = true;
1248                         }
1249                         break;
1250
1251                 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1252                         char buf[sizeof("arg")-1 + 2 + 1];
1253
1254                         if (c->type - BUS_MATCH_ARG < 3)
1255                                 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1256
1257                         snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1258                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1259                         using_bloom = true;
1260                         break;
1261                 }
1262
1263                 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1264                         char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1265
1266                         snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1267                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1268                         using_bloom = true;
1269                         break;
1270                 }
1271
1272                 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1273                         char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1274
1275                         snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1276                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1277                         using_bloom = true;
1278                         break;
1279                 }
1280
1281                 case BUS_MATCH_DESTINATION:
1282                         /* The bloom filter does not include
1283                            the destination, since it is only
1284                            available for broadcast messages
1285                            which do not carry a destination
1286                            since they are undirected. */
1287                         break;
1288
1289                 case BUS_MATCH_ROOT:
1290                 case BUS_MATCH_VALUE:
1291                 case BUS_MATCH_LEAF:
1292                 case _BUS_MATCH_NODE_TYPE_MAX:
1293                 case _BUS_MATCH_NODE_TYPE_INVALID:
1294                         assert_not_reached("Invalid match type?");
1295                 }
1296         }
1297
1298         if (using_bloom)
1299                 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1300
1301         m = alloca0_align(sz, 8);
1302         m->size = sz;
1303         m->cookie = cookie;
1304
1305         item = m->items;
1306
1307         if (src_id != KDBUS_MATCH_ID_ANY) {
1308                 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1309                 item->type = KDBUS_ITEM_ID;
1310                 item->id = src_id;
1311                 item = KDBUS_ITEM_NEXT(item);
1312         }
1313
1314         if (using_bloom) {
1315                 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1316                 item->type = KDBUS_ITEM_BLOOM_MASK;
1317                 memcpy(item->data64, bloom, bus->bloom_size);
1318                 item = KDBUS_ITEM_NEXT(item);
1319         }
1320
1321         if (sender) {
1322                 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1323                 item->type = KDBUS_ITEM_NAME;
1324                 memcpy(item->str, sender, sender_length + 1);
1325         }
1326
1327         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1328         if (r < 0)
1329                 return -errno;
1330
1331         if (matches_name_change) {
1332
1333                 /* If this match could theoretically match
1334                  * NameOwnerChanged messages, we need to
1335                  * install a second non-bloom filter explitly
1336                  * for it */
1337
1338                 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1339                 if (r < 0)
1340                         return r;
1341         }
1342
1343         return 0;
1344 }
1345
1346 #define internal_match(bus, m)                                          \
1347         ((bus)->hello_flags & KDBUS_HELLO_MONITOR                       \
1348          ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1349          : (m))
1350
1351 static int bus_add_match_internal_dbus1(
1352                 sd_bus *bus,
1353                 const char *match) {
1354
1355         const char *e;
1356
1357         assert(bus);
1358         assert(match);
1359
1360         e = internal_match(bus, match);
1361
1362         return sd_bus_call_method(
1363                         bus,
1364                         "org.freedesktop.DBus",
1365                         "/org/freedesktop/DBus",
1366                         "org.freedesktop.DBus",
1367                         "AddMatch",
1368                         NULL,
1369                         NULL,
1370                         "s",
1371                         e);
1372 }
1373
1374 int bus_add_match_internal(
1375                 sd_bus *bus,
1376                 const char *match,
1377                 struct bus_match_component *components,
1378                 unsigned n_components,
1379                 uint64_t cookie) {
1380
1381         assert(bus);
1382
1383         if (bus->is_kernel)
1384                 return bus_add_match_internal_kernel(bus, components, n_components, cookie);
1385         else
1386                 return bus_add_match_internal_dbus1(bus, match);
1387 }
1388
1389 int bus_remove_match_internal_kernel(
1390                 sd_bus *bus,
1391                 uint64_t cookie) {
1392
1393         struct kdbus_cmd_match m;
1394         int r;
1395
1396         assert(bus);
1397
1398         /* Monitor streams don't support matches, make this a NOP */
1399         if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1400                 return 0;
1401
1402         zero(m);
1403         m.size = offsetof(struct kdbus_cmd_match, items);
1404         m.cookie = cookie;
1405
1406         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1407         if (r < 0)
1408                 return -errno;
1409
1410         return 0;
1411 }
1412
1413 static int bus_remove_match_internal_dbus1(
1414                 sd_bus *bus,
1415                 const char *match) {
1416
1417         const char *e;
1418
1419         assert(bus);
1420         assert(match);
1421
1422         e = internal_match(bus, match);
1423
1424         return sd_bus_call_method(
1425                         bus,
1426                         "org.freedesktop.DBus",
1427                         "/org/freedesktop/DBus",
1428                         "org.freedesktop.DBus",
1429                         "RemoveMatch",
1430                         NULL,
1431                         NULL,
1432                         "s",
1433                         e);
1434 }
1435
1436 int bus_remove_match_internal(
1437                 sd_bus *bus,
1438                 const char *match,
1439                 uint64_t cookie) {
1440
1441         assert(bus);
1442
1443         if (bus->is_kernel)
1444                 return bus_remove_match_internal_kernel(bus, cookie);
1445         else
1446                 return bus_remove_match_internal_dbus1(bus, match);
1447 }
1448
1449 _public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1450         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1451         const char *mid;
1452         int r;
1453
1454         assert_return(bus, -EINVAL);
1455         assert_return(name, -EINVAL);
1456         assert_return(machine, -EINVAL);
1457         assert_return(!bus_pid_changed(bus), -ECHILD);
1458         assert_return(service_name_is_valid(name), -EINVAL);
1459
1460         if (!BUS_IS_OPEN(bus->state))
1461                 return -ENOTCONN;
1462
1463         if (streq_ptr(name, bus->unique_name))
1464                 return sd_id128_get_machine(machine);
1465
1466         r = sd_bus_message_new_method_call(
1467                         bus,
1468                         &m,
1469                         name,
1470                         "/",
1471                         "org.freedesktop.DBus.Peer",
1472                         "GetMachineId");
1473         if (r < 0)
1474                 return r;
1475
1476         r = sd_bus_message_set_auto_start(m, false);
1477         if (r < 0)
1478                 return r;
1479
1480         r = sd_bus_call(bus, m, 0, NULL, &reply);
1481         if (r < 0)
1482                 return r;
1483
1484         r = sd_bus_message_read(reply, "s", &mid);
1485         if (r < 0)
1486                 return r;
1487
1488         return sd_id128_from_string(mid, machine);
1489 }