]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-internal.h
udev: gracefully handle ENODEV or friends in opening device node
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-internal.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
de1c301e
LP
2#pragma once
3
5cdf13c7 4#include "sd-id128.h"
de1c301e 5
d117687a 6#include "bus-forward.h"
bc7fd8cd 7#include "bus-kernel.h"
07630cea 8#include "bus-match.h"
28db6fbf 9#include "constants.h"
07630cea 10#include "list.h"
4870133b 11#include "runtime-scope.h"
07630cea 12#include "socket-util.h"
de1c301e 13
47094ce0
LP
14/* Note that we use the new /run prefix here (instead of /var/run) since we require them to be aliases and
15 * that way we become independent of /var being mounted */
16#define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket"
17#define DEFAULT_USER_BUS_ADDRESS_FMT "unix:path=%s/bus"
18
d117687a 19typedef struct BusReplyCallback {
52f3ba91 20 sd_bus_message_handler_t callback;
ac8029fc 21 usec_t timeout_usec; /* this is a relative timeout until we reach the BUS_HELLO state, and an absolute one right after */
693eb9a2 22 uint64_t cookie;
e3017af9 23 unsigned prioq_idx;
d117687a 24} BusReplyCallback;
de1c301e 25
d117687a 26typedef struct BusFilterCallback {
52f3ba91 27 sd_bus_message_handler_t callback;
de1c301e 28
7286037f
LP
29 unsigned last_iteration;
30
d117687a
YW
31 LIST_FIELDS(BusFilterCallback, callbacks);
32} BusFilterCallback;
de1c301e 33
d117687a 34typedef struct BusNode {
29ddb38f 35 char *path;
d117687a
YW
36 BusNode *parent;
37 LIST_HEAD(BusNode, child);
38 LIST_FIELDS(BusNode, siblings);
29ddb38f 39
d117687a
YW
40 LIST_HEAD(BusNodeCallback, callbacks);
41 LIST_HEAD(BusNodeVTable, vtables);
42 LIST_HEAD(BusNodeEnumerator, enumerators);
43 LIST_HEAD(BusNodeObjectManager, object_managers);
44} BusNode;
29ddb38f 45
d117687a
YW
46typedef struct BusNodeCallback {
47 BusNode *node;
29ddb38f 48
519ae503 49 bool is_fallback;
29ddb38f
LP
50 unsigned last_iteration;
51
0a6991e0
LP
52 sd_bus_message_handler_t callback;
53
d117687a
YW
54 LIST_FIELDS(BusNodeCallback, callbacks);
55} BusNodeCallback;
29ddb38f 56
d117687a
YW
57typedef struct BusNodeEnumerator {
58 BusNode *node;
29ddb38f
LP
59
60 sd_bus_node_enumerator_t callback;
29ddb38f
LP
61
62 unsigned last_iteration;
63
d117687a
YW
64 LIST_FIELDS(BusNodeEnumerator, enumerators);
65} BusNodeEnumerator;
29ddb38f 66
d117687a
YW
67typedef struct BusNodeObjectManager {
68 BusNode *node;
19befb2d 69
d117687a
YW
70 LIST_FIELDS(BusNodeObjectManager, object_managers);
71} BusNodeObjectManager;
19befb2d 72
d117687a
YW
73typedef struct BusNodeVTable {
74 BusNode *node;
29ddb38f 75
519ae503 76 bool is_fallback;
0a6991e0
LP
77 unsigned last_iteration;
78
29ddb38f 79 char *interface;
29ddb38f 80 const sd_bus_vtable *vtable;
29ddb38f 81 sd_bus_object_find_t find;
7286037f 82
d117687a
YW
83 LIST_FIELDS(BusNodeVTable, vtables);
84} BusNodeVTable;
29ddb38f 85
d117687a 86typedef struct BusVTableMember {
29ddb38f
LP
87 const char *path;
88 const char *interface;
89 const char *member;
d117687a 90 BusNodeVTable *parent;
29ddb38f
LP
91 unsigned last_iteration;
92 const sd_bus_vtable *vtable;
d117687a 93} BusVTableMember;
a652755d 94
19befb2d 95typedef enum BusSlotType {
19befb2d
LP
96 BUS_REPLY_CALLBACK,
97 BUS_FILTER_CALLBACK,
98 BUS_MATCH_CALLBACK,
99 BUS_NODE_CALLBACK,
100 BUS_NODE_ENUMERATOR,
101 BUS_NODE_VTABLE,
102 BUS_NODE_OBJECT_MANAGER,
2d93c20e 103 _BUS_SLOT_INVALID = -EINVAL,
19befb2d
LP
104} BusSlotType;
105
5cdf13c7 106typedef struct sd_bus_slot {
19befb2d 107 unsigned n_ref;
38d1e120
ZJS
108 BusSlotType type:8;
109
110 /* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the
111 * bus object they are associated with. This means the bus object stays allocated at least as long as
112 * there is a slot around associated with it. If it is floating, then the slot's lifecycle is bound
113 * to the lifecycle of the bus: it will be disconnected from the bus when the bus is destroyed, and
114 * it keeping the slot reffed hence won't mean the bus stays reffed too. Internally this means the
115 * reference direction is reversed: floating slots objects are referenced by the bus object, and not
116 * vice versa. */
117 bool floating;
118 bool match_added;
0a6991e0
LP
119
120 sd_bus *bus;
121 void *userdata;
122 sd_bus_destroy_t destroy_callback;
123
9cbfc66c 124 char *description;
19befb2d
LP
125
126 LIST_FIELDS(sd_bus_slot, slots);
127
128 union {
d117687a
YW
129 BusReplyCallback reply_callback;
130 BusFilterCallback filter_callback;
131 BusMatchCallback match_callback;
132 BusNodeCallback node_callback;
133 BusNodeEnumerator node_enumerator;
134 BusNodeObjectManager node_object_manager;
135 BusNodeVTable node_vtable;
19befb2d 136 };
5cdf13c7 137} sd_bus_slot;
19befb2d 138
d117687a 139typedef enum BusState {
021a1e78 140 BUS_UNSET,
ac8029fc
LP
141 BUS_WATCH_BIND, /* waiting for the socket to appear via inotify */
142 BUS_OPENING, /* the kernel's connect() is still not ready */
143 BUS_AUTHENTICATING, /* we are currently in the "SASL" authorization phase of dbus */
144 BUS_HELLO, /* we are waiting for the Hello() response */
f54514f3 145 BUS_RUNNING,
718db961 146 BUS_CLOSING,
3e0e196e
LP
147 BUS_CLOSED,
148 _BUS_STATE_MAX,
d117687a 149} BusState;
de1c301e 150
d117687a 151static inline bool BUS_IS_OPEN(BusState state) {
718db961 152 return state > BUS_UNSET && state < BUS_CLOSING;
f54514f3
LP
153}
154
d117687a 155typedef enum BusAuth {
2181a7f5
LP
156 _BUS_AUTH_INVALID,
157 BUS_AUTH_EXTERNAL,
158 BUS_AUTH_ANONYMOUS
d117687a 159} BusAuth;
2181a7f5 160
5cdf13c7 161typedef struct sd_bus {
42541a71 162 unsigned n_ref;
e4ee6e5c 163
d117687a 164 BusState state;
e82c9509 165 int input_fd, output_fd;
8a5cd31e 166 int inotify_fd;
de1c301e 167 int message_version;
0f437184 168 int message_endian;
021a1e78 169
519ae503
ZJS
170 bool can_fds;
171 bool bus_client;
172 bool ucred_valid;
173 bool is_server;
174 bool anonymous_auth;
175 bool prefer_readv;
176 bool prefer_writev;
177 bool match_callbacks_modified;
178 bool filter_callbacks_modified;
179 bool nodes_modified;
180 bool trusted;
181 bool manual_peer_interface;
182 bool allow_interactive_authorization;
183 bool exit_on_disconnect;
184 bool exited;
185 bool exit_triggered;
186 bool is_local;
187 bool watch_bind;
188 bool is_monitor;
189 bool accept_fd;
190 bool attach_timestamp;
191 bool connected_signal;
192 bool close_on_exit;
de1c301e 193
4870133b
LP
194 RuntimeScope runtime_scope;
195
519ae503 196 int use_memfd;
8f155917 197
de1c301e
LP
198 void *rbuffer;
199 size_t rbuffer_size;
200
201 sd_bus_message **rqueue;
143d4e04 202 size_t rqueue_size;
de1c301e
LP
203
204 sd_bus_message **wqueue;
143d4e04 205 size_t wqueue_size;
de1c301e
LP
206 size_t windex;
207
693eb9a2 208 uint64_t cookie;
f1617a3b 209 uint64_t read_counter; /* A counter for each incoming msg */
de1c301e
LP
210
211 char *unique_name;
219728b3 212 uint64_t unique_id;
de1c301e 213
d117687a 214 BusMatchNode match_callbacks;
e3017af9 215 Prioq *reply_callbacks_prioq;
c9fe4af7 216 OrderedHashmap *reply_callbacks;
d117687a 217 LIST_HEAD(BusFilterCallback, filter_callbacks);
29ddb38f
LP
218
219 Hashmap *nodes;
b87501ea
YW
220 Set *vtable_methods;
221 Set *vtable_properties;
de1c301e 222
3cb46740 223 union sockaddr_union sockaddr;
de1c301e
LP
224 socklen_t sockaddr_size;
225
ee502e0c 226 pid_t nspid;
0a6991e0 227 char *machine;
6629161f 228
98178d39 229 sd_id128_t server_id;
de1c301e
LP
230
231 char *address;
232 unsigned address_index;
233
fc772c61
LP
234 uid_t connect_as_uid;
235 gid_t connect_as_gid;
236
de1c301e
LP
237 int last_connect_error;
238
d117687a 239 BusAuth auth;
de1c301e 240 unsigned auth_index;
0a6991e0
LP
241 struct iovec auth_iovec[3];
242 size_t auth_rbegin;
2181a7f5 243 char *auth_buffer;
e3017af9 244 usec_t auth_timeout;
2571ead1
LP
245
246 struct ucred ucred;
c4e6556c 247 char *label;
18ac4643
LP
248 gid_t *groups;
249 size_t n_groups;
c32f9648
LP
250 union sockaddr_union sockaddr_peer;
251 socklen_t sockaddr_size_peer;
71be6406 252 int pidfd;
2c93b4ef 253
5b12334d
LP
254 uint64_t creds_mask;
255
2c93b4ef 256 int *fds;
da6053d0 257 size_t n_fds;
2fd9ae2e
LP
258
259 char *exec_path;
260 char **exec_argv;
9d373862 261
45fbe937
LP
262 /* We do locking around the memfd cache, since we want to
263 * allow people to process a sd_bus_message in a different
264 * thread then it was generated on and free it there. Since
265 * adding something to the memfd cache might happen when a
266 * message is released, we hence need to protect this bit with
267 * a mutex. */
268 pthread_mutex_t memfd_cache_mutex;
bc7fd8cd
LP
269 struct memfd_cache memfd_cache[MEMFD_CACHE_MAX];
270 unsigned n_memfd_cache;
d5a2b9a6 271
bf876e3f 272 uint64_t origin_id;
392cf1d0 273 pid_t busexec_pid;
264ad849 274
0a6991e0
LP
275 unsigned iteration_counter;
276
40ca29a1
LP
277 sd_event_source *input_io_event_source;
278 sd_event_source *output_io_event_source;
279 sd_event_source *time_event_source;
abc5fe72 280 sd_event_source *quit_event_source;
8a5cd31e 281 sd_event_source *inotify_event_source;
40ca29a1 282 sd_event *event;
1e05d493 283 int event_priority;
affff0b6 284
0a6991e0
LP
285 pid_t tid;
286
19befb2d
LP
287 sd_bus_message *current_message;
288 sd_bus_slot *current_slot;
caa82984
LP
289 sd_bus_message_handler_t current_handler;
290 void *current_userdata;
76b54375
LP
291
292 sd_bus **default_bus_ptr;
8a0e0ed9 293
455971c1 294 char *description;
48ef41a3 295 char *patch_sender;
b28ff39f 296
8f8f05a9 297 sd_bus_track *track_queue;
19befb2d
LP
298
299 LIST_HEAD(sd_bus_slot, slots);
232f3677 300 LIST_HEAD(sd_bus_track, tracks);
8a5cd31e
LP
301
302 int *inotify_watches;
303 size_t n_inotify_watches;
385b2eb2
YW
304
305 /* zero means use value specified by $SYSTEMD_BUS_TIMEOUT= environment variable or built-in default */
306 usec_t method_call_timeout;
5cdf13c7 307} sd_bus;
e3017af9 308
3f9a0a52 309/* For method calls we timeout at 25s, like in the D-Bus reference implementation */
e3017af9 310#define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
25220239 311
036d61b3
LP
312/* For the authentication phase we grant 90s, to provide extra room during boot, when RNGs and such are not filled up
313 * with enough entropy yet and might delay the boot */
314#define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC)
315
83a32ea7
FB
316#define BUS_WQUEUE_MAX (384*1024)
317#define BUS_RQUEUE_MAX (384*1024)
25220239 318
33d8fe60 319#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
25220239 320#define BUS_AUTH_SIZE_MAX (64*1024)
61397a60
RS
321/* Note that the D-Bus specification states that bus paths shall have no size limit. We enforce here one
322 * anyway, since truly unbounded strings are a security problem. The limit we pick is relatively large however,
323 * to not clash unnecessarily with real-life applications. */
324#define BUS_PATH_SIZE_MAX (64*1024)
ac89bf1d 325
ed205a6b
LP
326#define BUS_CONTAINER_DEPTH 128
327
385b2eb2 328/* Defined by the specification as maximum size of an array in bytes */
ac89bf1d
LP
329#define BUS_ARRAY_MAX_SIZE 67108864
330
2c93b4ef
LP
331#define BUS_FDS_MAX 1024
332
2fd9ae2e
LP
333#define BUS_EXEC_ARGV_MAX 256
334
0ce036ce
LP
335bool interface_name_is_valid(const char *p) _pure_;
336bool service_name_is_valid(const char *p) _pure_;
337bool member_name_is_valid(const char *p) _pure_;
338bool object_path_is_valid(const char *p) _pure_;
d2916409 339
ff3f2953 340char* object_path_startswith(const char *a, const char *b) _pure_;
6693860f 341
0ce036ce
LP
342bool namespace_complex_pattern(const char *pattern, const char *value) _pure_;
343bool path_complex_pattern(const char *pattern, const char *value) _pure_;
392d5b37 344
0ce036ce
LP
345bool namespace_simple_pattern(const char *pattern, const char *value) _pure_;
346bool path_simple_pattern(const char *pattern, const char *value) _pure_;
392d5b37 347
6723c28f 348int bus_message_type_from_string(const char *s, uint8_t *u);
bfd5a068 349const char* bus_message_type_to_string(uint8_t u) _pure_;
392d5b37 350
6693860f 351#define error_name_is_valid interface_name_is_valid
20902f3e 352
45b1f410
NM
353sd_bus *bus_resolve(sd_bus *bus);
354
20902f3e 355int bus_ensure_running(sd_bus *bus);
a7e3212d
LP
356int bus_start_running(sd_bus *bus);
357int bus_next_address(sd_bus *bus);
d5a2b9a6 358
7adc46fc 359int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m);
777d7a61 360
7adc46fc 361int bus_rqueue_make_room(sd_bus *bus);
7d22c717 362
bf876e3f 363bool bus_origin_changed(sd_bus *bus);
92e189e5 364
ff3f2953 365char* bus_address_escape(const char *v);
0f8bd8de 366
8a5cd31e
LP
367int bus_attach_io_events(sd_bus *b);
368int bus_attach_inotify_event(sd_bus *b);
369
370void bus_close_inotify_fd(sd_bus *b);
371void bus_close_io_fds(sd_bus *b);
372
bb30e58f 373int bus_add_match_full(
374 sd_bus *bus,
375 sd_bus_slot **slot,
376 bool asynchronous,
377 const char *match,
378 sd_bus_message_handler_t callback,
379 sd_bus_message_handler_t install_callback,
380 void *userdata,
381 uint64_t timeout_usec);
382
92e189e5
LP
383#define OBJECT_PATH_FOREACH_PREFIX(prefix, path) \
384 for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \
283c2653 385 _slash && ((_slash[(_slash) == (prefix)] = 0), true); \
92e189e5 386 _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/'))
8ce2afd6
LP
387
388/* If we are invoking callbacks of a bus object, ensure unreffing the
385b2eb2 389 * bus from the callback doesn't destroy the object we are working on */
8ce2afd6 390#define BUS_DONT_DESTROY(bus) \
4afd3348 391 _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)
09365592
LP
392
393int bus_set_address_system(sd_bus *bus);
394int bus_set_address_user(sd_bus *bus);
395int bus_set_address_system_remote(sd_bus *b, const char *host);
4870133b 396int bus_set_address_machine(sd_bus *b, RuntimeScope runtime_scope, const char *machine);
19befb2d 397
31a1e15c 398int bus_maybe_reply_error(sd_bus_message *m, int r, const sd_bus_error *e);
d4d00020 399
759e02e7
LP
400#define bus_assert_return(expr, r, error) \
401 do { \
34c38d2a 402 if (!assert_log(expr, #expr)) \
759e02e7
LP
403 return sd_bus_error_set_errno(error, r); \
404 } while (false)
98c5bbc8
LP
405
406void bus_enter_closing(sd_bus *bus);
3e0e196e 407
d117687a 408void bus_set_state(sd_bus *bus, BusState state);