File: | build-scan/../src/core/dbus.c |
Warning: | line 488, column 33 Potential leak of memory pointed to by 'l' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
48 | static void destroy_bus(Manager *m, sd_bus **bus); | |||
49 | ||||
50 | int 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 | ||||
70 | int 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 | ||||
96 | static 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 | ||||
126 | static 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 | ||||
147 | static 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 | ||||
186 | failed: | |||
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 | |||
212 | static 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 | ||||
276 | static 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 | ||||
295 | static 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 | ||||
334 | static 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 | ||||
346 | static 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 | ||||
368 | static 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 | ||||
393 | static 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 | ||||
420 | static 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 | ||||
447 | static 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 | ||||
474 | static 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 | ||||
500 | static 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*) )); | |||
508 | if (!l) | |||
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)); ) { | |||
512 | l[k] = unit_dbus_path(u); | |||
513 | if (!l[k]) | |||
514 | return -ENOMEM12; | |||
515 | ||||
516 | k++; | |||
517 | } | |||
518 | ||||
519 | *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; }); | |||
520 | ||||
521 | return k; | |||
522 | } | |||
523 | ||||
524 | static 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 | ||||
592 | static 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 | ||||
612 | static 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 | ||||
719 | static 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 | ||||
799 | int 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 | ||||
827 | static 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 | ||||
877 | int 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 | ||||
917 | static 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 | ||||
941 | int 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 | ||||
974 | int 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 | ||||
1046 | static 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 | ||||
1099 | void bus_done_api(Manager *m) { | |||
1100 | destroy_bus(m, &m->api_bus); | |||
1101 | } | |||
1102 | ||||
1103 | void bus_done_system(Manager *m) { | |||
1104 | destroy_bus(m, &m->system_bus); | |||
1105 | } | |||
1106 | ||||
1107 | void 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 | ||||
1121 | void 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 | ||||
1134 | int 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 | ||||
1174 | int 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 | ||||
1208 | void 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 | ||||
1228 | int 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 | ||||
1253 | int 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 | ||||
1257 | int 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 | ||||
1261 | int 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 | ||||
1265 | int 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 | ||||
1269 | uint64_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 | ||||
1300 | static 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 | ||||
1312 | void 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 | } |