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