Bug Summary

File:build-scan/../src/core/dbus.c
Warning:line 514, column 33
Potential leak of memory pointed to by 'l'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name dbus.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/core/libcore.a.p -I src/core -I ../src/core -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/libmount -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/core/dbus.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <errno(*__errno_location ()).h>
4#include <sys/epoll.h>
5#include <unistd.h>
6
7#include "sd-bus.h"
8
9#include "alloc-util.h"
10#include "bus-common-errors.h"
11#include "bus-error.h"
12#include "bus-internal.h"
13#include "bus-util.h"
14#include "dbus-automount.h"
15#include "dbus-cgroup.h"
16#include "dbus-device.h"
17#include "dbus-execute.h"
18#include "dbus-job.h"
19#include "dbus-kill.h"
20#include "dbus-manager.h"
21#include "dbus-mount.h"
22#include "dbus-path.h"
23#include "dbus-scope.h"
24#include "dbus-service.h"
25#include "dbus-slice.h"
26#include "dbus-socket.h"
27#include "dbus-swap.h"
28#include "dbus-target.h"
29#include "dbus-timer.h"
30#include "dbus-unit.h"
31#include "dbus.h"
32#include "fd-util.h"
33#include "fs-util.h"
34#include "log.h"
35#include "missing.h"
36#include "mkdir.h"
37#include "process-util.h"
38#include "selinux-access.h"
39#include "service.h"
40#include "special.h"
41#include "string-util.h"
42#include "strv.h"
43#include "strxcpyx.h"
44#include "user-util.h"
45
46#define CONNECTIONS_MAX4096 4096
47
48static void destroy_bus(Manager *m, sd_bus **bus);
49
50int bus_send_pending_reload_message(Manager *m) {
51 int r;
52
53 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 53, __PRETTY_FUNCTION__
); } while (0)
;
54
55 if (!m->pending_reload_message)
56 return 0;
57
58 /* If we cannot get rid of this message we won't dispatch any D-Bus messages, so that we won't end up wanting
59 * to queue another message. */
60
61 r = sd_bus_send(NULL((void*)0), m->pending_reload_message, NULL((void*)0));
62 if (r < 0)
63 log_warning_errno(r, "Failed to send queued message, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 63, __func__, "Failed to send queued message, ignoring: %m"
) : -abs(_e); })
;
64
65 m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
66
67 return 0;
68}
69
70int bus_forward_agent_released(Manager *m, const char *path) {
71 int r;
72
73 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 73, __PRETTY_FUNCTION__
); } while (0)
;
74 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 74, __PRETTY_FUNCTION__
); } while (0)
;
75
76 if (!MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM))
77 return 0;
78
79 if (!m->system_bus)
80 return 0;
81
82 /* If we are running a system instance we forward the agent message on the system bus, so that the user
83 * instances get notified about this, too */
84
85 r = sd_bus_emit_signal(m->system_bus,
86 "/org/freedesktop/systemd1/agent",
87 "org.freedesktop.systemd1.Agent",
88 "Released",
89 "s", path);
90 if (r < 0)
91 return log_debug_errno(r, "Failed to propagate agent release message: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 91, __func__, "Failed to propagate agent release message: %m"
) : -abs(_e); })
;
92
93 return 1;
94}
95
96static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
97 _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0);
98 Manager *m = userdata;
99 const char *cgroup;
100 uid_t sender_uid;
101 int r;
102
103 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 103, __PRETTY_FUNCTION__
); } while (0)
;
104 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 104, __PRETTY_FUNCTION__
); } while (0)
;
105
106 /* only accept org.freedesktop.systemd1.Agent from UID=0 */
107 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
108 if (r < 0)
109 return r;
110
111 r = sd_bus_creds_get_euid(creds, &sender_uid);
112 if (r < 0 || sender_uid != 0)
113 return 0;
114
115 /* parse 'cgroup-empty' notification */
116 r = sd_bus_message_read(message, "s", &cgroup);
117 if (r < 0) {
118 bus_log_parse_error(r);
119 return 0;
120 }
121
122 manager_notify_cgroup_empty(m, cgroup);
123 return 0;
124}
125
126static int signal_disconnected(sd_bus_message *message, void *userdata, sd_bus_error *error) {
127 Manager *m = userdata;
128 sd_bus *bus;
129
130 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 130, __PRETTY_FUNCTION__
); } while (0)
;
131 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 131, __PRETTY_FUNCTION__
); } while (0)
;
132 assert_se(bus = sd_bus_message_get_bus(message))do { if ((__builtin_expect(!!(!(bus = sd_bus_message_get_bus(
message))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("bus = sd_bus_message_get_bus(message)"
), "../src/core/dbus.c", 132, __PRETTY_FUNCTION__); } while (
0)
;
133
134 if (bus == m->api_bus)
135 bus_done_api(m);
136 if (bus == m->system_bus)
137 bus_done_system(m);
138
139 if (set_remove(m->private_buses, bus)) {
140 log_debug("Got disconnect on private connection.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 140, __func__, "Got disconnect on private connection."
) : -abs(_e); })
;
141 destroy_bus(m, &bus);
142 }
143
144 return 0;
145}
146
147static int signal_activation_request(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
148 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
149 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
150 Manager *m = userdata;
151 const char *name;
152 Unit *u;
153 int r;
154
155 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 155, __PRETTY_FUNCTION__
); } while (0)
;
156 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 156, __PRETTY_FUNCTION__
); } while (0)
;
157
158 r = sd_bus_message_read(message, "s", &name);
159 if (r < 0) {
160 bus_log_parse_error(r);
161 return 0;
162 }
163
164 if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE"dbus.service") ||
165 manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET"dbus.socket")) {
166 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN"org.freedesktop.systemd1.ShuttingDown", "Refusing activation, D-Bus is shutting down.");
167 goto failed;
168 }
169
170 r = manager_load_unit(m, name, NULL((void*)0), &error, &u);
171 if (r < 0)
172 goto failed;
173
174 if (u->refuse_manual_start) {
175 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY"org.freedesktop.systemd1.OnlyByDependency", "Operation refused, %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
176 goto failed;
177 }
178
179 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0));
180 if (r < 0)
181 goto failed;
182
183 /* Successfully queued, that's it for us */
184 return 0;
185
186failed:
187 if (!sd_bus_error_is_set(&error))
188 sd_bus_error_set_errno(&error, r);
189
190 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 190, __func__, "D-Bus activation failed for %s: %s"
, name, bus_error_message(&error, r)) : -abs(_e); })
;
191
192 r = sd_bus_message_new_signal(sd_bus_message_get_bus(message), &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
193 if (r < 0) {
194 bus_log_create_error(r);
195 return 0;
196 }
197
198 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
199 if (r < 0) {
200 bus_log_create_error(r);
201 return 0;
202 }
203
204 r = sd_bus_send_to(NULL((void*)0), reply, "org.freedesktop.DBus", NULL((void*)0));
205 if (r < 0)
206 return log_error_errno(r, "Failed to respond with to bus activation request: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 206, __func__, "Failed to respond with to bus activation request: %m"
) : -abs(_e); })
;
207
208 return 0;
209}
210
211#if HAVE_SELINUX1
212static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_error *error) {
213 Manager *m = userdata;
214 const char *verb, *path;
215 Unit *u = NULL((void*)0);
216 Job *j;
217 int r;
218
219 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/core/dbus.c", 219, __PRETTY_FUNCTION__
); } while (0)
;
220
221 /* Our own method calls are all protected individually with
222 * selinux checks, but the built-in interfaces need to be
223 * protected too. */
224
225 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
226 verb = "reload";
227 else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL((void*)0)) ||
228 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL((void*)0)) ||
229 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL((void*)0)) ||
230 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL((void*)0)))
231 verb = "status";
232 else
233 return 0;
234
235 path = sd_bus_message_get_path(message);
236
237 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
238 r = mac_selinux_access_check(message, verb, error)mac_selinux_generic_access_check((message), ((void*)0), (verb
), (error))
;
239 if (r < 0)
240 return r;
241
242 return 0;
243 }
244
245 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
246 _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0);
247 pid_t pid;
248
249 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
250 if (r < 0)
251 return 0;
252
253 r = sd_bus_creds_get_pid(creds, &pid);
254 if (r < 0)
255 return 0;
256
257 u = manager_get_unit_by_pid(m, pid);
258 } else {
259 r = manager_get_job_from_dbus_path(m, path, &j);
260 if (r >= 0)
261 u = j->unit;
262 else
263 manager_load_unit_from_dbus_path(m, path, NULL((void*)0), &u);
264 }
265 if (!u)
266 return 0;
267
268 r = mac_selinux_unit_access_check(u, message, verb, error)mac_selinux_generic_access_check((message), unit_label_path(u
), (verb), (error))
;
269 if (r < 0)
270 return r;
271
272 return 0;
273}
274#endif
275
276static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
277 Manager *m = userdata;
278 Job *j;
279 int r;
280
281 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 281, __PRETTY_FUNCTION__
); } while (0)
;
282 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 282, __PRETTY_FUNCTION__
); } while (0)
;
283 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 283,
__PRETTY_FUNCTION__); } while (0)
;
284 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 284, __PRETTY_FUNCTION__
); } while (0)
;
285 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 285, __PRETTY_FUNCTION__
); } while (0)
;
286
287 r = manager_get_job_from_dbus_path(m, path, &j);
288 if (r < 0)
289 return 0;
290
291 *found = j;
292 return 1;
293}
294
295static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
296 Unit *u = NULL((void*)0); /* just to appease gcc, initialization is not really necessary */
297 int r;
298
299 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 299, __PRETTY_FUNCTION__
); } while (0)
;
300 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 300, __PRETTY_FUNCTION__
); } while (0)
;
301 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 301, __PRETTY_FUNCTION__
); } while (0)
;
302
303 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
304 _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0);
305 sd_bus_message *message;
306 pid_t pid;
307
308 message = sd_bus_get_current_message(bus);
309 if (!message)
310 return 0;
311
312 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
313 if (r < 0)
314 return r;
315
316 r = sd_bus_creds_get_pid(creds, &pid);
317 if (r < 0)
318 return r;
319
320 u = manager_get_unit_by_pid(m, pid);
321 if (!u)
322 return 0;
323 } else {
324 r = manager_load_unit_from_dbus_path(m, path, error, &u);
325 if (r < 0)
326 return 0;
327 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/dbus.c", 327, __PRETTY_FUNCTION__
); } while (0)
;
328 }
329
330 *unit = u;
331 return 1;
332}
333
334static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
335 Manager *m = userdata;
336
337 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 337, __PRETTY_FUNCTION__
); } while (0)
;
338 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 338, __PRETTY_FUNCTION__
); } while (0)
;
339 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 339,
__PRETTY_FUNCTION__); } while (0)
;
340 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 340, __PRETTY_FUNCTION__
); } while (0)
;
341 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 341, __PRETTY_FUNCTION__
); } while (0)
;
342
343 return find_unit(m, bus, path, (Unit**) found, error);
344}
345
346static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
347 Manager *m = userdata;
348 Unit *u;
349 int r;
350
351 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 351, __PRETTY_FUNCTION__
); } while (0)
;
352 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 352, __PRETTY_FUNCTION__
); } while (0)
;
353 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 353,
__PRETTY_FUNCTION__); } while (0)
;
354 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 354, __PRETTY_FUNCTION__
); } while (0)
;
355 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 355, __PRETTY_FUNCTION__
); } while (0)
;
356
357 r = find_unit(m, bus, path, &u, error);
358 if (r <= 0)
359 return r;
360
361 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
362 return 0;
363
364 *found = u;
365 return 1;
366}
367
368static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
369 Manager *m = userdata;
370 Unit *u;
371 int r;
372
373 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 373, __PRETTY_FUNCTION__
); } while (0)
;
374 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 374, __PRETTY_FUNCTION__
); } while (0)
;
375 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 375,
__PRETTY_FUNCTION__); } while (0)
;
376 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 376, __PRETTY_FUNCTION__
); } while (0)
;
377 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 377, __PRETTY_FUNCTION__
); } while (0)
;
378
379 r = find_unit(m, bus, path, &u, error);
380 if (r <= 0)
381 return r;
382
383 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
384 return 0;
385
386 if (!UNIT_HAS_CGROUP_CONTEXT(u)(unit_vtable[(u)->type]->cgroup_context_offset > 0))
387 return 0;
388
389 *found = u;
390 return 1;
391}
392
393static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
394 Manager *m = userdata;
395 CGroupContext *c;
396 Unit *u;
397 int r;
398
399 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 399, __PRETTY_FUNCTION__
); } while (0)
;
400 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 400, __PRETTY_FUNCTION__
); } while (0)
;
401 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 401,
__PRETTY_FUNCTION__); } while (0)
;
402 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 402, __PRETTY_FUNCTION__
); } while (0)
;
403 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 403, __PRETTY_FUNCTION__
); } while (0)
;
404
405 r = find_unit(m, bus, path, &u, error);
406 if (r <= 0)
407 return r;
408
409 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
410 return 0;
411
412 c = unit_get_cgroup_context(u);
413 if (!c)
414 return 0;
415
416 *found = c;
417 return 1;
418}
419
420static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
421 Manager *m = userdata;
422 ExecContext *c;
423 Unit *u;
424 int r;
425
426 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 426, __PRETTY_FUNCTION__
); } while (0)
;
427 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 427, __PRETTY_FUNCTION__
); } while (0)
;
428 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 428,
__PRETTY_FUNCTION__); } while (0)
;
429 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 429, __PRETTY_FUNCTION__
); } while (0)
;
430 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 430, __PRETTY_FUNCTION__
); } while (0)
;
431
432 r = find_unit(m, bus, path, &u, error);
433 if (r <= 0)
434 return r;
435
436 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
437 return 0;
438
439 c = unit_get_exec_context(u);
440 if (!c)
441 return 0;
442
443 *found = c;
444 return 1;
445}
446
447static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
448 Manager *m = userdata;
449 KillContext *c;
450 Unit *u;
451 int r;
452
453 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 453, __PRETTY_FUNCTION__
); } while (0)
;
454 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/dbus.c", 454, __PRETTY_FUNCTION__
); } while (0)
;
455 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/core/dbus.c", 455,
__PRETTY_FUNCTION__); } while (0)
;
456 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/core/dbus.c", 456, __PRETTY_FUNCTION__
); } while (0)
;
457 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 457, __PRETTY_FUNCTION__
); } while (0)
;
458
459 r = find_unit(m, bus, path, &u, error);
460 if (r <= 0)
461 return r;
462
463 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
464 return 0;
465
466 c = unit_get_kill_context(u);
467 if (!c)
468 return 0;
469
470 *found = c;
471 return 1;
472}
473
474static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
475 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
476 Manager *m = userdata;
477 unsigned k = 0;
478 Iterator i;
479 Job *j;
480
481 l = new0(char*, hashmap_size(m->jobs)+1)((char**) calloc((hashmap_size(m->jobs)+1), sizeof(char*))
)
;
482 if (!l)
483 return -ENOMEM12;
484
485 HASHMAP_FOREACH(j, m->jobs, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->jobs), &
(i), (void**)&(j), ((void*)0)); )
{
486 l[k] = job_dbus_path(j);
487 if (!l[k])
488 return -ENOMEM12;
489
490 k++;
491 }
492
493 assert(hashmap_size(m->jobs) == k)do { if ((__builtin_expect(!!(!(hashmap_size(m->jobs) == k
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("hashmap_size(m->jobs) == k"
), "../src/core/dbus.c", 493, __PRETTY_FUNCTION__); } while (
0)
;
494
495 *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
496
497 return k;
498}
499
500static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
501 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
502 Manager *m = userdata;
503 unsigned k = 0;
504 Iterator i;
505 Unit *u;
506
507 l = new0(char*, hashmap_size(m->units)+1)((char**) calloc((hashmap_size(m->units)+1), sizeof(char*)
))
;
1
Memory is allocated
508 if (!l)
2
Assuming 'l' is non-null
3
Taking false branch
509 return -ENOMEM12;
510
511 HASHMAP_FOREACH(u, m->units, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->units), &
(i), (void**)&(u), ((void*)0)); )
{
4
Loop condition is true. Entering loop body
512 l[k] = unit_dbus_path(u);
513 if (!l[k])
5
Assuming the condition is true
6
Taking true branch
514 return -ENOMEM12;
7
Potential leak of memory pointed to by 'l'
515
516 k++;
517 }
518
519 *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
520
521 return k;
522}
523
524static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
525 UnitType t;
526 int r;
527
528 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 528, __PRETTY_FUNCTION__
); } while (0)
;
529 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 529, __PRETTY_FUNCTION__
); } while (0)
;
530
531#if HAVE_SELINUX1
532 r = sd_bus_add_filter(bus, NULL((void*)0), mac_selinux_filter, m);
533 if (r < 0)
534 return log_error_errno(r, "Failed to add SELinux access filter: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 534, __func__, "Failed to add SELinux access filter: %m"
) : -abs(_e); })
;
535#endif
536
537 r = sd_bus_add_object_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
538 if (r < 0)
539 return log_error_errno(r, "Failed to register Manager vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 539, __func__, "Failed to register Manager vtable: %m"
) : -abs(_e); })
;
540
541 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
542 if (r < 0)
543 return log_error_errno(r, "Failed to register Job vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 543, __func__, "Failed to register Job vtable: %m"
) : -abs(_e); })
;
544
545 r = sd_bus_add_node_enumerator(bus, NULL((void*)0), "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
546 if (r < 0)
547 return log_error_errno(r, "Failed to add job enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 547, __func__, "Failed to add job enumerator: %m"
) : -abs(_e); })
;
548
549 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
550 if (r < 0)
551 return log_error_errno(r, "Failed to register Unit vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 551, __func__, "Failed to register Unit vtable: %m"
) : -abs(_e); })
;
552
553 r = sd_bus_add_node_enumerator(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
554 if (r < 0)
555 return log_error_errno(r, "Failed to add job enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 555, __func__, "Failed to add job enumerator: %m"
) : -abs(_e); })
;
556
557 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
558 const char *interface;
559
560 assert_se(interface = unit_dbus_interface_from_type(t))do { if ((__builtin_expect(!!(!(interface = unit_dbus_interface_from_type
(t))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("interface = unit_dbus_interface_from_type(t)"
), "../src/core/dbus.c", 560, __PRETTY_FUNCTION__); } while (
0)
;
561
562 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
563 if (r < 0)
564 return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 564, __func__, "Failed to register type specific vtable for %s: %m"
, interface) : -abs(_e); })
;
565
566 if (unit_vtable[t]->cgroup_context_offset > 0) {
567 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
568 if (r < 0)
569 return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 569, __func__, "Failed to register control group unit vtable for %s: %m"
, interface) : -abs(_e); })
;
570
571 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
572 if (r < 0)
573 return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 573, __func__, "Failed to register control group vtable for %s: %m"
, interface) : -abs(_e); })
;
574 }
575
576 if (unit_vtable[t]->exec_context_offset > 0) {
577 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m);
578 if (r < 0)
579 return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 579, __func__, "Failed to register execute vtable for %s: %m"
, interface) : -abs(_e); })
;
580 }
581
582 if (unit_vtable[t]->kill_context_offset > 0) {
583 r = sd_bus_add_fallback_vtable(bus, NULL((void*)0), "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m);
584 if (r < 0)
585 return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 585, __func__, "Failed to register kill vtable for %s: %m"
, interface) : -abs(_e); })
;
586 }
587 }
588
589 return 0;
590}
591
592static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
593 int r;
594
595 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 595, __PRETTY_FUNCTION__
); } while (0)
;
596 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 596, __PRETTY_FUNCTION__
); } while (0)
;
597
598 r = sd_bus_match_signal_async(
599 bus,
600 NULL((void*)0),
601 "org.freedesktop.DBus.Local",
602 "/org/freedesktop/DBus/Local",
603 "org.freedesktop.DBus.Local",
604 "Disconnected",
605 signal_disconnected, NULL((void*)0), m);
606 if (r < 0)
607 return log_error_errno(r, "Failed to request match for Disconnected message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 607, __func__, "Failed to request match for Disconnected message: %m"
) : -abs(_e); })
;
608
609 return 0;
610}
611
612static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
613 _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0);
614 _cleanup_close___attribute__((cleanup(closep))) int nfd = -1;
615 Manager *m = userdata;
616 sd_id128_t id;
617 int r;
618
619 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/dbus.c", 619, __PRETTY_FUNCTION__
); } while (0)
;
620 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 620, __PRETTY_FUNCTION__
); } while (0)
;
621
622 nfd = accept4(fd, NULL((void*)0), NULL((void*)0), SOCK_NONBLOCKSOCK_NONBLOCK|SOCK_CLOEXECSOCK_CLOEXEC);
623 if (nfd < 0) {
624 log_warning_errno(errno, "Failed to accept private connection, ignoring: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/core/dbus.c", 624, __func__, "Failed to accept private connection, ignoring: %m"
) : -abs(_e); })
;
625 return 0;
626 }
627
628 if (set_size(m->private_buses) >= CONNECTIONS_MAX4096) {
629 log_warning("Too many concurrent connections, refusing")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 629, __func__, "Too many concurrent connections, refusing"
) : -abs(_e); })
;
630 return 0;
631 }
632
633 r = set_ensure_allocated(&m->private_buses, NULL)internal_set_ensure_allocated(&m->private_buses, ((void
*)0) )
;
634 if (r < 0) {
635 log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/dbus.c", 635
, __func__)
;
636 return 0;
637 }
638
639 r = sd_bus_new(&bus);
640 if (r < 0) {
641 log_warning_errno(r, "Failed to allocate new private connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 641, __func__, "Failed to allocate new private connection bus: %m"
) : -abs(_e); })
;
642 return 0;
643 }
644
645 (void) sd_bus_set_description(bus, "private-bus-connection");
646
647 r = sd_bus_set_fd(bus, nfd, nfd);
648 if (r < 0) {
649 log_warning_errno(r, "Failed to set fd on new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 649, __func__, "Failed to set fd on new connection bus: %m"
) : -abs(_e); })
;
650 return 0;
651 }
652
653 nfd = -1;
654
655 r = bus_check_peercred(bus);
656 if (r < 0) {
657 log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 657, __func__, "Incoming private connection from unprivileged client, refusing: %m"
) : -abs(_e); })
;
658 return 0;
659 }
660
661 assert_se(sd_id128_randomize(&id) >= 0)do { if ((__builtin_expect(!!(!(sd_id128_randomize(&id) >=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sd_id128_randomize(&id) >= 0"
), "../src/core/dbus.c", 661, __PRETTY_FUNCTION__); } while (
0)
;
662
663 r = sd_bus_set_server(bus, 1, id);
664 if (r < 0) {
665 log_warning_errno(r, "Failed to enable server support for new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 665, __func__, "Failed to enable server support for new connection bus: %m"
) : -abs(_e); })
;
666 return 0;
667 }
668
669 r = sd_bus_negotiate_creds(bus, 1,
670 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
671 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
672 SD_BUS_CREDS_SELINUX_CONTEXT);
673 if (r < 0) {
674 log_warning_errno(r, "Failed to enable credentials for new connection: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 674, __func__, "Failed to enable credentials for new connection: %m"
) : -abs(_e); })
;
675 return 0;
676 }
677
678 r = sd_bus_set_sender(bus, "org.freedesktop.systemd1");
679 if (r < 0) {
680 log_warning_errno(r, "Failed to set direct connection sender: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 680, __func__, "Failed to set direct connection sender: %m"
) : -abs(_e); })
;
681 return 0;
682 }
683
684 r = sd_bus_start(bus);
685 if (r < 0) {
686 log_warning_errno(r, "Failed to start new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 686, __func__, "Failed to start new connection bus: %m"
) : -abs(_e); })
;
687 return 0;
688 }
689
690 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
691 if (r < 0) {
692 log_warning_errno(r, "Failed to attach new connection bus to event loop: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 692, __func__, "Failed to attach new connection bus to event loop: %m"
) : -abs(_e); })
;
693 return 0;
694 }
695
696 r = bus_setup_disconnected_match(m, bus);
697 if (r < 0)
698 return 0;
699
700 r = bus_setup_api_vtables(m, bus);
701 if (r < 0) {
702 log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 702, __func__, "Failed to set up API vtables on new connection bus: %m"
) : -abs(_e); })
;
703 return 0;
704 }
705
706 r = set_put(m->private_buses, bus);
707 if (r < 0) {
708 log_warning_errno(r, "Failed to add new connection bus to set: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 708, __func__, "Failed to add new connection bus to set: %m"
) : -abs(_e); })
;
709 return 0;
710 }
711
712 bus = NULL((void*)0);
713
714 log_debug("Accepted new private connection.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 714, __func__, "Accepted new private connection."
) : -abs(_e); })
;
715
716 return 0;
717}
718
719static int manager_dispatch_sync_bus_names(sd_event_source *es, void *userdata) {
720 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **names = NULL((void*)0);
721 Manager *m = userdata;
722 const char *name;
723 Iterator i;
724 Unit *u;
725 int r;
726
727 assert(es)do { if ((__builtin_expect(!!(!(es)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("es"), "../src/core/dbus.c", 727, __PRETTY_FUNCTION__
); } while (0)
;
728 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 728, __PRETTY_FUNCTION__
); } while (0)
;
729 assert(m->sync_bus_names_event_source == es)do { if ((__builtin_expect(!!(!(m->sync_bus_names_event_source
== es)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("m->sync_bus_names_event_source == es"
), "../src/core/dbus.c", 729, __PRETTY_FUNCTION__); } while (
0)
;
730
731 /* First things first, destroy the defer event so that we aren't triggered again */
732 m->sync_bus_names_event_source = sd_event_source_unref(m->sync_bus_names_event_source);
733
734 /* Let's see if there's anything to do still? */
735 if (!m->api_bus)
736 return 0;
737 if (hashmap_isempty(m->watch_bus))
738 return 0;
739
740 /* OK, let's sync up the names. Let's see which names are currently on the bus. */
741 r = sd_bus_list_names(m->api_bus, &names, NULL((void*)0));
742 if (r < 0)
743 return log_error_errno(r, "Failed to get initial list of names: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 743, __func__, "Failed to get initial list of names: %m"
) : -abs(_e); })
;
744
745 /* We have to synchronize the current bus names with the
746 * list of active services. To do this, walk the list of
747 * all units with bus names. */
748 HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), &
(i), (void**)&(u), (const void**) &(name)); )
{
749 Service *s = SERVICE(u);
750
751 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/dbus.c", 751, __PRETTY_FUNCTION__
); } while (0)
;
752
753 if (!streq_ptr(s->bus_name, name)) {
754 log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name)({ const Unit *_u = (u); _u ? log_object_internal(4, 0, "../src/core/dbus.c"
, 754, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Bus name has changed from %s → %s, ignoring.", s->bus_name
, name) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10
| ((4))), 0, "../src/core/dbus.c", 754, __func__, "Bus name has changed from %s → %s, ignoring."
, s->bus_name, name); })
;
755 continue;
756 }
757
758 /* Check if a service's bus name is in the list of currently
759 * active names */
760 if (strv_contains(names, name)(!!strv_find((names), (name)))) {
761 _cleanup_(sd_bus_creds_unrefp)__attribute__((cleanup(sd_bus_creds_unrefp))) sd_bus_creds *creds = NULL((void*)0);
762 const char *unique;
763
764 /* If it is, determine its current owner */
765 r = sd_bus_get_name_creds(m->api_bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
766 if (r < 0) {
767 log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name)({ int _level = ((r == -6 ? 7 : 3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 767, __func__, "Failed to get bus name owner %s: %m"
, name) : -abs(_e); })
;
768 continue;
769 }
770
771 r = sd_bus_creds_get_unique_name(creds, &unique);
772 if (r < 0) {
773 log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name)({ int _level = ((r == -6 ? 7 : 3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 773, __func__, "Failed to get unique name for %s: %m"
, name) : -abs(_e); })
;
774 continue;
775 }
776
777 /* Now, let's compare that to the previous bus owner, and
778 * if it's still the same, all is fine, so just don't
779 * bother the service. Otherwise, the name has apparently
780 * changed, so synthesize a name owner changed signal. */
781
782 if (!streq_ptr(unique, s->bus_name_owner))
783 UNIT_VTABLE(u)unit_vtable[(u)->type]->bus_name_owner_change(u, name, s->bus_name_owner, unique);
784 } else {
785 /* So, the name we're watching is not on the bus.
786 * This either means it simply hasn't appeared yet,
787 * or it was lost during the daemon reload.
788 * Check if the service has a stored name owner,
789 * and synthesize a name loss signal in this case. */
790
791 if (s->bus_name_owner)
792 UNIT_VTABLE(u)unit_vtable[(u)->type]->bus_name_owner_change(u, name, s->bus_name_owner, NULL((void*)0));
793 }
794 }
795
796 return 0;
797}
798
799int manager_enqueue_sync_bus_names(Manager *m) {
800 int r;
801
802 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 802, __PRETTY_FUNCTION__
); } while (0)
;
803
804 /* Enqueues a request to synchronize the bus names in a later event loop iteration. The callers generally don't
805 * want us to invoke ->bus_name_owner_change() unit calls from their stack frames as this might result in event
806 * dispatching on its own creating loops, hence we simply create a defer event for the event loop and exit. */
807
808 if (m->sync_bus_names_event_source)
809 return 0;
810
811 r = sd_event_add_defer(m->event, &m->sync_bus_names_event_source, manager_dispatch_sync_bus_names, m);
812 if (r < 0)
813 return log_error_errno(r, "Failed to create bus name synchronization event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 813, __func__, "Failed to create bus name synchronization event: %m"
) : -abs(_e); })
;
814
815 r = sd_event_source_set_priority(m->sync_bus_names_event_source, SD_EVENT_PRIORITY_IDLE);
816 if (r < 0)
817 return log_error_errno(r, "Failed to set event priority: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 817, __func__, "Failed to set event priority: %m"
) : -abs(_e); })
;
818
819 r = sd_event_source_set_enabled(m->sync_bus_names_event_source, SD_EVENT_ONESHOT);
820 if (r < 0)
821 return log_error_errno(r, "Failed to set even to oneshot: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 821, __func__, "Failed to set even to oneshot: %m"
) : -abs(_e); })
;
822
823 (void) sd_event_source_set_description(m->sync_bus_names_event_source, "manager-sync-bus-names");
824 return 0;
825}
826
827static int bus_setup_api(Manager *m, sd_bus *bus) {
828 Iterator i;
829 char *name;
830 Unit *u;
831 int r;
832
833 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 833, __PRETTY_FUNCTION__
); } while (0)
;
834 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 834, __PRETTY_FUNCTION__
); } while (0)
;
835
836 /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
837 r = sd_bus_negotiate_creds(bus, 1,
838 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
839 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
840 SD_BUS_CREDS_SELINUX_CONTEXT);
841 if (r < 0)
842 log_warning_errno(r, "Failed to enable credential passing, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 842, __func__, "Failed to enable credential passing, ignoring: %m"
) : -abs(_e); })
;
843
844 r = bus_setup_api_vtables(m, bus);
845 if (r < 0)
846 return r;
847
848 HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), &
(i), (void**)&(u), (const void**) &(name)); )
{
849 r = unit_install_bus_match(u, bus, name);
850 if (r < 0)
851 log_error_errno(r, "Failed to subscribe to NameOwnerChanged signal for '%s': %m", name)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 851, __func__, "Failed to subscribe to NameOwnerChanged signal for '%s': %m"
, name) : -abs(_e); })
;
852 }
853
854 r = sd_bus_match_signal_async(
855 bus,
856 NULL((void*)0),
857 "org.freedesktop.DBus",
858 "/org/freedesktop/DBus",
859 "org.freedesktop.systemd1.Activator",
860 "ActivationRequest",
861 signal_activation_request, NULL((void*)0), m);
862 if (r < 0)
863 log_warning_errno(r, "Failed to subscribe to activation signal: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 863, __func__, "Failed to subscribe to activation signal: %m"
) : -abs(_e); })
;
864
865 /* Allow replacing of our name, to ease implementation of reexecution, where we keep the old connection open
866 * until after the new connection is set up and the name installed to allow clients to synchronously wait for
867 * reexecution to finish */
868 r = sd_bus_request_name_async(bus, NULL((void*)0), "org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT, NULL((void*)0), NULL((void*)0));
869 if (r < 0)
870 return log_error_errno(r, "Failed to request name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 870, __func__, "Failed to request name: %m"
) : -abs(_e); })
;
871
872 log_debug("Successfully connected to API bus.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 872, __func__, "Successfully connected to API bus."
) : -abs(_e); })
;
873
874 return 0;
875}
876
877int bus_init_api(Manager *m) {
878 _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0);
879 int r;
880
881 if (m->api_bus)
882 return 0;
883
884 /* The API and system bus is the same if we are running in system mode */
885 if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM) && m->system_bus)
886 bus = sd_bus_ref(m->system_bus);
887 else {
888 if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM))
889 r = sd_bus_open_system_with_description(&bus, "bus-api-system");
890 else
891 r = sd_bus_open_user_with_description(&bus, "bus-api-user");
892 if (r < 0)
893 return log_error_errno(r, "Failed to connect to API bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 893, __func__, "Failed to connect to API bus: %m"
) : -abs(_e); })
;
894
895 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
896 if (r < 0)
897 return log_error_errno(r, "Failed to attach API bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 897, __func__, "Failed to attach API bus to event loop: %m"
) : -abs(_e); })
;
898
899 r = bus_setup_disconnected_match(m, bus);
900 if (r < 0)
901 return r;
902 }
903
904 r = bus_setup_api(m, bus);
905 if (r < 0)
906 return log_error_errno(r, "Failed to set up API bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 906, __func__, "Failed to set up API bus: %m"
) : -abs(_e); })
;
907
908 m->api_bus = TAKE_PTR(bus)({ typeof(bus) _ptr_ = (bus); (bus) = ((void*)0); _ptr_; });
909
910 r = manager_enqueue_sync_bus_names(m);
911 if (r < 0)
912 return r;
913
914 return 0;
915}
916
917static int bus_setup_system(Manager *m, sd_bus *bus) {
918 int r;
919
920 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 920, __PRETTY_FUNCTION__
); } while (0)
;
921 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 921, __PRETTY_FUNCTION__
); } while (0)
;
922
923 /* if we are a user instance we get the Released message via the system bus */
924 if (MANAGER_IS_USER(m)((m)->unit_file_scope != UNIT_FILE_SYSTEM)) {
925 r = sd_bus_match_signal_async(
926 bus,
927 NULL((void*)0),
928 NULL((void*)0),
929 "/org/freedesktop/systemd1/agent",
930 "org.freedesktop.systemd1.Agent",
931 "Released",
932 signal_agent_released, NULL((void*)0), m);
933 if (r < 0)
934 log_warning_errno(r, "Failed to request Released match on system bus: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 934, __func__, "Failed to request Released match on system bus: %m"
) : -abs(_e); })
;
935 }
936
937 log_debug("Successfully connected to system bus.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 937, __func__, "Successfully connected to system bus."
) : -abs(_e); })
;
938 return 0;
939}
940
941int bus_init_system(Manager *m) {
942 _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0);
943 int r;
944
945 if (m->system_bus)
946 return 0;
947
948 /* The API and system bus is the same if we are running in system mode */
949 if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM) && m->api_bus)
950 bus = sd_bus_ref(m->api_bus);
951 else {
952 r = sd_bus_open_system_with_description(&bus, "bus-system");
953 if (r < 0)
954 return log_error_errno(r, "Failed to connect to system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 954, __func__, "Failed to connect to system bus: %m"
) : -abs(_e); })
;
955
956 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
957 if (r < 0)
958 return log_error_errno(r, "Failed to attach system bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 958, __func__, "Failed to attach system bus to event loop: %m"
) : -abs(_e); })
;
959
960 r = bus_setup_disconnected_match(m, bus);
961 if (r < 0)
962 return r;
963 }
964
965 r = bus_setup_system(m, bus);
966 if (r < 0)
967 return log_error_errno(r, "Failed to set up system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 967, __func__, "Failed to set up system bus: %m"
) : -abs(_e); })
;
968
969 m->system_bus = TAKE_PTR(bus)({ typeof(bus) _ptr_ = (bus); (bus) = ((void*)0); _ptr_; });
970
971 return 0;
972}
973
974int bus_init_private(Manager *m) {
975 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
976 union sockaddr_union sa = {
977 .un.sun_family = AF_UNIX1
978 };
979 sd_event_source *s;
980 socklen_t salen;
981 int r;
982
983 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 983, __PRETTY_FUNCTION__
); } while (0)
;
984
985 if (m->private_listen_fd >= 0)
986 return 0;
987
988 if (MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM)) {
989
990 /* We want the private bus only when running as init */
991 if (getpid_cached() != 1)
992 return 0;
993
994 strcpy(sa.un.sun_path, "/run/systemd/private");
995 salen = SOCKADDR_UN_LEN(sa.un)({ const struct sockaddr_un *_sa = &(sa.un); do { if ((__builtin_expect
(!!(!(_sa->sun_family == 1)),0))) log_assert_failed_realm(
LOG_REALM_SYSTEMD, ("_sa->sun_family == AF_UNIX"), "../src/core/dbus.c"
, 995, __PRETTY_FUNCTION__); } while (0); __builtin_offsetof(
struct sockaddr_un, sun_path) + (_sa->sun_path[0] == 0 ? 1
+ strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : strnlen
(_sa->sun_path, sizeof(_sa->sun_path))); })
;
996 } else {
997 size_t left = sizeof(sa.un.sun_path);
998 char *p = sa.un.sun_path;
999 const char *e;
1000
1001 e = secure_getenv("XDG_RUNTIME_DIR");
1002 if (!e) {
1003 log_error("Failed to determine XDG_RUNTIME_DIR")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 1003, __func__, "Failed to determine XDG_RUNTIME_DIR"
) : -abs(_e); })
;
1004 return -EHOSTDOWN112;
1005 }
1006
1007 left = strpcpy(&p, left, e);
1008 left = strpcpy(&p, left, "/systemd/private");
1009
1010 salen = sizeof(sa.un) - left;
1011 }
1012
1013 (void) mkdir_parents_label(sa.un.sun_path, 0755);
1014 (void) unlink(sa.un.sun_path);
1015
1016 fd = socket(AF_UNIX1, SOCK_STREAMSOCK_STREAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0);
1017 if (fd < 0)
1018 return log_error_errno(errno, "Failed to allocate private socket: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/core/dbus.c", 1018, __func__, "Failed to allocate private socket: %m"
) : -abs(_e); })
;
1019
1020 r = bind(fd, &sa.sa, salen);
1021 if (r < 0)
1022 return log_error_errno(errno, "Failed to bind private socket: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/core/dbus.c", 1022, __func__, "Failed to bind private socket: %m"
) : -abs(_e); })
;
1023
1024 r = listen(fd, SOMAXCONN4096);
1025 if (r < 0)
1026 return log_error_errno(errno, "Failed to make private socket listening: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/core/dbus.c", 1026, __func__, "Failed to make private socket listening: %m"
) : -abs(_e); })
;
1027
1028 /* Generate an inotify event in case somebody waits for this socket to appear using inotify() */
1029 (void) touch(sa.un.sun_path);
1030
1031 r = sd_event_add_io(m->event, &s, fd, EPOLLINEPOLLIN, bus_on_connection, m);
1032 if (r < 0)
1033 return log_error_errno(r, "Failed to allocate event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 1033, __func__, "Failed to allocate event source: %m"
) : -abs(_e); })
;
1034
1035 (void) sd_event_source_set_description(s, "bus-connection");
1036
1037 m->private_listen_fd = fd;
1038 m->private_listen_event_source = s;
1039 fd = -1;
1040
1041 log_debug("Successfully created private D-Bus server.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 1041, __func__, "Successfully created private D-Bus server."
) : -abs(_e); })
;
1042
1043 return 0;
1044}
1045
1046static void destroy_bus(Manager *m, sd_bus **bus) {
1047 Iterator i;
1048 Unit *u;
1049 Job *j;
1050
1051 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1051, __PRETTY_FUNCTION__
); } while (0)
;
1052 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/core/dbus.c", 1052, __PRETTY_FUNCTION__
); } while (0)
;
1053
1054 if (!*bus)
1055 return;
1056
1057 /* Make sure all bus slots watching names are released. */
1058 HASHMAP_FOREACH(u, m->watch_bus, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->watch_bus), &
(i), (void**)&(u), ((void*)0)); )
{
1059 if (!u->match_bus_slot)
1060 continue;
1061
1062 if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus)
1063 continue;
1064
1065 u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
1066 }
1067
1068 /* Get rid of tracked clients on this bus */
1069 if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1070 m->subscribed = sd_bus_track_unref(m->subscribed);
1071
1072 HASHMAP_FOREACH(j, m->jobs, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->jobs), &
(i), (void**)&(j), ((void*)0)); )
1073 if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus)
1074 j->bus_track = sd_bus_track_unref(j->bus_track);
1075
1076 HASHMAP_FOREACH(u, m->units, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->units), &
(i), (void**)&(u), ((void*)0)); )
{
1077 if (u->bus_track && sd_bus_track_get_bus(u->bus_track) == *bus)
1078 u->bus_track = sd_bus_track_unref(u->bus_track);
1079
1080 /* Get rid of pending freezer messages on this bus */
1081 if (u->pending_freezer_message && sd_bus_message_get_bus(u->pending_freezer_message) == *bus)
1082 u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
1083 }
1084
1085 /* Get rid of queued message on this bus */
1086 if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus)
1087 m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
1088
1089 /* Possibly flush unwritten data, but only if we are
1090 * unprivileged, since we don't want to sync here */
1091 if (!MANAGER_IS_SYSTEM(m)((m)->unit_file_scope == UNIT_FILE_SYSTEM))
1092 sd_bus_flush(*bus);
1093
1094 /* And destroy the object */
1095 sd_bus_close(*bus);
1096 *bus = sd_bus_unref(*bus);
1097}
1098
1099void bus_done_api(Manager *m) {
1100 destroy_bus(m, &m->api_bus);
1101}
1102
1103void bus_done_system(Manager *m) {
1104 destroy_bus(m, &m->system_bus);
1105}
1106
1107void bus_done_private(Manager *m) {
1108 sd_bus *b;
1109
1110 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1110, __PRETTY_FUNCTION__
); } while (0)
;
1111
1112 while ((b = set_steal_first(m->private_buses)))
1113 destroy_bus(m, &b);
1114
1115 m->private_buses = set_free(m->private_buses);
1116
1117 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1118 m->private_listen_fd = safe_close(m->private_listen_fd);
1119}
1120
1121void bus_done(Manager *m) {
1122 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1122, __PRETTY_FUNCTION__
); } while (0)
;
1123
1124 bus_done_api(m);
1125 bus_done_system(m);
1126 bus_done_private(m);
1127
1128 assert(!m->subscribed)do { if ((__builtin_expect(!!(!(!m->subscribed)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!m->subscribed"), "../src/core/dbus.c"
, 1128, __PRETTY_FUNCTION__); } while (0)
;
1129
1130 m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
1131 bus_verify_polkit_async_registry_free(m->polkit_registry);
1132}
1133
1134int bus_fdset_add_all(Manager *m, FDSet *fds) {
1135 Iterator i;
1136 sd_bus *b;
1137 int fd;
1138
1139 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1139, __PRETTY_FUNCTION__
); } while (0)
;
1140 assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fds"), "../src/core/dbus.c", 1140, __PRETTY_FUNCTION__
); } while (0)
;
1141
1142 /* When we are about to reexecute we add all D-Bus fds to the
1143 * set to pass over to the newly executed systemd. They won't
1144 * be used there however, except thatt they are closed at the
1145 * very end of deserialization, those making it possible for
1146 * clients to synchronously wait for systemd to reexec by
1147 * simply waiting for disconnection */
1148
1149 if (m->api_bus) {
1150 fd = sd_bus_get_fd(m->api_bus);
1151 if (fd >= 0) {
1152 fd = fdset_put_dup(fds, fd);
1153 if (fd < 0)
1154 return fd;
1155 }
1156 }
1157
1158 SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((m->private_buses), &
(i), (void**)&(b)); )
{
1159 fd = sd_bus_get_fd(b);
1160 if (fd >= 0) {
1161 fd = fdset_put_dup(fds, fd);
1162 if (fd < 0)
1163 return fd;
1164 }
1165 }
1166
1167 /* We don't offer any APIs on the system bus (well, unless it
1168 * is the same as the API bus) hence we don't bother with it
1169 * here */
1170
1171 return 0;
1172}
1173
1174int bus_foreach_bus(
1175 Manager *m,
1176 sd_bus_track *subscribed2,
1177 int (*send_message)(sd_bus *bus, void *userdata),
1178 void *userdata) {
1179
1180 Iterator i;
1181 sd_bus *b;
1182 int r, ret = 0;
1183
1184 /* Send to all direct buses, unconditionally */
1185 SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((m->private_buses), &
(i), (void**)&(b)); )
{
1186
1187 /* Don't bother with enqueing these messages to clients that haven't started yet */
1188 if (sd_bus_is_ready(b) <= 0)
1189 continue;
1190
1191 r = send_message(b, userdata);
1192 if (r < 0)
1193 ret = r;
1194 }
1195
1196 /* Send to API bus, but only if somebody is subscribed */
1197 if (m->api_bus &&
1198 (sd_bus_track_count(m->subscribed) > 0 ||
1199 sd_bus_track_count(subscribed2) > 0)) {
1200 r = send_message(m->api_bus, userdata);
1201 if (r < 0)
1202 ret = r;
1203 }
1204
1205 return ret;
1206}
1207
1208void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
1209 const char *n;
1210
1211 assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("f"), "../src/core/dbus.c", 1211, __PRETTY_FUNCTION__
); } while (0)
;
1212 assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefix"), "../src/core/dbus.c", 1212, __PRETTY_FUNCTION__
); } while (0)
;
1213
1214 for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
1215 int c, j;
1216
1217 c = sd_bus_track_count_name(t, n);
1218
1219 for (j = 0; j < c; j++) {
1220 fputs(prefix, f);
1221 fputc('=', f);
1222 fputs(n, f);
1223 fputc('\n', f);
1224 }
1225 }
1226}
1227
1228int bus_track_coldplug(Manager *m, sd_bus_track **t, bool_Bool recursive, char **l) {
1229 int r = 0;
1230
1231 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/core/dbus.c", 1231, __PRETTY_FUNCTION__
); } while (0)
;
1232 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/core/dbus.c", 1232, __PRETTY_FUNCTION__
); } while (0)
;
1233
1234 if (strv_isempty(l))
1235 return 0;
1236
1237 if (!m->api_bus)
1238 return 0;
1239
1240 if (!*t) {
1241 r = sd_bus_track_new(m->api_bus, t, NULL((void*)0), NULL((void*)0));
1242 if (r < 0)
1243 return r;
1244 }
1245
1246 r = sd_bus_track_set_recursive(*t, recursive);
1247 if (r < 0)
1248 return r;
1249
1250 return bus_track_add_name_many(*t, l);
1251}
1252
1253int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1254 return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.manage-units", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error);
1255}
1256
1257int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1258 return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.manage-unit-files", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error);
1259}
1260
1261int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1262 return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.reload-daemon", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error);
1263}
1264
1265int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1266 return bus_verify_polkit_async(call, CAP_SYS_ADMIN21, "org.freedesktop.systemd1.set-environment", NULL((void*)0), false0, UID_INVALID((uid_t) -1), &m->polkit_registry, error);
1267}
1268
1269uint64_t manager_bus_n_queued_write(Manager *m) {
1270 uint64_t c = 0;
1271 Iterator i;
1272 sd_bus *b;
1273 int r;
1274
1275 /* Returns the total number of messages queued for writing on all our direct and API busses. */
1276
1277 SET_FOREACH(b, m->private_buses, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((m->private_buses), &
(i), (void**)&(b)); )
{
1278 uint64_t k;
1279
1280 r = sd_bus_get_n_queued_write(b, &k);
1281 if (r < 0)
1282 log_debug_errno(r, "Failed to query queued messages for private bus: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 1282, __func__, "Failed to query queued messages for private bus: %m"
) : -abs(_e); })
;
1283 else
1284 c += k;
1285 }
1286
1287 if (m->api_bus) {
1288 uint64_t k;
1289
1290 r = sd_bus_get_n_queued_write(m->api_bus, &k);
1291 if (r < 0)
1292 log_debug_errno(r, "Failed to query queued messages for API bus: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/dbus.c", 1292, __func__, "Failed to query queued messages for API bus: %m"
) : -abs(_e); })
;
1293 else
1294 c += k;
1295 }
1296
1297 return c;
1298}
1299
1300static void vtable_dump_bus_properties(FILE *f, const sd_bus_vtable *table) {
1301 const sd_bus_vtable *i;
1302
1303 for (i = table; i->type != _SD_BUS_VTABLE_END; i++) {
1304 if (!IN_SET(i->type, _SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){_SD_BUS_VTABLE_PROPERTY, _SD_BUS_VTABLE_WRITABLE_PROPERTY
})/sizeof(int)]; switch(i->type) { case _SD_BUS_VTABLE_PROPERTY
: case _SD_BUS_VTABLE_WRITABLE_PROPERTY: _found = 1; break; default
: break; } _found; })
||
1305 (i->flags & (SD_BUS_VTABLE_DEPRECATED | SD_BUS_VTABLE_HIDDEN)) != 0)
1306 continue;
1307
1308 fprintf(f, "%s\n", i->x.property.member);
1309 }
1310}
1311
1312void dump_bus_properties(FILE *f) {
1313 assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("f"), "../src/core/dbus.c", 1313, __PRETTY_FUNCTION__
); } while (0)
;
1314
1315 vtable_dump_bus_properties(f, bus_automount_vtable);
1316 vtable_dump_bus_properties(f, bus_cgroup_vtable);
1317 vtable_dump_bus_properties(f, bus_device_vtable);
1318 vtable_dump_bus_properties(f, bus_exec_vtable);
1319 vtable_dump_bus_properties(f, bus_job_vtable);
1320 vtable_dump_bus_properties(f, bus_kill_vtable);
1321 vtable_dump_bus_properties(f, bus_manager_vtable);
1322 vtable_dump_bus_properties(f, bus_mount_vtable);
1323 vtable_dump_bus_properties(f, bus_path_vtable);
1324 vtable_dump_bus_properties(f, bus_scope_vtable);
1325 vtable_dump_bus_properties(f, bus_service_vtable);
1326 vtable_dump_bus_properties(f, bus_slice_vtable);
1327 vtable_dump_bus_properties(f, bus_socket_vtable);
1328 vtable_dump_bus_properties(f, bus_swap_vtable);
1329 vtable_dump_bus_properties(f, bus_target_vtable);
1330 vtable_dump_bus_properties(f, bus_timer_vtable);
1331 vtable_dump_bus_properties(f, bus_unit_vtable);
1332 vtable_dump_bus_properties(f, bus_unit_cgroup_vtable);
1333}