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