Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <net/if.h>
4 : : #include <netinet/in.h>
5 : : #include <sys/capability.h>
6 : :
7 : : #include "alloc-util.h"
8 : : #include "bus-common-errors.h"
9 : : #include "bus-util.h"
10 : : #include "dns-domain.h"
11 : : #include "networkd-link-bus.h"
12 : : #include "networkd-link.h"
13 : : #include "networkd-manager.h"
14 : : #include "parse-util.h"
15 : : #include "resolve-util.h"
16 : : #include "strv.h"
17 : : #include "user-util.h"
18 : :
19 [ # # # # : 0 : BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
# # ]
20 [ # # # # : 0 : BUS_DEFINE_PROPERTY_GET_ENUM(property_get_carrier_state, link_carrier_state, LinkCarrierState);
# # ]
21 [ # # # # : 0 : BUS_DEFINE_PROPERTY_GET_ENUM(property_get_address_state, link_address_state, LinkAddressState);
# # ]
22 [ # # # # : 0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
# # ]
23 : :
24 : 0 : static int property_get_bit_rates(
25 : : sd_bus *bus,
26 : : const char *path,
27 : : const char *interface,
28 : : const char *property,
29 : : sd_bus_message *reply,
30 : : void *userdata,
31 : : sd_bus_error *error) {
32 : :
33 : 0 : Link *link = userdata;
34 : : Manager *manager;
35 : : double interval_sec;
36 : : uint64_t tx, rx;
37 : :
38 [ # # ]: 0 : assert(bus);
39 [ # # ]: 0 : assert(reply);
40 [ # # ]: 0 : assert(userdata);
41 : :
42 : 0 : manager = link->manager;
43 : :
44 [ # # ]: 0 : if (!manager->use_speed_meter)
45 : 0 : return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is disabled.");
46 : :
47 [ # # ]: 0 : if (manager->speed_meter_usec_old == 0)
48 : 0 : return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is not active.");
49 : :
50 [ # # ]: 0 : if (!link->stats_updated)
51 : 0 : return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Failed to measure bit-rates.");
52 : :
53 [ # # ]: 0 : assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
54 : 0 : interval_sec = (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
55 : :
56 [ # # ]: 0 : if (link->stats_new.tx_bytes > link->stats_old.tx_bytes)
57 : 0 : tx = (uint64_t) ((link->stats_new.tx_bytes - link->stats_old.tx_bytes) / interval_sec);
58 : : else
59 : 0 : tx = (uint64_t) ((UINT64_MAX - (link->stats_old.tx_bytes - link->stats_new.tx_bytes)) / interval_sec);
60 : :
61 [ # # ]: 0 : if (link->stats_new.rx_bytes > link->stats_old.rx_bytes)
62 : 0 : rx = (uint64_t) ((link->stats_new.rx_bytes - link->stats_old.rx_bytes) / interval_sec);
63 : : else
64 : 0 : rx = (uint64_t) ((UINT64_MAX - (link->stats_old.rx_bytes - link->stats_new.rx_bytes)) / interval_sec);
65 : :
66 : 0 : return sd_bus_message_append(reply, "(tt)", tx, rx);
67 : : }
68 : :
69 : 0 : static int verify_managed_link(Link *l, sd_bus_error *error) {
70 [ # # ]: 0 : assert(l);
71 : :
72 [ # # ]: 0 : if (l->flags & IFF_LOOPBACK)
73 : 0 : return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is loopback device.", l->ifname);
74 : :
75 : 0 : return 0;
76 : : }
77 : :
78 : 0 : int bus_link_method_set_ntp_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
79 : 0 : _cleanup_strv_free_ char **ntp = NULL;
80 : 0 : Link *l = userdata;
81 : : int r;
82 : : char **i;
83 : :
84 [ # # ]: 0 : assert(message);
85 [ # # ]: 0 : assert(l);
86 : :
87 : 0 : r = verify_managed_link(l, error);
88 [ # # ]: 0 : if (r < 0)
89 : 0 : return r;
90 : :
91 : 0 : r = sd_bus_message_read_strv(message, &ntp);
92 [ # # ]: 0 : if (r < 0)
93 : 0 : return r;
94 : :
95 [ # # # # ]: 0 : STRV_FOREACH(i, ntp) {
96 : 0 : r = dns_name_is_valid_or_address(*i);
97 [ # # ]: 0 : if (r < 0)
98 : 0 : return r;
99 [ # # ]: 0 : if (r == 0)
100 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NTP server: %s", *i);
101 : : }
102 : :
103 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
104 : : "org.freedesktop.network1.set-ntp-servers",
105 : : NULL, true, UID_INVALID,
106 : 0 : &l->manager->polkit_registry, error);
107 [ # # ]: 0 : if (r < 0)
108 : 0 : return r;
109 [ # # ]: 0 : if (r == 0)
110 : 0 : return 1; /* Polkit will call us back */
111 : :
112 : 0 : strv_free_and_replace(l->ntp, ntp);
113 : :
114 : 0 : (void) link_dirty(l);
115 : :
116 : 0 : return sd_bus_reply_method_return(message, NULL);
117 : : }
118 : :
119 : 0 : int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
120 : 0 : _cleanup_free_ struct in_addr_data *dns = NULL;
121 : 0 : size_t allocated = 0, n = 0;
122 : 0 : Link *l = userdata;
123 : : int r;
124 : :
125 [ # # ]: 0 : assert(message);
126 [ # # ]: 0 : assert(l);
127 : :
128 : 0 : r = verify_managed_link(l, error);
129 [ # # ]: 0 : if (r < 0)
130 : 0 : return r;
131 : :
132 : 0 : r = sd_bus_message_enter_container(message, 'a', "(iay)");
133 [ # # ]: 0 : if (r < 0)
134 : 0 : return r;
135 : :
136 : 0 : for (;;) {
137 : : int family;
138 : : size_t sz;
139 : : const void *d;
140 : :
141 : : assert_cc(sizeof(int) == sizeof(int32_t));
142 : :
143 : 0 : r = sd_bus_message_enter_container(message, 'r', "iay");
144 [ # # ]: 0 : if (r < 0)
145 : 0 : return r;
146 [ # # ]: 0 : if (r == 0)
147 : 0 : break;
148 : :
149 : 0 : r = sd_bus_message_read(message, "i", &family);
150 [ # # ]: 0 : if (r < 0)
151 : 0 : return r;
152 : :
153 [ # # # # ]: 0 : if (!IN_SET(family, AF_INET, AF_INET6))
154 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
155 : :
156 : 0 : r = sd_bus_message_read_array(message, 'y', &d, &sz);
157 [ # # ]: 0 : if (r < 0)
158 : 0 : return r;
159 [ # # ]: 0 : if (sz != FAMILY_ADDRESS_SIZE(family))
160 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
161 : :
162 [ # # ]: 0 : if (!dns_server_address_valid(family, d))
163 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
164 : :
165 : 0 : r = sd_bus_message_exit_container(message);
166 [ # # ]: 0 : if (r < 0)
167 : 0 : return r;
168 : :
169 [ # # ]: 0 : if (!GREEDY_REALLOC(dns, allocated, n+1))
170 : 0 : return -ENOMEM;
171 : :
172 : 0 : dns[n].family = family;
173 : 0 : memcpy(&dns[n].address, d, sz);
174 : 0 : n++;
175 : : }
176 : :
177 : 0 : r = sd_bus_message_exit_container(message);
178 [ # # ]: 0 : if (r < 0)
179 : 0 : return r;
180 : :
181 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
182 : : "org.freedesktop.network1.set-dns-servers",
183 : : NULL, true, UID_INVALID,
184 : 0 : &l->manager->polkit_registry, error);
185 [ # # ]: 0 : if (r < 0)
186 : 0 : return r;
187 [ # # ]: 0 : if (r == 0)
188 : 0 : return 1; /* Polkit will call us back */
189 : :
190 : 0 : free_and_replace(l->dns, dns);
191 : 0 : l->n_dns = n;
192 : :
193 : 0 : (void) link_dirty(l);
194 : :
195 : 0 : return sd_bus_reply_method_return(message, NULL);
196 : : }
197 : :
198 : 0 : int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
199 : 0 : _cleanup_(ordered_set_freep) OrderedSet *search_domains = NULL, *route_domains = NULL;
200 : 0 : Link *l = userdata;
201 : : int r;
202 : :
203 [ # # ]: 0 : assert(message);
204 [ # # ]: 0 : assert(l);
205 : :
206 : 0 : r = verify_managed_link(l, error);
207 [ # # ]: 0 : if (r < 0)
208 : 0 : return r;
209 : :
210 : 0 : r = sd_bus_message_enter_container(message, 'a', "(sb)");
211 [ # # ]: 0 : if (r < 0)
212 : 0 : return r;
213 : :
214 : 0 : for (;;) {
215 [ # # # ]: 0 : _cleanup_free_ char *str = NULL;
216 : : OrderedSet **domains;
217 : : const char *name;
218 : : int route_only;
219 : :
220 : 0 : r = sd_bus_message_read(message, "(sb)", &name, &route_only);
221 [ # # ]: 0 : if (r < 0)
222 : 0 : return r;
223 [ # # ]: 0 : if (r == 0)
224 : 0 : break;
225 : :
226 : 0 : r = dns_name_is_valid(name);
227 [ # # ]: 0 : if (r < 0)
228 : 0 : return r;
229 [ # # ]: 0 : if (r == 0)
230 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
231 [ # # # # ]: 0 : if (!route_only && dns_name_is_root(name))
232 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
233 : :
234 : 0 : r = dns_name_normalize(name, 0, &str);
235 [ # # ]: 0 : if (r < 0)
236 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
237 : :
238 [ # # ]: 0 : domains = route_only ? &route_domains : &search_domains;
239 : 0 : r = ordered_set_ensure_allocated(domains, &string_hash_ops);
240 [ # # ]: 0 : if (r < 0)
241 : 0 : return r;
242 : :
243 : 0 : r = ordered_set_put(*domains, str);
244 [ # # ]: 0 : if (r < 0)
245 : 0 : return r;
246 : :
247 : 0 : TAKE_PTR(str);
248 : : }
249 : :
250 : 0 : r = sd_bus_message_exit_container(message);
251 [ # # ]: 0 : if (r < 0)
252 : 0 : return r;
253 : :
254 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
255 : : "org.freedesktop.network1.set-domains",
256 : : NULL, true, UID_INVALID,
257 : 0 : &l->manager->polkit_registry, error);
258 [ # # ]: 0 : if (r < 0)
259 : 0 : return r;
260 [ # # ]: 0 : if (r == 0)
261 : 0 : return 1; /* Polkit will call us back */
262 : :
263 : 0 : ordered_set_free_free(l->search_domains);
264 : 0 : ordered_set_free_free(l->route_domains);
265 : 0 : l->search_domains = TAKE_PTR(search_domains);
266 : 0 : l->route_domains = TAKE_PTR(route_domains);
267 : :
268 : 0 : (void) link_dirty(l);
269 : :
270 : 0 : return sd_bus_reply_method_return(message, NULL);
271 : : }
272 : :
273 : 0 : int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) {
274 : 0 : Link *l = userdata;
275 : : int r, b;
276 : :
277 [ # # ]: 0 : assert(message);
278 [ # # ]: 0 : assert(l);
279 : :
280 : 0 : r = verify_managed_link(l, error);
281 [ # # ]: 0 : if (r < 0)
282 : 0 : return r;
283 : :
284 : 0 : r = sd_bus_message_read(message, "b", &b);
285 [ # # ]: 0 : if (r < 0)
286 : 0 : return r;
287 : :
288 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
289 : : "org.freedesktop.network1.set-default-route",
290 : : NULL, true, UID_INVALID,
291 : 0 : &l->manager->polkit_registry, error);
292 [ # # ]: 0 : if (r < 0)
293 : 0 : return r;
294 [ # # ]: 0 : if (r == 0)
295 : 0 : return 1; /* Polkit will call us back */
296 : :
297 [ # # ]: 0 : if (l->dns_default_route != b) {
298 : 0 : l->dns_default_route = b;
299 : 0 : (void) link_dirty(l);
300 : : }
301 : :
302 : 0 : return sd_bus_reply_method_return(message, NULL);
303 : : }
304 : :
305 : 0 : int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
306 : 0 : Link *l = userdata;
307 : : ResolveSupport mode;
308 : : const char *llmnr;
309 : : int r;
310 : :
311 [ # # ]: 0 : assert(message);
312 [ # # ]: 0 : assert(l);
313 : :
314 : 0 : r = verify_managed_link(l, error);
315 [ # # ]: 0 : if (r < 0)
316 : 0 : return r;
317 : :
318 : 0 : r = sd_bus_message_read(message, "s", &llmnr);
319 [ # # ]: 0 : if (r < 0)
320 : 0 : return r;
321 : :
322 [ # # ]: 0 : if (isempty(llmnr))
323 : 0 : mode = RESOLVE_SUPPORT_YES;
324 : : else {
325 : 0 : mode = resolve_support_from_string(llmnr);
326 [ # # ]: 0 : if (mode < 0)
327 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
328 : : }
329 : :
330 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
331 : : "org.freedesktop.network1.set-llmnr",
332 : : NULL, true, UID_INVALID,
333 : 0 : &l->manager->polkit_registry, error);
334 [ # # ]: 0 : if (r < 0)
335 : 0 : return r;
336 [ # # ]: 0 : if (r == 0)
337 : 0 : return 1; /* Polkit will call us back */
338 : :
339 [ # # ]: 0 : if (l->llmnr != mode) {
340 : 0 : l->llmnr = mode;
341 : 0 : (void) link_dirty(l);
342 : : }
343 : :
344 : 0 : return sd_bus_reply_method_return(message, NULL);
345 : : }
346 : :
347 : 0 : int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
348 : 0 : Link *l = userdata;
349 : : ResolveSupport mode;
350 : : const char *mdns;
351 : : int r;
352 : :
353 [ # # ]: 0 : assert(message);
354 [ # # ]: 0 : assert(l);
355 : :
356 : 0 : r = verify_managed_link(l, error);
357 [ # # ]: 0 : if (r < 0)
358 : 0 : return r;
359 : :
360 : 0 : r = sd_bus_message_read(message, "s", &mdns);
361 [ # # ]: 0 : if (r < 0)
362 : 0 : return r;
363 : :
364 [ # # ]: 0 : if (isempty(mdns))
365 : 0 : mode = RESOLVE_SUPPORT_NO;
366 : : else {
367 : 0 : mode = resolve_support_from_string(mdns);
368 [ # # ]: 0 : if (mode < 0)
369 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
370 : : }
371 : :
372 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
373 : : "org.freedesktop.network1.set-mdns",
374 : : NULL, true, UID_INVALID,
375 : 0 : &l->manager->polkit_registry, error);
376 [ # # ]: 0 : if (r < 0)
377 : 0 : return r;
378 [ # # ]: 0 : if (r == 0)
379 : 0 : return 1; /* Polkit will call us back */
380 : :
381 [ # # ]: 0 : if (l->mdns != mode) {
382 : 0 : l->mdns = mode;
383 : 0 : (void) link_dirty(l);
384 : : }
385 : :
386 : 0 : return sd_bus_reply_method_return(message, NULL);
387 : : }
388 : :
389 : 0 : int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) {
390 : 0 : Link *l = userdata;
391 : : const char *dns_over_tls;
392 : : DnsOverTlsMode mode;
393 : : int r;
394 : :
395 [ # # ]: 0 : assert(message);
396 [ # # ]: 0 : assert(l);
397 : :
398 : 0 : r = verify_managed_link(l, error);
399 [ # # ]: 0 : if (r < 0)
400 : 0 : return r;
401 : :
402 : 0 : r = sd_bus_message_read(message, "s", &dns_over_tls);
403 [ # # ]: 0 : if (r < 0)
404 : 0 : return r;
405 : :
406 [ # # ]: 0 : if (isempty(dns_over_tls))
407 : 0 : mode = _DNS_OVER_TLS_MODE_INVALID;
408 : : else {
409 : 0 : mode = dns_over_tls_mode_from_string(dns_over_tls);
410 [ # # ]: 0 : if (mode < 0)
411 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
412 : : }
413 : :
414 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
415 : : "org.freedesktop.network1.set-dns-over-tls",
416 : : NULL, true, UID_INVALID,
417 : 0 : &l->manager->polkit_registry, error);
418 [ # # ]: 0 : if (r < 0)
419 : 0 : return r;
420 [ # # ]: 0 : if (r == 0)
421 : 0 : return 1; /* Polkit will call us back */
422 : :
423 [ # # ]: 0 : if (l->dns_over_tls_mode != mode) {
424 : 0 : l->dns_over_tls_mode = mode;
425 : 0 : (void) link_dirty(l);
426 : : }
427 : :
428 : 0 : return sd_bus_reply_method_return(message, NULL);
429 : : }
430 : :
431 : 0 : int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
432 : 0 : Link *l = userdata;
433 : : const char *dnssec;
434 : : DnssecMode mode;
435 : : int r;
436 : :
437 [ # # ]: 0 : assert(message);
438 [ # # ]: 0 : assert(l);
439 : :
440 : 0 : r = verify_managed_link(l, error);
441 [ # # ]: 0 : if (r < 0)
442 : 0 : return r;
443 : :
444 : 0 : r = sd_bus_message_read(message, "s", &dnssec);
445 [ # # ]: 0 : if (r < 0)
446 : 0 : return r;
447 : :
448 [ # # ]: 0 : if (isempty(dnssec))
449 : 0 : mode = _DNSSEC_MODE_INVALID;
450 : : else {
451 : 0 : mode = dnssec_mode_from_string(dnssec);
452 [ # # ]: 0 : if (mode < 0)
453 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
454 : : }
455 : :
456 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
457 : : "org.freedesktop.network1.set-dnssec",
458 : : NULL, true, UID_INVALID,
459 : 0 : &l->manager->polkit_registry, error);
460 [ # # ]: 0 : if (r < 0)
461 : 0 : return r;
462 [ # # ]: 0 : if (r == 0)
463 : 0 : return 1; /* Polkit will call us back */
464 : :
465 [ # # ]: 0 : if (l->dnssec_mode != mode) {
466 : 0 : l->dnssec_mode = mode;
467 : 0 : (void) link_dirty(l);
468 : : }
469 : :
470 : 0 : return sd_bus_reply_method_return(message, NULL);
471 : : }
472 : :
473 : 0 : int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
474 : 0 : _cleanup_set_free_free_ Set *ns = NULL;
475 : 0 : _cleanup_strv_free_ char **ntas = NULL;
476 : 0 : Link *l = userdata;
477 : : int r;
478 : : char **i;
479 : :
480 [ # # ]: 0 : assert(message);
481 [ # # ]: 0 : assert(l);
482 : :
483 : 0 : r = verify_managed_link(l, error);
484 [ # # ]: 0 : if (r < 0)
485 : 0 : return r;
486 : :
487 : 0 : r = sd_bus_message_read_strv(message, &ntas);
488 [ # # ]: 0 : if (r < 0)
489 : 0 : return r;
490 : :
491 [ # # # # ]: 0 : STRV_FOREACH(i, ntas) {
492 : 0 : r = dns_name_is_valid(*i);
493 [ # # ]: 0 : if (r < 0)
494 : 0 : return r;
495 [ # # ]: 0 : if (r == 0)
496 : 0 : return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
497 : : }
498 : :
499 : 0 : ns = set_new(&dns_name_hash_ops);
500 [ # # ]: 0 : if (!ns)
501 : 0 : return -ENOMEM;
502 : :
503 [ # # # # ]: 0 : STRV_FOREACH(i, ntas) {
504 : 0 : r = set_put_strdup(ns, *i);
505 [ # # ]: 0 : if (r < 0)
506 : 0 : return r;
507 : : }
508 : :
509 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
510 : : "org.freedesktop.network1.set-dnssec-negative-trust-anchors",
511 : : NULL, true, UID_INVALID,
512 : 0 : &l->manager->polkit_registry, error);
513 [ # # ]: 0 : if (r < 0)
514 : 0 : return r;
515 [ # # ]: 0 : if (r == 0)
516 : 0 : return 1; /* Polkit will call us back */
517 : :
518 : 0 : set_free_free(l->dnssec_negative_trust_anchors);
519 : 0 : l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
520 : :
521 : 0 : (void) link_dirty(l);
522 : :
523 : 0 : return sd_bus_reply_method_return(message, NULL);
524 : : }
525 : :
526 : 0 : int bus_link_method_revert_ntp(sd_bus_message *message, void *userdata, sd_bus_error *error) {
527 : 0 : Link *l = userdata;
528 : : int r;
529 : :
530 [ # # ]: 0 : assert(message);
531 [ # # ]: 0 : assert(l);
532 : :
533 : 0 : r = verify_managed_link(l, error);
534 [ # # ]: 0 : if (r < 0)
535 : 0 : return r;
536 : :
537 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
538 : : "org.freedesktop.network1.revert-ntp",
539 : : NULL, true, UID_INVALID,
540 : 0 : &l->manager->polkit_registry, error);
541 [ # # ]: 0 : if (r < 0)
542 : 0 : return r;
543 [ # # ]: 0 : if (r == 0)
544 : 0 : return 1; /* Polkit will call us back */
545 : :
546 : 0 : link_ntp_settings_clear(l);
547 : 0 : (void) link_dirty(l);
548 : :
549 : 0 : return sd_bus_reply_method_return(message, NULL);
550 : : }
551 : :
552 : 0 : int bus_link_method_revert_dns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
553 : 0 : Link *l = userdata;
554 : : int r;
555 : :
556 [ # # ]: 0 : assert(message);
557 [ # # ]: 0 : assert(l);
558 : :
559 : 0 : r = verify_managed_link(l, error);
560 [ # # ]: 0 : if (r < 0)
561 : 0 : return r;
562 : :
563 : 0 : r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
564 : : "org.freedesktop.network1.revert-dns",
565 : : NULL, true, UID_INVALID,
566 : 0 : &l->manager->polkit_registry, error);
567 [ # # ]: 0 : if (r < 0)
568 : 0 : return r;
569 [ # # ]: 0 : if (r == 0)
570 : 0 : return 1; /* Polkit will call us back */
571 : :
572 : 0 : link_dns_settings_clear(l);
573 : 0 : (void) link_dirty(l);
574 : :
575 : 0 : return sd_bus_reply_method_return(message, NULL);
576 : : }
577 : :
578 : : const sd_bus_vtable link_vtable[] = {
579 : : SD_BUS_VTABLE_START(0),
580 : :
581 : : SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
582 : : SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Link, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
583 : : SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
584 : : SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
585 : : SD_BUS_PROPERTY("BitRates", "(tt)", property_get_bit_rates, 0, 0),
586 : :
587 : : SD_BUS_METHOD("SetNTP", "as", NULL, bus_link_method_set_ntp_servers, SD_BUS_VTABLE_UNPRIVILEGED),
588 : : SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
589 : : SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED),
590 : : SD_BUS_METHOD("SetDefaultRoute", "b", NULL, bus_link_method_set_default_route, SD_BUS_VTABLE_UNPRIVILEGED),
591 : : SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
592 : : SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
593 : : SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
594 : : SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
595 : : SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
596 : : SD_BUS_METHOD("RevertNTP", NULL, NULL, bus_link_method_revert_ntp, SD_BUS_VTABLE_UNPRIVILEGED),
597 : : SD_BUS_METHOD("RevertDNS", NULL, NULL, bus_link_method_revert_dns, SD_BUS_VTABLE_UNPRIVILEGED),
598 : :
599 : : SD_BUS_VTABLE_END
600 : : };
601 : :
602 : 0 : char *link_bus_path(Link *link) {
603 : 0 : _cleanup_free_ char *ifindex = NULL;
604 : : char *p;
605 : : int r;
606 : :
607 [ # # ]: 0 : assert(link);
608 [ # # ]: 0 : assert(link->ifindex > 0);
609 : :
610 [ # # ]: 0 : if (asprintf(&ifindex, "%d", link->ifindex) < 0)
611 : 0 : return NULL;
612 : :
613 : 0 : r = sd_bus_path_encode("/org/freedesktop/network1/link", ifindex, &p);
614 [ # # ]: 0 : if (r < 0)
615 : 0 : return NULL;
616 : :
617 : 0 : return p;
618 : : }
619 : :
620 : 0 : int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
621 : 0 : _cleanup_strv_free_ char **l = NULL;
622 : 0 : Manager *m = userdata;
623 : 0 : unsigned c = 0;
624 : : Link *link;
625 : : Iterator i;
626 : :
627 [ # # ]: 0 : assert(bus);
628 [ # # ]: 0 : assert(path);
629 [ # # ]: 0 : assert(m);
630 [ # # ]: 0 : assert(nodes);
631 : :
632 [ # # ]: 0 : l = new0(char*, hashmap_size(m->links) + 1);
633 [ # # ]: 0 : if (!l)
634 : 0 : return -ENOMEM;
635 : :
636 [ # # ]: 0 : HASHMAP_FOREACH(link, m->links, i) {
637 : : char *p;
638 : :
639 : 0 : p = link_bus_path(link);
640 [ # # ]: 0 : if (!p)
641 : 0 : return -ENOMEM;
642 : :
643 : 0 : l[c++] = p;
644 : : }
645 : :
646 : 0 : l[c] = NULL;
647 : 0 : *nodes = TAKE_PTR(l);
648 : :
649 : 0 : return 1;
650 : : }
651 : :
652 : 0 : int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
653 : 0 : _cleanup_free_ char *identifier = NULL;
654 : 0 : Manager *m = userdata;
655 : : Link *link;
656 : : int ifindex, r;
657 : :
658 [ # # ]: 0 : assert(bus);
659 [ # # ]: 0 : assert(path);
660 [ # # ]: 0 : assert(interface);
661 [ # # ]: 0 : assert(m);
662 [ # # ]: 0 : assert(found);
663 : :
664 : 0 : r = sd_bus_path_decode(path, "/org/freedesktop/network1/link", &identifier);
665 [ # # ]: 0 : if (r <= 0)
666 : 0 : return 0;
667 : :
668 : 0 : r = parse_ifindex(identifier, &ifindex);
669 [ # # ]: 0 : if (r < 0)
670 : 0 : return 0;
671 : :
672 : 0 : r = link_get(m, ifindex, &link);
673 [ # # ]: 0 : if (r < 0)
674 : 0 : return 0;
675 : :
676 : 0 : *found = link;
677 : :
678 : 0 : return 1;
679 : : }
680 : :
681 : 52 : int link_send_changed_strv(Link *link, char **properties) {
682 : 52 : _cleanup_free_ char *p = NULL;
683 : :
684 [ - + ]: 52 : assert(link);
685 [ - + ]: 52 : assert(link->manager);
686 [ - + ]: 52 : assert(properties);
687 : :
688 [ + - ]: 52 : if (!link->manager->bus)
689 : 52 : return 0;
690 : :
691 : 0 : p = link_bus_path(link);
692 [ # # ]: 0 : if (!p)
693 : 0 : return -ENOMEM;
694 : :
695 : 0 : return sd_bus_emit_properties_changed_strv(
696 : 0 : link->manager->bus,
697 : : p,
698 : : "org.freedesktop.network1.Link",
699 : : properties);
700 : : }
701 : :
702 : 28 : int link_send_changed(Link *link, const char *property, ...) {
703 : : char **properties;
704 : :
705 [ - + - + : 28 : properties = strv_from_stdarg_alloca(property);
- + - + +
- ]
706 : :
707 : 28 : return link_send_changed_strv(link, properties);
708 : : }
|