]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-link-bus.c
resolved: make two functions static
[thirdparty/systemd.git] / src / resolve / resolved-link-bus.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
3abaabda 2
6ff79f76 3#include <net/if.h>
52aaef0f
ZJS
4#include <netinet/in.h>
5#include <sys/capability.h>
6ff79f76 6
3abaabda 7#include "alloc-util.h"
04b764bf 8#include "bus-common-errors.h"
3abaabda
LP
9#include "bus-util.h"
10#include "parse-util.h"
11#include "resolve-util.h"
12#include "resolved-bus.h"
13#include "resolved-link-bus.h"
7207052d 14#include "resolved-resolv-conf.h"
0a6c0745 15#include "stdio-util.h"
3abaabda 16#include "strv.h"
52aaef0f 17#include "user-util.h"
3abaabda 18
acd380c4
YW
19static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
20static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
3abaabda 21
c9299be2 22static int property_get_dns_over_tls_mode(
d050561a
IT
23 sd_bus *bus,
24 const char *path,
25 const char *interface,
26 const char *property,
27 sd_bus_message *reply,
28 void *userdata,
29 sd_bus_error *error) {
30
31 Link *l = userdata;
32
33 assert(reply);
34 assert(l);
35
c9299be2 36 return sd_bus_message_append(reply, "s", dns_over_tls_mode_to_string(link_get_dns_over_tls_mode(l)));
d050561a
IT
37}
38
3abaabda
LP
39static int property_get_dns(
40 sd_bus *bus,
41 const char *path,
42 const char *interface,
43 const char *property,
44 sd_bus_message *reply,
45 void *userdata,
46 sd_bus_error *error) {
47
48 Link *l = userdata;
49 DnsServer *s;
50 int r;
51
52 assert(reply);
53 assert(l);
54
55 r = sd_bus_message_open_container(reply, 'a', "(iay)");
56 if (r < 0)
57 return r;
58
59 LIST_FOREACH(servers, s, l->dns_servers) {
60 r = bus_dns_server_append(reply, s, false);
61 if (r < 0)
62 return r;
63 }
64
65 return sd_bus_message_close_container(reply);
66}
67
b7ac92cd
YW
68static int property_get_current_dns_server(
69 sd_bus *bus,
70 const char *path,
71 const char *interface,
72 const char *property,
73 sd_bus_message *reply,
74 void *userdata,
75 sd_bus_error *error) {
76
77 DnsServer *s;
78
79 assert(reply);
80 assert(userdata);
81
82 s = *(DnsServer **) userdata;
83
84 return bus_dns_server_append(reply, s, false);
85}
86
3abaabda
LP
87static int property_get_domains(
88 sd_bus *bus,
89 const char *path,
90 const char *interface,
91 const char *property,
92 sd_bus_message *reply,
93 void *userdata,
94 sd_bus_error *error) {
95
96 Link *l = userdata;
97 DnsSearchDomain *d;
98 int r;
99
100 assert(reply);
101 assert(l);
102
ad44b56b 103 r = sd_bus_message_open_container(reply, 'a', "(sb)");
3abaabda
LP
104 if (r < 0)
105 return r;
106
107 LIST_FOREACH(domains, d, l->search_domains) {
ad44b56b 108 r = sd_bus_message_append(reply, "(sb)", d->name, d->route_only);
3abaabda
LP
109 if (r < 0)
110 return r;
111 }
112
113 return sd_bus_message_close_container(reply);
114}
115
77673795
LP
116static int property_get_default_route(
117 sd_bus *bus,
118 const char *path,
119 const char *interface,
120 const char *property,
121 sd_bus_message *reply,
122 void *userdata,
123 sd_bus_error *error) {
124
125 Link *l = userdata;
126
127 assert(reply);
128 assert(l);
129
130 /* Return what is configured, if there's something configured */
131 if (l->default_route >= 0)
132 return sd_bus_message_append(reply, "b", l->default_route);
133
134 /* Otherwise report what is in effect */
135 if (l->unicast_scope)
136 return sd_bus_message_append(reply, "b", dns_scope_is_default_route(l->unicast_scope));
137
138 return sd_bus_message_append(reply, "b", false);
139}
140
3abaabda
LP
141static int property_get_scopes_mask(
142 sd_bus *bus,
143 const char *path,
144 const char *interface,
145 const char *property,
146 sd_bus_message *reply,
147 void *userdata,
148 sd_bus_error *error) {
149
150 Link *l = userdata;
151 uint64_t mask;
152
153 assert(reply);
154 assert(l);
155
156 mask = (l->unicast_scope ? SD_RESOLVED_DNS : 0) |
157 (l->llmnr_ipv4_scope ? SD_RESOLVED_LLMNR_IPV4 : 0) |
158 (l->llmnr_ipv6_scope ? SD_RESOLVED_LLMNR_IPV6 : 0) |
159 (l->mdns_ipv4_scope ? SD_RESOLVED_MDNS_IPV4 : 0) |
160 (l->mdns_ipv6_scope ? SD_RESOLVED_MDNS_IPV6 : 0);
161
162 return sd_bus_message_append(reply, "t", mask);
163}
164
165static int property_get_ntas(
166 sd_bus *bus,
167 const char *path,
168 const char *interface,
169 const char *property,
170 sd_bus_message *reply,
171 void *userdata,
172 sd_bus_error *error) {
173
174 Link *l = userdata;
175 const char *name;
176 Iterator i;
177 int r;
178
179 assert(reply);
180 assert(l);
181
182 r = sd_bus_message_open_container(reply, 'a', "s");
183 if (r < 0)
184 return r;
185
186 SET_FOREACH(name, l->dnssec_negative_trust_anchors, i) {
187 r = sd_bus_message_append(reply, "s", name);
188 if (r < 0)
189 return r;
190 }
191
192 return sd_bus_message_close_container(reply);
193}
194
04b764bf
LP
195static int verify_unmanaged_link(Link *l, sd_bus_error *error) {
196 assert(l);
197
198 if (l->flags & IFF_LOOPBACK)
6ff79f76 199 return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is loopback device.", l->ifname);
04b764bf 200 if (l->is_managed)
6ff79f76 201 return sd_bus_error_setf(error, BUS_ERROR_LINK_BUSY, "Link %s is managed.", l->ifname);
04b764bf
LP
202
203 return 0;
204}
205
d2ec6608
LP
206int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
207 _cleanup_free_ struct in_addr_data *dns = NULL;
208 size_t allocated = 0, n = 0;
209 Link *l = userdata;
210 unsigned i;
211 int r;
212
213 assert(message);
214 assert(l);
215
04b764bf
LP
216 r = verify_unmanaged_link(l, error);
217 if (r < 0)
218 return r;
219
d2ec6608
LP
220 r = sd_bus_message_enter_container(message, 'a', "(iay)");
221 if (r < 0)
222 return r;
223
224 for (;;) {
225 int family;
226 size_t sz;
227 const void *d;
228
229 assert_cc(sizeof(int) == sizeof(int32_t));
230
231 r = sd_bus_message_enter_container(message, 'r', "iay");
232 if (r < 0)
233 return r;
234 if (r == 0)
235 break;
236
237 r = sd_bus_message_read(message, "i", &family);
238 if (r < 0)
239 return r;
240
241 if (!IN_SET(family, AF_INET, AF_INET6))
242 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
243
244 r = sd_bus_message_read_array(message, 'y', &d, &sz);
245 if (r < 0)
246 return r;
247 if (sz != FAMILY_ADDRESS_SIZE(family))
248 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
249
b30bf55d
LP
250 if (!dns_server_address_valid(family, d))
251 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
252
d2ec6608
LP
253 r = sd_bus_message_exit_container(message);
254 if (r < 0)
255 return r;
256
257 if (!GREEDY_REALLOC(dns, allocated, n+1))
258 return -ENOMEM;
259
260 dns[n].family = family;
261 memcpy(&dns[n].address, d, sz);
262 n++;
263 }
264
265 r = sd_bus_message_exit_container(message);
266 if (r < 0)
267 return r;
268
52aaef0f
ZJS
269 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
270 "org.freedesktop.resolve1.set-dns-servers",
271 NULL, true, UID_INVALID,
272 &l->manager->polkit_registry, error);
273 if (r < 0)
274 return r;
275 if (r == 0)
276 return 1; /* Polkit will call us back */
277
d2ec6608
LP
278 dns_server_mark_all(l->dns_servers);
279
280 for (i = 0; i < n; i++) {
281 DnsServer *s;
282
2817157b 283 s = dns_server_find(l->dns_servers, dns[i].family, &dns[i].address, 0);
d2ec6608
LP
284 if (s)
285 dns_server_move_back_and_unmark(s);
286 else {
2817157b 287 r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i].family, &dns[i].address, 0);
d2ec6608
LP
288 if (r < 0)
289 goto clear;
290 }
291
292 }
293
294 dns_server_unlink_marked(l->dns_servers);
295 link_allocate_scopes(l);
296
943ef07c 297 (void) link_save_user(l);
7207052d
LP
298 (void) manager_write_resolv_conf(l->manager);
299
d2ec6608
LP
300 return sd_bus_reply_method_return(message, NULL);
301
302clear:
303 dns_server_unlink_all(l->dns_servers);
304 return r;
305}
306
ee116b54 307int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d2ec6608 308 Link *l = userdata;
d2ec6608
LP
309 int r;
310
311 assert(message);
312 assert(l);
313
04b764bf
LP
314 r = verify_unmanaged_link(l, error);
315 if (r < 0)
316 return r;
317
ad44b56b 318 r = sd_bus_message_enter_container(message, 'a', "(sb)");
d2ec6608
LP
319 if (r < 0)
320 return r;
321
ad44b56b
LP
322 for (;;) {
323 const char *name;
324 int route_only;
d2ec6608 325
ad44b56b 326 r = sd_bus_message_read(message, "(sb)", &name, &route_only);
d2ec6608
LP
327 if (r < 0)
328 return r;
329 if (r == 0)
ad44b56b
LP
330 break;
331
332 r = dns_name_is_valid(name);
333 if (r < 0)
334 return r;
335 if (r == 0)
336 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
337 if (!route_only && dns_name_is_root(name))
d2ec6608
LP
338 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
339 }
340
ad44b56b
LP
341 r = sd_bus_message_rewind(message, false);
342 if (r < 0)
343 return r;
344
52aaef0f
ZJS
345 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
346 "org.freedesktop.resolve1.set-domains",
347 NULL, true, UID_INVALID,
348 &l->manager->polkit_registry, error);
349 if (r < 0)
350 return r;
351 if (r == 0)
352 return 1; /* Polkit will call us back */
353
354 dns_search_domain_mark_all(l->search_domains);
355
ad44b56b 356 for (;;) {
d2ec6608 357 DnsSearchDomain *d;
ad44b56b
LP
358 const char *name;
359 int route_only;
d2ec6608 360
ad44b56b
LP
361 r = sd_bus_message_read(message, "(sb)", &name, &route_only);
362 if (r < 0)
363 goto clear;
364 if (r == 0)
365 break;
366
367 r = dns_search_domain_find(l->search_domains, name, &d);
d2ec6608
LP
368 if (r < 0)
369 goto clear;
370
371 if (r > 0)
372 dns_search_domain_move_back_and_unmark(d);
373 else {
ad44b56b 374 r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
d2ec6608
LP
375 if (r < 0)
376 goto clear;
377 }
ad44b56b
LP
378
379 d->route_only = route_only;
d2ec6608
LP
380 }
381
ad44b56b
LP
382 r = sd_bus_message_exit_container(message);
383 if (r < 0)
384 goto clear;
385
d2ec6608 386 dns_search_domain_unlink_marked(l->search_domains);
7207052d 387
943ef07c 388 (void) link_save_user(l);
7207052d
LP
389 (void) manager_write_resolv_conf(l->manager);
390
d2ec6608
LP
391 return sd_bus_reply_method_return(message, NULL);
392
393clear:
394 dns_search_domain_unlink_all(l->search_domains);
395 return r;
396}
397
77673795
LP
398int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) {
399 Link *l = userdata;
400 int r, b;
401
402 assert(message);
403 assert(l);
404
405 r = verify_unmanaged_link(l, error);
406 if (r < 0)
407 return r;
408
409 r = sd_bus_message_read(message, "b", &b);
410 if (r < 0)
411 return r;
412
52aaef0f
ZJS
413 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
414 "org.freedesktop.resolve1.set-default-route",
415 NULL, true, UID_INVALID,
416 &l->manager->polkit_registry, error);
417 if (r < 0)
418 return r;
419 if (r == 0)
420 return 1; /* Polkit will call us back */
421
77673795
LP
422 if (l->default_route != b) {
423 l->default_route = b;
424
425 (void) link_save_user(l);
426 (void) manager_write_resolv_conf(l->manager);
427 }
428
429 return sd_bus_reply_method_return(message, NULL);
430}
431
d2ec6608
LP
432int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
433 Link *l = userdata;
434 ResolveSupport mode;
435 const char *llmnr;
436 int r;
437
438 assert(message);
439 assert(l);
440
04b764bf
LP
441 r = verify_unmanaged_link(l, error);
442 if (r < 0)
443 return r;
444
d2ec6608
LP
445 r = sd_bus_message_read(message, "s", &llmnr);
446 if (r < 0)
447 return r;
448
449 if (isempty(llmnr))
450 mode = RESOLVE_SUPPORT_YES;
451 else {
452 mode = resolve_support_from_string(llmnr);
453 if (mode < 0)
454 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
455 }
456
52aaef0f
ZJS
457 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
458 "org.freedesktop.resolve1.set-llmnr",
459 NULL, true, UID_INVALID,
460 &l->manager->polkit_registry, error);
461 if (r < 0)
462 return r;
463 if (r == 0)
464 return 1; /* Polkit will call us back */
465
d2ec6608
LP
466 l->llmnr_support = mode;
467 link_allocate_scopes(l);
468 link_add_rrs(l, false);
469
943ef07c
LP
470 (void) link_save_user(l);
471
d2ec6608
LP
472 return sd_bus_reply_method_return(message, NULL);
473}
474
475int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
476 Link *l = userdata;
477 ResolveSupport mode;
478 const char *mdns;
479 int r;
480
481 assert(message);
482 assert(l);
483
04b764bf
LP
484 r = verify_unmanaged_link(l, error);
485 if (r < 0)
486 return r;
487
d2ec6608
LP
488 r = sd_bus_message_read(message, "s", &mdns);
489 if (r < 0)
490 return r;
491
492 if (isempty(mdns))
493 mode = RESOLVE_SUPPORT_NO;
494 else {
495 mode = resolve_support_from_string(mdns);
496 if (mode < 0)
497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
498 }
499
52aaef0f
ZJS
500 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
501 "org.freedesktop.resolve1.set-mdns",
502 NULL, true, UID_INVALID,
503 &l->manager->polkit_registry, error);
504 if (r < 0)
505 return r;
506 if (r == 0)
507 return 1; /* Polkit will call us back */
508
d2ec6608
LP
509 l->mdns_support = mode;
510 link_allocate_scopes(l);
511 link_add_rrs(l, false);
512
943ef07c
LP
513 (void) link_save_user(l);
514
d2ec6608
LP
515 return sd_bus_reply_method_return(message, NULL);
516}
517
c9299be2 518int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d050561a 519 Link *l = userdata;
c9299be2
IT
520 const char *dns_over_tls;
521 DnsOverTlsMode mode;
d050561a
IT
522 int r;
523
524 assert(message);
525 assert(l);
526
527 r = verify_unmanaged_link(l, error);
528 if (r < 0)
529 return r;
530
c9299be2 531 r = sd_bus_message_read(message, "s", &dns_over_tls);
d050561a
IT
532 if (r < 0)
533 return r;
534
c9299be2
IT
535 if (isempty(dns_over_tls))
536 mode = _DNS_OVER_TLS_MODE_INVALID;
d050561a 537 else {
c9299be2 538 mode = dns_over_tls_mode_from_string(dns_over_tls);
d050561a 539 if (mode < 0)
c9299be2 540 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
d050561a
IT
541 }
542
52aaef0f
ZJS
543 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
544 "org.freedesktop.resolve1.set-dns-over-tls",
545 NULL, true, UID_INVALID,
546 &l->manager->polkit_registry, error);
547 if (r < 0)
548 return r;
549 if (r == 0)
550 return 1; /* Polkit will call us back */
551
c9299be2 552 link_set_dns_over_tls_mode(l, mode);
d050561a
IT
553
554 (void) link_save_user(l);
555
556 return sd_bus_reply_method_return(message, NULL);
557}
558
d2ec6608
LP
559int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 Link *l = userdata;
561 const char *dnssec;
562 DnssecMode mode;
563 int r;
564
565 assert(message);
566 assert(l);
567
04b764bf
LP
568 r = verify_unmanaged_link(l, error);
569 if (r < 0)
570 return r;
571
d2ec6608
LP
572 r = sd_bus_message_read(message, "s", &dnssec);
573 if (r < 0)
574 return r;
575
576 if (isempty(dnssec))
577 mode = _DNSSEC_MODE_INVALID;
578 else {
579 mode = dnssec_mode_from_string(dnssec);
580 if (mode < 0)
581 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
582 }
583
52aaef0f
ZJS
584 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
585 "org.freedesktop.resolve1.set-dnssec",
586 NULL, true, UID_INVALID,
587 &l->manager->polkit_registry, error);
588 if (r < 0)
589 return r;
590 if (r == 0)
591 return 1; /* Polkit will call us back */
592
d2ec6608
LP
593 link_set_dnssec_mode(l, mode);
594
943ef07c
LP
595 (void) link_save_user(l);
596
d2ec6608
LP
597 return sd_bus_reply_method_return(message, NULL);
598}
599
600int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
601 _cleanup_set_free_free_ Set *ns = NULL;
c6d92582 602 _cleanup_strv_free_ char **ntas = NULL;
d2ec6608
LP
603 Link *l = userdata;
604 int r;
605 char **i;
606
607 assert(message);
608 assert(l);
609
04b764bf
LP
610 r = verify_unmanaged_link(l, error);
611 if (r < 0)
612 return r;
613
ab77c879
ZJS
614 ns = set_new(&dns_name_hash_ops);
615 if (!ns)
616 return -ENOMEM;
617
d2ec6608
LP
618 r = sd_bus_message_read_strv(message, &ntas);
619 if (r < 0)
620 return r;
621
622 STRV_FOREACH(i, ntas) {
623 r = dns_name_is_valid(*i);
624 if (r < 0)
625 return r;
626 if (r == 0)
ab77c879
ZJS
627 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
628 "Invalid negative trust anchor domain: %s", *i);
d2ec6608 629
d2ec6608
LP
630 r = set_put_strdup(ns, *i);
631 if (r < 0)
632 return r;
633 }
634
52aaef0f
ZJS
635 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
636 "org.freedesktop.resolve1.set-dnssec-negative-trust-anchors",
637 NULL, true, UID_INVALID,
638 &l->manager->polkit_registry, error);
639 if (r < 0)
640 return r;
641 if (r == 0)
642 return 1; /* Polkit will call us back */
643
d2ec6608 644 set_free_free(l->dnssec_negative_trust_anchors);
ae2a15bc 645 l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
d2ec6608 646
943ef07c
LP
647 (void) link_save_user(l);
648
d2ec6608
LP
649 return sd_bus_reply_method_return(message, NULL);
650}
651
652int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error *error) {
653 Link *l = userdata;
04b764bf 654 int r;
d2ec6608
LP
655
656 assert(message);
657 assert(l);
658
04b764bf
LP
659 r = verify_unmanaged_link(l, error);
660 if (r < 0)
661 return r;
662
52aaef0f
ZJS
663 r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
664 "org.freedesktop.resolve1.revert",
665 NULL, true, UID_INVALID,
666 &l->manager->polkit_registry, error);
667 if (r < 0)
668 return r;
669 if (r == 0)
670 return 1; /* Polkit will call us back */
671
d2ec6608
LP
672 link_flush_settings(l);
673 link_allocate_scopes(l);
674 link_add_rrs(l, false);
675
943ef07c 676 (void) link_save_user(l);
7207052d
LP
677 (void) manager_write_resolv_conf(l->manager);
678
d2ec6608
LP
679 return sd_bus_reply_method_return(message, NULL);
680}
681
3abaabda
LP
682const sd_bus_vtable link_vtable[] = {
683 SD_BUS_VTABLE_START(0),
684
685 SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
686 SD_BUS_PROPERTY("DNS", "a(iay)", property_get_dns, 0, 0),
b7ac92cd 687 SD_BUS_PROPERTY("CurrentDNSServer", "(iay)", property_get_current_dns_server, offsetof(Link, current_dns_server), 0),
ad44b56b 688 SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0),
77673795 689 SD_BUS_PROPERTY("DefaultRoute", "b", property_get_default_route, 0, 0),
bf4e5c4c
YW
690 SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Link, llmnr_support), 0),
691 SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Link, mdns_support), 0),
c9299be2 692 SD_BUS_PROPERTY("DNSOverTLS", "s", property_get_dns_over_tls_mode, 0, 0),
a3712979 693 SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, 0, 0),
3abaabda 694 SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
c2cf6e0b 695 SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
3abaabda 696
52aaef0f
ZJS
697 SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
698 SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED),
699 SD_BUS_METHOD("SetDefaultRoute", "b", NULL, bus_link_method_set_default_route, SD_BUS_VTABLE_UNPRIVILEGED),
700 SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
701 SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
702 SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
703 SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
704 SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
705 SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
d2ec6608 706
3abaabda
LP
707 SD_BUS_VTABLE_END
708};
709
710int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
711 _cleanup_free_ char *e = NULL;
712 Manager *m = userdata;
713 int ifindex;
714 Link *link;
715 int r;
716
717 assert(bus);
718 assert(path);
719 assert(interface);
720 assert(found);
721 assert(m);
722
723 r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
724 if (r <= 0)
725 return 0;
726
727 r = parse_ifindex(e, &ifindex);
728 if (r < 0)
729 return 0;
730
731 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
732 if (!link)
733 return 0;
734
735 *found = link;
736 return 1;
737}
738
0a6c0745
ZJS
739char *link_bus_path(const Link *link) {
740 char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)];
3abaabda
LP
741 int r;
742
743 assert(link);
744
0a6c0745 745 xsprintf(ifindex, "%i", link->ifindex);
3abaabda
LP
746
747 r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
748 if (r < 0)
749 return NULL;
750
751 return p;
752}
753
754int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
755 _cleanup_strv_free_ char **l = NULL;
756 Manager *m = userdata;
757 Link *link;
758 Iterator i;
759 unsigned c = 0;
760
761 assert(bus);
762 assert(path);
763 assert(m);
764 assert(nodes);
765
766 l = new0(char*, hashmap_size(m->links) + 1);
767 if (!l)
768 return -ENOMEM;
769
770 HASHMAP_FOREACH(link, m->links, i) {
771 char *p;
772
773 p = link_bus_path(link);
774 if (!p)
775 return -ENOMEM;
776
777 l[c++] = p;
778 }
779
780 l[c] = NULL;
ae2a15bc 781 *nodes = TAKE_PTR(l);
3abaabda
LP
782
783 return 1;
784}