]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-bus.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / resolve / resolved-bus.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "bus-common-errors.h"
5 #include "bus-get-properties.h"
6 #include "bus-log-control-api.h"
7 #include "bus-message-util.h"
8 #include "bus-polkit.h"
9 #include "dns-domain.h"
10 #include "memory-util.h"
11 #include "missing_capability.h"
12 #include "resolved-bus.h"
13 #include "resolved-def.h"
14 #include "resolved-dns-synthesize.h"
15 #include "resolved-dnssd-bus.h"
16 #include "resolved-dnssd.h"
17 #include "resolved-link-bus.h"
18 #include "resolved-resolv-conf.h"
19 #include "socket-netlink.h"
20 #include "stdio-util.h"
21 #include "strv.h"
22 #include "syslog-util.h"
23 #include "user-util.h"
24 #include "utf8.h"
25
26 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_resolve_support, resolve_support, ResolveSupport);
27
28 static int query_on_bus_track(sd_bus_track *t, void *userdata) {
29 DnsQuery *q = userdata;
30
31 assert(t);
32 assert(q);
33
34 if (!DNS_TRANSACTION_IS_LIVE(q->state))
35 return 0;
36
37 log_debug("Client of active query vanished, aborting query.");
38 dns_query_complete(q, DNS_TRANSACTION_ABORTED);
39 return 0;
40 }
41
42 static int dns_query_bus_track(DnsQuery *q, sd_bus_message *m) {
43 int r;
44
45 assert(q);
46 assert(m);
47
48 if (!q->bus_track) {
49 r = sd_bus_track_new(sd_bus_message_get_bus(m), &q->bus_track, query_on_bus_track, q);
50 if (r < 0)
51 return r;
52 }
53
54 r = sd_bus_track_add_sender(q->bus_track, m);
55 if (r < 0)
56 return r;
57
58 return 0;
59 }
60
61 static int reply_query_state(DnsQuery *q) {
62
63 assert(q);
64 assert(q->bus_request);
65
66 switch (q->state) {
67
68 case DNS_TRANSACTION_NO_SERVERS:
69 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
70
71 case DNS_TRANSACTION_TIMEOUT:
72 return sd_bus_reply_method_errorf(q->bus_request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
73
74 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
75 return sd_bus_reply_method_errorf(q->bus_request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
76
77 case DNS_TRANSACTION_INVALID_REPLY:
78 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
79
80 case DNS_TRANSACTION_ERRNO:
81 return sd_bus_reply_method_errnof(q->bus_request, q->answer_errno, "Lookup failed due to system error: %m");
82
83 case DNS_TRANSACTION_ABORTED:
84 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_ABORTED, "Query aborted");
85
86 case DNS_TRANSACTION_DNSSEC_FAILED:
87 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s",
88 dnssec_result_to_string(q->answer_dnssec_result));
89
90 case DNS_TRANSACTION_NO_TRUST_ANCHOR:
91 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known");
92
93 case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED:
94 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_RR_TYPE_UNSUPPORTED, "Server does not support requested resource record type");
95
96 case DNS_TRANSACTION_NETWORK_DOWN:
97 return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NETWORK_DOWN, "Network is down");
98
99 case DNS_TRANSACTION_NOT_FOUND:
100 /* We return this as NXDOMAIN. This is only generated when a host doesn't implement LLMNR/TCP, and we
101 * thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
102 return sd_bus_reply_method_errorf(q->bus_request, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
103
104 case DNS_TRANSACTION_RCODE_FAILURE: {
105 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
106
107 if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
108 sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
109 else {
110 const char *rc, *n;
111 char p[DECIMAL_STR_MAX(q->answer_rcode)];
112
113 rc = dns_rcode_to_string(q->answer_rcode);
114 if (!rc) {
115 xsprintf(p, "%i", q->answer_rcode);
116 rc = p;
117 }
118
119 n = strjoina(_BUS_ERROR_DNS, rc);
120 sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", dns_query_string(q), rc);
121 }
122
123 return sd_bus_reply_method_error(q->bus_request, &error);
124 }
125
126 case DNS_TRANSACTION_NULL:
127 case DNS_TRANSACTION_PENDING:
128 case DNS_TRANSACTION_VALIDATING:
129 case DNS_TRANSACTION_SUCCESS:
130 default:
131 assert_not_reached("Impossible state");
132 }
133 }
134
135 static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
136 int r;
137
138 assert(reply);
139 assert(rr);
140
141 r = sd_bus_message_open_container(reply, 'r', "iiay");
142 if (r < 0)
143 return r;
144
145 r = sd_bus_message_append(reply, "i", ifindex);
146 if (r < 0)
147 return r;
148
149 if (rr->key->type == DNS_TYPE_A) {
150 r = sd_bus_message_append(reply, "i", AF_INET);
151 if (r < 0)
152 return r;
153
154 r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
155
156 } else if (rr->key->type == DNS_TYPE_AAAA) {
157 r = sd_bus_message_append(reply, "i", AF_INET6);
158 if (r < 0)
159 return r;
160
161 r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
162 } else
163 return -EAFNOSUPPORT;
164
165 if (r < 0)
166 return r;
167
168 r = sd_bus_message_close_container(reply);
169 if (r < 0)
170 return r;
171
172 return 0;
173 }
174
175 static void bus_method_resolve_hostname_complete(DnsQuery *q) {
176 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
177 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
178 _cleanup_free_ char *normalized = NULL;
179 DnsQuestion *question;
180 DnsResourceRecord *rr;
181 unsigned added = 0;
182 int ifindex, r;
183
184 assert(q);
185
186 if (q->state != DNS_TRANSACTION_SUCCESS) {
187 r = reply_query_state(q);
188 goto finish;
189 }
190
191 r = dns_query_process_cname(q);
192 if (r == -ELOOP) {
193 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
194 goto finish;
195 }
196 if (r < 0)
197 goto finish;
198 if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
199 return;
200
201 r = sd_bus_message_new_method_return(q->bus_request, &reply);
202 if (r < 0)
203 goto finish;
204
205 r = sd_bus_message_open_container(reply, 'a', "(iiay)");
206 if (r < 0)
207 goto finish;
208
209 question = dns_query_question_for_protocol(q, q->answer_protocol);
210
211 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
212
213 r = dns_question_matches_rr(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
214 if (r < 0)
215 goto finish;
216 if (r == 0)
217 continue;
218
219 r = append_address(reply, rr, ifindex);
220 if (r < 0)
221 goto finish;
222
223 if (!canonical)
224 canonical = dns_resource_record_ref(rr);
225
226 added++;
227 }
228
229 if (added <= 0) {
230 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
231 goto finish;
232 }
233
234 r = sd_bus_message_close_container(reply);
235 if (r < 0)
236 goto finish;
237
238 /* The key names are not necessarily normalized, make sure that they are when we return them to our
239 * bus clients. */
240 assert(canonical);
241 r = dns_name_normalize(dns_resource_key_name(canonical->key), 0, &normalized);
242 if (r < 0)
243 goto finish;
244
245 /* Return the precise spelling and uppercasing and CNAME target reported by the server */
246 r = sd_bus_message_append(
247 reply, "st",
248 normalized,
249 SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
250 if (r < 0)
251 goto finish;
252
253 r = sd_bus_send(q->manager->bus, reply, NULL);
254
255 finish:
256 if (r < 0) {
257 log_error_errno(r, "Failed to send hostname reply: %m");
258 sd_bus_reply_method_errno(q->bus_request, r, NULL);
259 }
260
261 dns_query_free(q);
262 }
263
264 static int validate_and_mangle_flags(
265 const char *name,
266 uint64_t *flags,
267 uint64_t ok,
268 sd_bus_error *error) {
269
270 assert(flags);
271
272 /* Checks that the client supplied interface index and flags parameter actually are valid and make
273 * sense in our method call context. Specifically:
274 *
275 * 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive
276 *
277 * 2. Only the protocols flags and the NO_CNAME flag are set, at most. Plus additional flags specific
278 * to our method, passed in the "ok" parameter.
279 *
280 * 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way
281 * clients can simply pass 0 as flags and all will work as it should. They can also use this so
282 * that clients don't have to know all the protocols resolved implements, but can just specify 0
283 * to mean "all supported protocols".
284 */
285
286 if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
287 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
288
289 if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
290 *flags |= SD_RESOLVED_PROTOCOLS_ALL;
291
292 /* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */
293 if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0)
294 *flags |= SD_RESOLVED_NO_SEARCH;
295
296 return 0;
297 }
298
299 static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname, int family, uint64_t flags) {
300 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
301 _cleanup_free_ char *canonical = NULL;
302 union in_addr_union parsed;
303 int r, ff, parsed_ifindex = 0;
304
305 /* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
306 * let's not attempt to look it up. */
307
308 r = in_addr_ifindex_from_string_auto(hostname, &ff, &parsed, &parsed_ifindex);
309 if (r < 0) /* not an address */
310 return 0;
311
312 if (family != AF_UNSPEC && ff != family)
313 return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address is not of the requested family.");
314 if (ifindex > 0 && parsed_ifindex > 0 && parsed_ifindex != ifindex)
315 return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address interface index does not match requested interface.");
316
317 if (parsed_ifindex > 0)
318 ifindex = parsed_ifindex;
319
320 r = sd_bus_message_new_method_return(m, &reply);
321 if (r < 0)
322 return r;
323
324 r = sd_bus_message_open_container(reply, 'a', "(iiay)");
325 if (r < 0)
326 return r;
327
328 r = sd_bus_message_open_container(reply, 'r', "iiay");
329 if (r < 0)
330 return r;
331
332 r = sd_bus_message_append(reply, "ii", ifindex, ff);
333 if (r < 0)
334 return r;
335
336 r = sd_bus_message_append_array(reply, 'y', &parsed, FAMILY_ADDRESS_SIZE(ff));
337 if (r < 0)
338 return r;
339
340 r = sd_bus_message_close_container(reply);
341 if (r < 0)
342 return r;
343
344 r = sd_bus_message_close_container(reply);
345 if (r < 0)
346 return r;
347
348 /* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
349 * look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
350 * omissions are always done the same way). */
351 r = in_addr_ifindex_to_string(ff, &parsed, ifindex, &canonical);
352 if (r < 0)
353 return r;
354
355 r = sd_bus_message_append(reply, "st", canonical,
356 SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true));
357 if (r < 0)
358 return r;
359
360 return sd_bus_send(sd_bus_message_get_bus(m), reply, NULL);
361 }
362
363 static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
364 _cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
365 Manager *m = userdata;
366 const char *hostname;
367 int family, ifindex;
368 uint64_t flags;
369 DnsQuery *q;
370 int r;
371
372 assert(message);
373 assert(m);
374
375 assert_cc(sizeof(int) == sizeof(int32_t));
376
377 r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
378 if (r < 0)
379 return r;
380
381 if (ifindex < 0)
382 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
383
384 if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
385 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
386
387 r = validate_and_mangle_flags(hostname, &flags, SD_RESOLVED_NO_SEARCH, error);
388 if (r < 0)
389 return r;
390
391 r = parse_as_address(message, ifindex, hostname, family, flags);
392 if (r != 0)
393 return r;
394
395 r = dns_name_is_valid(hostname);
396 if (r < 0)
397 return r;
398 if (r == 0)
399 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
400
401 r = dns_question_new_address(&question_utf8, family, hostname, false);
402 if (r < 0)
403 return r;
404
405 r = dns_question_new_address(&question_idna, family, hostname, true);
406 if (r < 0 && r != -EALREADY)
407 return r;
408
409 r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, ifindex, flags);
410 if (r < 0)
411 return r;
412
413 q->bus_request = sd_bus_message_ref(message);
414 q->request_family = family;
415 q->complete = bus_method_resolve_hostname_complete;
416
417 r = dns_query_bus_track(q, message);
418 if (r < 0)
419 goto fail;
420
421 r = dns_query_go(q);
422 if (r < 0)
423 goto fail;
424
425 return 1;
426
427 fail:
428 dns_query_free(q);
429 return r;
430 }
431
432 static void bus_method_resolve_address_complete(DnsQuery *q) {
433 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
434 DnsQuestion *question;
435 DnsResourceRecord *rr;
436 unsigned added = 0;
437 int ifindex, r;
438
439 assert(q);
440
441 if (q->state != DNS_TRANSACTION_SUCCESS) {
442 r = reply_query_state(q);
443 goto finish;
444 }
445
446 r = dns_query_process_cname(q);
447 if (r == -ELOOP) {
448 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
449 goto finish;
450 }
451 if (r < 0)
452 goto finish;
453 if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
454 return;
455
456 r = sd_bus_message_new_method_return(q->bus_request, &reply);
457 if (r < 0)
458 goto finish;
459
460 r = sd_bus_message_open_container(reply, 'a', "(is)");
461 if (r < 0)
462 goto finish;
463
464 question = dns_query_question_for_protocol(q, q->answer_protocol);
465
466 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
467 _cleanup_free_ char *normalized = NULL;
468
469 r = dns_question_matches_rr(question, rr, NULL);
470 if (r < 0)
471 goto finish;
472 if (r == 0)
473 continue;
474
475 r = dns_name_normalize(rr->ptr.name, 0, &normalized);
476 if (r < 0)
477 goto finish;
478
479 r = sd_bus_message_append(reply, "(is)", ifindex, normalized);
480 if (r < 0)
481 goto finish;
482
483 added++;
484 }
485
486 if (added <= 0) {
487 _cleanup_free_ char *ip = NULL;
488
489 (void) in_addr_to_string(q->request_family, &q->request_address, &ip);
490 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR,
491 "Address '%s' does not have any RR of requested type", strnull(ip));
492 goto finish;
493 }
494
495 r = sd_bus_message_close_container(reply);
496 if (r < 0)
497 goto finish;
498
499 r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
500 if (r < 0)
501 goto finish;
502
503 r = sd_bus_send(q->manager->bus, reply, NULL);
504
505 finish:
506 if (r < 0) {
507 log_error_errno(r, "Failed to send address reply: %m");
508 sd_bus_reply_method_errno(q->bus_request, r, NULL);
509 }
510
511 dns_query_free(q);
512 }
513
514 static int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
515 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
516 Manager *m = userdata;
517 union in_addr_union a;
518 int family, ifindex;
519 uint64_t flags;
520 DnsQuery *q;
521 int r;
522
523 assert(message);
524 assert(m);
525
526 assert_cc(sizeof(int) == sizeof(int32_t));
527
528 r = sd_bus_message_read(message, "i", &ifindex);
529 if (r < 0)
530 return r;
531
532 r = bus_message_read_in_addr_auto(message, error, &family, &a);
533 if (r < 0)
534 return r;
535
536 r = sd_bus_message_read(message, "t", &flags);
537 if (r < 0)
538 return r;
539
540 if (ifindex < 0)
541 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
542
543 r = validate_and_mangle_flags(NULL, &flags, 0, error);
544 if (r < 0)
545 return r;
546
547 r = dns_question_new_reverse(&question, family, &a);
548 if (r < 0)
549 return r;
550
551 r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
552 if (r < 0)
553 return r;
554
555 q->bus_request = sd_bus_message_ref(message);
556 q->request_family = family;
557 q->request_address = a;
558 q->complete = bus_method_resolve_address_complete;
559
560 r = dns_query_bus_track(q, message);
561 if (r < 0)
562 goto fail;
563
564 r = dns_query_go(q);
565 if (r < 0)
566 goto fail;
567
568 return 1;
569
570 fail:
571 dns_query_free(q);
572 return r;
573 }
574
575 static int bus_message_append_rr(sd_bus_message *m, DnsResourceRecord *rr, int ifindex) {
576 int r;
577
578 assert(m);
579 assert(rr);
580
581 r = sd_bus_message_open_container(m, 'r', "iqqay");
582 if (r < 0)
583 return r;
584
585 r = sd_bus_message_append(m, "iqq",
586 ifindex,
587 rr->key->class,
588 rr->key->type);
589 if (r < 0)
590 return r;
591
592 r = dns_resource_record_to_wire_format(rr, false);
593 if (r < 0)
594 return r;
595
596 r = sd_bus_message_append_array(m, 'y', rr->wire_format, rr->wire_format_size);
597 if (r < 0)
598 return r;
599
600 return sd_bus_message_close_container(m);
601 }
602
603 static void bus_method_resolve_record_complete(DnsQuery *q) {
604 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
605 DnsResourceRecord *rr;
606 DnsQuestion *question;
607 unsigned added = 0;
608 int ifindex;
609 int r;
610
611 assert(q);
612
613 if (q->state != DNS_TRANSACTION_SUCCESS) {
614 r = reply_query_state(q);
615 goto finish;
616 }
617
618 r = dns_query_process_cname(q);
619 if (r == -ELOOP) {
620 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
621 goto finish;
622 }
623 if (r < 0)
624 goto finish;
625 if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
626 return;
627
628 r = sd_bus_message_new_method_return(q->bus_request, &reply);
629 if (r < 0)
630 goto finish;
631
632 r = sd_bus_message_open_container(reply, 'a', "(iqqay)");
633 if (r < 0)
634 goto finish;
635
636 question = dns_query_question_for_protocol(q, q->answer_protocol);
637
638 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
639 r = dns_question_matches_rr(question, rr, NULL);
640 if (r < 0)
641 goto finish;
642 if (r == 0)
643 continue;
644
645 r = bus_message_append_rr(reply, rr, ifindex);
646 if (r < 0)
647 goto finish;
648
649 added++;
650 }
651
652 if (added <= 0) {
653 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", dns_query_string(q));
654 goto finish;
655 }
656
657 r = sd_bus_message_close_container(reply);
658 if (r < 0)
659 goto finish;
660
661 r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
662 if (r < 0)
663 goto finish;
664
665 r = sd_bus_send(q->manager->bus, reply, NULL);
666
667 finish:
668 if (r < 0) {
669 log_error_errno(r, "Failed to send record reply: %m");
670 sd_bus_reply_method_errno(q->bus_request, r, NULL);
671 }
672
673 dns_query_free(q);
674 }
675
676 static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
677 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
678 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
679 Manager *m = userdata;
680 uint16_t class, type;
681 const char *name;
682 int r, ifindex;
683 uint64_t flags;
684 DnsQuery *q;
685
686 assert(message);
687 assert(m);
688
689 assert_cc(sizeof(int) == sizeof(int32_t));
690
691 r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
692 if (r < 0)
693 return r;
694
695 if (ifindex < 0)
696 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
697
698 r = dns_name_is_valid(name);
699 if (r < 0)
700 return r;
701 if (r == 0)
702 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
703
704 if (!dns_type_is_valid_query(type))
705 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified resource record type %" PRIu16 " may not be used in a query.", type);
706 if (dns_type_is_zone_transer(type))
707 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Zone transfers not permitted via this programming interface.");
708 if (dns_type_is_obsolete(type))
709 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
710
711 r = validate_and_mangle_flags(name, &flags, 0, error);
712 if (r < 0)
713 return r;
714
715 question = dns_question_new(1);
716 if (!question)
717 return -ENOMEM;
718
719 key = dns_resource_key_new(class, type, name);
720 if (!key)
721 return -ENOMEM;
722
723 r = dns_question_add(question, key);
724 if (r < 0)
725 return r;
726
727 r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
728 if (r < 0)
729 return r;
730
731 /* Let's request that the TTL is fixed up for locally cached entries, after all we return it in the wire format
732 * blob */
733 q->clamp_ttl = true;
734
735 q->bus_request = sd_bus_message_ref(message);
736 q->complete = bus_method_resolve_record_complete;
737
738 r = dns_query_bus_track(q, message);
739 if (r < 0)
740 goto fail;
741
742 r = dns_query_go(q);
743 if (r < 0)
744 goto fail;
745
746 return 1;
747
748 fail:
749 dns_query_free(q);
750 return r;
751 }
752
753 static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
754 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
755 _cleanup_free_ char *normalized = NULL;
756 DnsQuery *aux;
757 int r;
758
759 assert(q);
760 assert(reply);
761 assert(rr);
762 assert(rr->key);
763
764 if (rr->key->type != DNS_TYPE_SRV)
765 return 0;
766
767 if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
768 /* First, let's see if we could find an appropriate A or AAAA
769 * record for the SRV record */
770 LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
771 DnsResourceRecord *zz;
772 DnsQuestion *question;
773
774 if (aux->state != DNS_TRANSACTION_SUCCESS)
775 continue;
776 if (aux->auxiliary_result != 0)
777 continue;
778
779 question = dns_query_question_for_protocol(aux, aux->answer_protocol);
780
781 r = dns_name_equal(dns_question_first_name(question), rr->srv.name);
782 if (r < 0)
783 return r;
784 if (r == 0)
785 continue;
786
787 DNS_ANSWER_FOREACH(zz, aux->answer) {
788
789 r = dns_question_matches_rr(question, zz, NULL);
790 if (r < 0)
791 return r;
792 if (r == 0)
793 continue;
794
795 canonical = dns_resource_record_ref(zz);
796 break;
797 }
798
799 if (canonical)
800 break;
801 }
802
803 /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
804 if (!canonical)
805 return 0;
806 }
807
808 r = sd_bus_message_open_container(reply, 'r', "qqqsa(iiay)s");
809 if (r < 0)
810 return r;
811
812 r = dns_name_normalize(rr->srv.name, 0, &normalized);
813 if (r < 0)
814 return r;
815
816 r = sd_bus_message_append(
817 reply,
818 "qqqs",
819 rr->srv.priority, rr->srv.weight, rr->srv.port, normalized);
820 if (r < 0)
821 return r;
822
823 r = sd_bus_message_open_container(reply, 'a', "(iiay)");
824 if (r < 0)
825 return r;
826
827 if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
828 LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
829 DnsResourceRecord *zz;
830 DnsQuestion *question;
831 int ifindex;
832
833 if (aux->state != DNS_TRANSACTION_SUCCESS)
834 continue;
835 if (aux->auxiliary_result != 0)
836 continue;
837
838 question = dns_query_question_for_protocol(aux, aux->answer_protocol);
839
840 r = dns_name_equal(dns_question_first_name(question), rr->srv.name);
841 if (r < 0)
842 return r;
843 if (r == 0)
844 continue;
845
846 DNS_ANSWER_FOREACH_IFINDEX(zz, ifindex, aux->answer) {
847
848 r = dns_question_matches_rr(question, zz, NULL);
849 if (r < 0)
850 return r;
851 if (r == 0)
852 continue;
853
854 r = append_address(reply, zz, ifindex);
855 if (r < 0)
856 return r;
857 }
858 }
859 }
860
861 r = sd_bus_message_close_container(reply);
862 if (r < 0)
863 return r;
864
865 if (canonical) {
866 normalized = mfree(normalized);
867
868 r = dns_name_normalize(dns_resource_key_name(canonical->key), 0, &normalized);
869 if (r < 0)
870 return r;
871 }
872
873 /* Note that above we appended the hostname as encoded in the
874 * SRV, and here the canonical hostname this maps to. */
875 r = sd_bus_message_append(reply, "s", normalized);
876 if (r < 0)
877 return r;
878
879 r = sd_bus_message_close_container(reply);
880 if (r < 0)
881 return r;
882
883 return 1;
884 }
885
886 static int append_txt(sd_bus_message *reply, DnsResourceRecord *rr) {
887 DnsTxtItem *i;
888 int r;
889
890 assert(reply);
891 assert(rr);
892 assert(rr->key);
893
894 if (rr->key->type != DNS_TYPE_TXT)
895 return 0;
896
897 LIST_FOREACH(items, i, rr->txt.items) {
898
899 if (i->length <= 0)
900 continue;
901
902 r = sd_bus_message_append_array(reply, 'y', i->data, i->length);
903 if (r < 0)
904 return r;
905 }
906
907 return 1;
908 }
909
910 static void resolve_service_all_complete(DnsQuery *q) {
911 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
912 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
913 _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
914 DnsQuestion *question;
915 DnsResourceRecord *rr;
916 unsigned added = 0;
917 DnsQuery *aux;
918 int r;
919
920 assert(q);
921
922 if (q->block_all_complete > 0)
923 return;
924
925 if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
926 DnsQuery *bad = NULL;
927 bool have_success = false;
928
929 LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
930
931 switch (aux->state) {
932
933 case DNS_TRANSACTION_PENDING:
934 /* If an auxiliary query is still pending, let's wait */
935 return;
936
937 case DNS_TRANSACTION_SUCCESS:
938 if (aux->auxiliary_result == 0)
939 have_success = true;
940 else
941 bad = aux;
942 break;
943
944 default:
945 bad = aux;
946 break;
947 }
948 }
949
950 if (!have_success) {
951 /* We can only return one error, hence pick the last error we encountered */
952
953 assert(bad);
954
955 if (bad->state == DNS_TRANSACTION_SUCCESS) {
956 assert(bad->auxiliary_result != 0);
957
958 if (bad->auxiliary_result == -ELOOP) {
959 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(bad));
960 goto finish;
961 }
962
963 r = bad->auxiliary_result;
964 goto finish;
965 }
966
967 r = reply_query_state(bad);
968 goto finish;
969 }
970 }
971
972 r = sd_bus_message_new_method_return(q->bus_request, &reply);
973 if (r < 0)
974 goto finish;
975
976 r = sd_bus_message_open_container(reply, 'a', "(qqqsa(iiay)s)");
977 if (r < 0)
978 goto finish;
979
980 question = dns_query_question_for_protocol(q, q->answer_protocol);
981
982 DNS_ANSWER_FOREACH(rr, q->answer) {
983 r = dns_question_matches_rr(question, rr, NULL);
984 if (r < 0)
985 goto finish;
986 if (r == 0)
987 continue;
988
989 r = append_srv(q, reply, rr);
990 if (r < 0)
991 goto finish;
992 if (r == 0) /* not an SRV record */
993 continue;
994
995 if (!canonical)
996 canonical = dns_resource_record_ref(rr);
997
998 added++;
999 }
1000
1001 if (added <= 0) {
1002 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
1003 goto finish;
1004 }
1005
1006 r = sd_bus_message_close_container(reply);
1007 if (r < 0)
1008 goto finish;
1009
1010 r = sd_bus_message_open_container(reply, 'a', "ay");
1011 if (r < 0)
1012 goto finish;
1013
1014 DNS_ANSWER_FOREACH(rr, q->answer) {
1015 r = dns_question_matches_rr(question, rr, NULL);
1016 if (r < 0)
1017 goto finish;
1018 if (r == 0)
1019 continue;
1020
1021 r = append_txt(reply, rr);
1022 if (r < 0)
1023 goto finish;
1024 }
1025
1026 r = sd_bus_message_close_container(reply);
1027 if (r < 0)
1028 goto finish;
1029
1030 assert(canonical);
1031 r = dns_service_split(dns_resource_key_name(canonical->key), &name, &type, &domain);
1032 if (r < 0)
1033 goto finish;
1034
1035 r = sd_bus_message_append(
1036 reply,
1037 "ssst",
1038 name, type, domain,
1039 SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
1040 if (r < 0)
1041 goto finish;
1042
1043 r = sd_bus_send(q->manager->bus, reply, NULL);
1044
1045 finish:
1046 if (r < 0) {
1047 log_error_errno(r, "Failed to send service reply: %m");
1048 sd_bus_reply_method_errno(q->bus_request, r, NULL);
1049 }
1050
1051 dns_query_free(q);
1052 }
1053
1054 static void resolve_service_hostname_complete(DnsQuery *q) {
1055 int r;
1056
1057 assert(q);
1058 assert(q->auxiliary_for);
1059
1060 if (q->state != DNS_TRANSACTION_SUCCESS) {
1061 resolve_service_all_complete(q->auxiliary_for);
1062 return;
1063 }
1064
1065 r = dns_query_process_cname(q);
1066 if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
1067 return;
1068
1069 /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
1070 q->auxiliary_result = r;
1071 resolve_service_all_complete(q->auxiliary_for);
1072 }
1073
1074 static int resolve_service_hostname(DnsQuery *q, DnsResourceRecord *rr, int ifindex) {
1075 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1076 DnsQuery *aux;
1077 int r;
1078
1079 assert(q);
1080 assert(rr);
1081 assert(rr->key);
1082 assert(rr->key->type == DNS_TYPE_SRV);
1083
1084 /* OK, we found an SRV record for the service. Let's resolve
1085 * the hostname included in it */
1086
1087 r = dns_question_new_address(&question, q->request_family, rr->srv.name, false);
1088 if (r < 0)
1089 return r;
1090
1091 r = dns_query_new(q->manager, &aux, question, question, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
1092 if (r < 0)
1093 return r;
1094
1095 aux->request_family = q->request_family;
1096 aux->complete = resolve_service_hostname_complete;
1097
1098 r = dns_query_make_auxiliary(aux, q);
1099 if (r == -EAGAIN) {
1100 /* Too many auxiliary lookups? If so, don't complain,
1101 * let's just not add this one, we already have more
1102 * than enough */
1103
1104 dns_query_free(aux);
1105 return 0;
1106 }
1107 if (r < 0)
1108 goto fail;
1109
1110 /* Note that auxiliary queries do not track the original bus
1111 * client, only the primary request does that. */
1112
1113 r = dns_query_go(aux);
1114 if (r < 0)
1115 goto fail;
1116
1117 return 1;
1118
1119 fail:
1120 dns_query_free(aux);
1121 return r;
1122 }
1123
1124 static void bus_method_resolve_service_complete(DnsQuery *q) {
1125 bool has_root_domain = false;
1126 DnsResourceRecord *rr;
1127 DnsQuestion *question;
1128 unsigned found = 0;
1129 int ifindex, r;
1130
1131 assert(q);
1132
1133 if (q->state != DNS_TRANSACTION_SUCCESS) {
1134 r = reply_query_state(q);
1135 goto finish;
1136 }
1137
1138 r = dns_query_process_cname(q);
1139 if (r == -ELOOP) {
1140 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_query_string(q));
1141 goto finish;
1142 }
1143 if (r < 0)
1144 goto finish;
1145 if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
1146 return;
1147
1148 question = dns_query_question_for_protocol(q, q->answer_protocol);
1149
1150 DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
1151 r = dns_question_matches_rr(question, rr, NULL);
1152 if (r < 0)
1153 goto finish;
1154 if (r == 0)
1155 continue;
1156
1157 if (rr->key->type != DNS_TYPE_SRV)
1158 continue;
1159
1160 if (dns_name_is_root(rr->srv.name)) {
1161 has_root_domain = true;
1162 continue;
1163 }
1164
1165 if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
1166 q->block_all_complete++;
1167 r = resolve_service_hostname(q, rr, ifindex);
1168 q->block_all_complete--;
1169
1170 if (r < 0)
1171 goto finish;
1172 }
1173
1174 found++;
1175 }
1176
1177 if (has_root_domain && found <= 0) {
1178 /* If there's exactly one SRV RR and it uses
1179 * the root domain as hostname, then the
1180 * service is explicitly not offered on the
1181 * domain. Report this as a recognizable
1182 * error. See RFC 2782, Section "Usage
1183 * Rules". */
1184 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_query_string(q));
1185 goto finish;
1186 }
1187
1188 if (found <= 0) {
1189 r = sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_query_string(q));
1190 goto finish;
1191 }
1192
1193 /* Maybe we are already finished? check now... */
1194 resolve_service_all_complete(q);
1195 return;
1196
1197 finish:
1198 if (r < 0) {
1199 log_error_errno(r, "Failed to send service reply: %m");
1200 sd_bus_reply_method_errno(q->bus_request, r, NULL);
1201 }
1202
1203 dns_query_free(q);
1204 }
1205
1206 static int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1207 _cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
1208 const char *name, *type, *domain;
1209 Manager *m = userdata;
1210 int family, ifindex;
1211 uint64_t flags;
1212 DnsQuery *q;
1213 int r;
1214
1215 assert(message);
1216 assert(m);
1217
1218 assert_cc(sizeof(int) == sizeof(int32_t));
1219
1220 r = sd_bus_message_read(message, "isssit", &ifindex, &name, &type, &domain, &family, &flags);
1221 if (r < 0)
1222 return r;
1223
1224 if (ifindex < 0)
1225 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
1226
1227 if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
1228 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
1229
1230 if (isempty(name))
1231 name = NULL;
1232 else if (!dns_service_name_is_valid(name))
1233 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service name '%s'", name);
1234
1235 if (isempty(type))
1236 type = NULL;
1237 else if (!dns_srv_type_is_valid(type))
1238 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SRV service type '%s'", type);
1239
1240 r = dns_name_is_valid(domain);
1241 if (r < 0)
1242 return r;
1243 if (r == 0)
1244 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid domain '%s'", domain);
1245
1246 if (name && !type)
1247 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
1248
1249 r = validate_and_mangle_flags(name, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
1250 if (r < 0)
1251 return r;
1252
1253 r = dns_question_new_service(&question_utf8, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), false);
1254 if (r < 0)
1255 return r;
1256
1257 r = dns_question_new_service(&question_idna, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), true);
1258 if (r < 0)
1259 return r;
1260
1261 r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags|SD_RESOLVED_NO_SEARCH);
1262 if (r < 0)
1263 return r;
1264
1265 q->bus_request = sd_bus_message_ref(message);
1266 q->request_family = family;
1267 q->complete = bus_method_resolve_service_complete;
1268
1269 r = dns_query_bus_track(q, message);
1270 if (r < 0)
1271 goto fail;
1272
1273 r = dns_query_go(q);
1274 if (r < 0)
1275 goto fail;
1276
1277 return 1;
1278
1279 fail:
1280 dns_query_free(q);
1281 return r;
1282 }
1283
1284 int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex, bool extended) {
1285 int r;
1286
1287 assert(reply);
1288
1289 if (!s) {
1290 if (with_ifindex) {
1291 if (extended)
1292 return sd_bus_message_append(reply, "(iiayqs)", 0, AF_UNSPEC, 0, 0, NULL);
1293 else
1294 return sd_bus_message_append(reply, "(iiay)", 0, AF_UNSPEC, 0);
1295 } else {
1296 if (extended)
1297 return sd_bus_message_append(reply, "(iayqs)", AF_UNSPEC, 0, 0, NULL);
1298 else
1299 return sd_bus_message_append(reply, "(iay)", AF_UNSPEC, 0);
1300 }
1301 }
1302
1303 r = sd_bus_message_open_container(reply, 'r', with_ifindex ? (extended ? "iiayqs" : "iiay") : (extended ? "iayqs" : "iay"));
1304 if (r < 0)
1305 return r;
1306
1307 if (with_ifindex) {
1308 r = sd_bus_message_append(reply, "i", dns_server_ifindex(s));
1309 if (r < 0)
1310 return r;
1311 }
1312
1313 r = sd_bus_message_append(reply, "i", s->family);
1314 if (r < 0)
1315 return r;
1316
1317 r = sd_bus_message_append_array(reply, 'y', &s->address, FAMILY_ADDRESS_SIZE(s->family));
1318 if (r < 0)
1319 return r;
1320
1321 if (extended) {
1322 r = sd_bus_message_append(reply, "q", s->port);
1323 if (r < 0)
1324 return r;
1325
1326 r = sd_bus_message_append(reply, "s", s->server_name);
1327 if (r < 0)
1328 return r;
1329 }
1330
1331 return sd_bus_message_close_container(reply);
1332 }
1333
1334 static int bus_property_get_dns_servers_internal(
1335 sd_bus *bus,
1336 const char *path,
1337 const char *interface,
1338 const char *property,
1339 sd_bus_message *reply,
1340 void *userdata,
1341 sd_bus_error *error,
1342 bool extended) {
1343
1344 Manager *m = userdata;
1345 DnsServer *s;
1346 Link *l;
1347 int r;
1348
1349 assert(reply);
1350 assert(m);
1351
1352 r = sd_bus_message_open_container(reply, 'a', extended ? "(iiayqs)" : "(iiay)");
1353 if (r < 0)
1354 return r;
1355
1356 LIST_FOREACH(servers, s, m->dns_servers) {
1357 r = bus_dns_server_append(reply, s, true, extended);
1358 if (r < 0)
1359 return r;
1360 }
1361
1362 HASHMAP_FOREACH(l, m->links)
1363 LIST_FOREACH(servers, s, l->dns_servers) {
1364 r = bus_dns_server_append(reply, s, true, extended);
1365 if (r < 0)
1366 return r;
1367 }
1368
1369 return sd_bus_message_close_container(reply);
1370 }
1371
1372 static int bus_property_get_dns_servers(
1373 sd_bus *bus,
1374 const char *path,
1375 const char *interface,
1376 const char *property,
1377 sd_bus_message *reply,
1378 void *userdata,
1379 sd_bus_error *error) {
1380 return bus_property_get_dns_servers_internal(bus, path, interface, property, reply, userdata, error, false);
1381 }
1382
1383 static int bus_property_get_dns_servers_ex(
1384 sd_bus *bus,
1385 const char *path,
1386 const char *interface,
1387 const char *property,
1388 sd_bus_message *reply,
1389 void *userdata,
1390 sd_bus_error *error) {
1391 return bus_property_get_dns_servers_internal(bus, path, interface, property, reply, userdata, error, true);
1392 }
1393
1394 static int bus_property_get_fallback_dns_servers_internal(
1395 sd_bus *bus,
1396 const char *path,
1397 const char *interface,
1398 const char *property,
1399 sd_bus_message *reply,
1400 void *userdata,
1401 sd_bus_error *error,
1402 bool extended) {
1403
1404 DnsServer *s, **f = userdata;
1405 int r;
1406
1407 assert(reply);
1408 assert(f);
1409
1410 r = sd_bus_message_open_container(reply, 'a', extended ? "(iiayqs)" : "(iiay)");
1411 if (r < 0)
1412 return r;
1413
1414 LIST_FOREACH(servers, s, *f) {
1415 r = bus_dns_server_append(reply, s, true, extended);
1416 if (r < 0)
1417 return r;
1418 }
1419
1420 return sd_bus_message_close_container(reply);
1421 }
1422
1423 static int bus_property_get_fallback_dns_servers(
1424 sd_bus *bus,
1425 const char *path,
1426 const char *interface,
1427 const char *property,
1428 sd_bus_message *reply,
1429 void *userdata,
1430 sd_bus_error *error) {
1431 return bus_property_get_fallback_dns_servers_internal(bus, path, interface, property, reply, userdata, error, false);
1432 }
1433
1434 static int bus_property_get_fallback_dns_servers_ex(
1435 sd_bus *bus,
1436 const char *path,
1437 const char *interface,
1438 const char *property,
1439 sd_bus_message *reply,
1440 void *userdata,
1441 sd_bus_error *error) {
1442 return bus_property_get_fallback_dns_servers_internal(bus, path, interface, property, reply, userdata, error, true);
1443 }
1444
1445 static int bus_property_get_current_dns_server_internal(
1446 sd_bus *bus,
1447 const char *path,
1448 const char *interface,
1449 const char *property,
1450 sd_bus_message *reply,
1451 void *userdata,
1452 sd_bus_error *error,
1453 bool extended) {
1454
1455 DnsServer *s;
1456
1457 assert(reply);
1458 assert(userdata);
1459
1460 s = *(DnsServer **) userdata;
1461
1462 return bus_dns_server_append(reply, s, true, extended);
1463 }
1464
1465 static int bus_property_get_current_dns_server(
1466 sd_bus *bus,
1467 const char *path,
1468 const char *interface,
1469 const char *property,
1470 sd_bus_message *reply,
1471 void *userdata,
1472 sd_bus_error *error) {
1473 return bus_property_get_current_dns_server_internal(bus, path, interface, property, reply, userdata, error, false);
1474 }
1475
1476 static int bus_property_get_current_dns_server_ex(
1477 sd_bus *bus,
1478 const char *path,
1479 const char *interface,
1480 const char *property,
1481 sd_bus_message *reply,
1482 void *userdata,
1483 sd_bus_error *error) {
1484 return bus_property_get_current_dns_server_internal(bus, path, interface, property, reply, userdata, error, true);
1485 }
1486
1487 static int bus_property_get_domains(
1488 sd_bus *bus,
1489 const char *path,
1490 const char *interface,
1491 const char *property,
1492 sd_bus_message *reply,
1493 void *userdata,
1494 sd_bus_error *error) {
1495
1496 Manager *m = userdata;
1497 DnsSearchDomain *d;
1498 Link *l;
1499 int r;
1500
1501 assert(reply);
1502 assert(m);
1503
1504 r = sd_bus_message_open_container(reply, 'a', "(isb)");
1505 if (r < 0)
1506 return r;
1507
1508 LIST_FOREACH(domains, d, m->search_domains) {
1509 r = sd_bus_message_append(reply, "(isb)", 0, d->name, d->route_only);
1510 if (r < 0)
1511 return r;
1512 }
1513
1514 HASHMAP_FOREACH(l, m->links) {
1515 LIST_FOREACH(domains, d, l->search_domains) {
1516 r = sd_bus_message_append(reply, "(isb)", l->ifindex, d->name, d->route_only);
1517 if (r < 0)
1518 return r;
1519 }
1520 }
1521
1522 return sd_bus_message_close_container(reply);
1523 }
1524
1525 static int bus_property_get_transaction_statistics(
1526 sd_bus *bus,
1527 const char *path,
1528 const char *interface,
1529 const char *property,
1530 sd_bus_message *reply,
1531 void *userdata,
1532 sd_bus_error *error) {
1533
1534 Manager *m = userdata;
1535
1536 assert(reply);
1537 assert(m);
1538
1539 return sd_bus_message_append(reply, "(tt)",
1540 (uint64_t) hashmap_size(m->dns_transactions),
1541 (uint64_t) m->n_transactions_total);
1542 }
1543
1544 static int bus_property_get_cache_statistics(
1545 sd_bus *bus,
1546 const char *path,
1547 const char *interface,
1548 const char *property,
1549 sd_bus_message *reply,
1550 void *userdata,
1551 sd_bus_error *error) {
1552
1553 uint64_t size = 0, hit = 0, miss = 0;
1554 Manager *m = userdata;
1555 DnsScope *s;
1556
1557 assert(reply);
1558 assert(m);
1559
1560 LIST_FOREACH(scopes, s, m->dns_scopes) {
1561 size += dns_cache_size(&s->cache);
1562 hit += s->cache.n_hit;
1563 miss += s->cache.n_miss;
1564 }
1565
1566 return sd_bus_message_append(reply, "(ttt)", size, hit, miss);
1567 }
1568
1569 static int bus_property_get_dnssec_statistics(
1570 sd_bus *bus,
1571 const char *path,
1572 const char *interface,
1573 const char *property,
1574 sd_bus_message *reply,
1575 void *userdata,
1576 sd_bus_error *error) {
1577
1578 Manager *m = userdata;
1579
1580 assert(reply);
1581 assert(m);
1582
1583 return sd_bus_message_append(reply, "(tttt)",
1584 (uint64_t) m->n_dnssec_verdict[DNSSEC_SECURE],
1585 (uint64_t) m->n_dnssec_verdict[DNSSEC_INSECURE],
1586 (uint64_t) m->n_dnssec_verdict[DNSSEC_BOGUS],
1587 (uint64_t) m->n_dnssec_verdict[DNSSEC_INDETERMINATE]);
1588 }
1589
1590 static int bus_property_get_ntas(
1591 sd_bus *bus,
1592 const char *path,
1593 const char *interface,
1594 const char *property,
1595 sd_bus_message *reply,
1596 void *userdata,
1597 sd_bus_error *error) {
1598
1599 Manager *m = userdata;
1600 const char *domain;
1601 int r;
1602
1603 assert(reply);
1604 assert(m);
1605
1606 r = sd_bus_message_open_container(reply, 'a', "s");
1607 if (r < 0)
1608 return r;
1609
1610 SET_FOREACH(domain, m->trust_anchor.negative_by_name) {
1611 r = sd_bus_message_append(reply, "s", domain);
1612 if (r < 0)
1613 return r;
1614 }
1615
1616 return sd_bus_message_close_container(reply);
1617 }
1618
1619 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode);
1620 static BUS_DEFINE_PROPERTY_GET(bus_property_get_dnssec_supported, "b", Manager, manager_dnssec_supported);
1621 static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dnssec_mode, "s", Manager, manager_get_dnssec_mode, dnssec_mode_to_string);
1622 static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dns_over_tls_mode, "s", Manager, manager_get_dns_over_tls_mode, dns_over_tls_mode_to_string);
1623
1624 static int bus_property_get_resolv_conf_mode(
1625 sd_bus *bus,
1626 const char *path,
1627 const char *interface,
1628 const char *property,
1629 sd_bus_message *reply,
1630 void *userdata,
1631 sd_bus_error *error) {
1632
1633 int r;
1634
1635 assert(reply);
1636
1637 r = resolv_conf_mode();
1638 if (r < 0) {
1639 log_warning_errno(r, "Failed to test /etc/resolv.conf mode, ignoring: %m");
1640 return sd_bus_message_append(reply, "s", NULL);
1641 }
1642
1643 return sd_bus_message_append(reply, "s", resolv_conf_mode_to_string(r));
1644 }
1645
1646 static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1647 Manager *m = userdata;
1648 DnsScope *s;
1649
1650 assert(message);
1651 assert(m);
1652
1653 LIST_FOREACH(scopes, s, m->dns_scopes)
1654 s->cache.n_hit = s->cache.n_miss = 0;
1655
1656 m->n_transactions_total = 0;
1657 zero(m->n_dnssec_verdict);
1658
1659 return sd_bus_reply_method_return(message, NULL);
1660 }
1661
1662 static int get_any_link(Manager *m, int ifindex, Link **ret, sd_bus_error *error) {
1663 Link *l;
1664
1665 assert(m);
1666 assert(ret);
1667
1668 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1669 if (!l)
1670 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex);
1671
1672 *ret = l;
1673 return 0;
1674 }
1675
1676 static int call_link_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) {
1677 int ifindex, r;
1678 Link *l;
1679
1680 assert(m);
1681 assert(message);
1682 assert(handler);
1683
1684 r = bus_message_read_ifindex(message, error, &ifindex);
1685 if (r < 0)
1686 return r;
1687
1688 r = get_any_link(m, ifindex, &l, error);
1689 if (r < 0)
1690 return r;
1691
1692 return handler(message, l, error);
1693 }
1694
1695 static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1696 return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
1697 }
1698
1699 static int bus_method_set_link_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1700 return call_link_method(userdata, message, bus_link_method_set_dns_servers_ex, error);
1701 }
1702
1703 static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1704 return call_link_method(userdata, message, bus_link_method_set_domains, error);
1705 }
1706
1707 static int bus_method_set_link_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1708 return call_link_method(userdata, message, bus_link_method_set_default_route, error);
1709 }
1710
1711 static int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1712 return call_link_method(userdata, message, bus_link_method_set_llmnr, error);
1713 }
1714
1715 static int bus_method_set_link_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1716 return call_link_method(userdata, message, bus_link_method_set_mdns, error);
1717 }
1718
1719 static int bus_method_set_link_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1720 return call_link_method(userdata, message, bus_link_method_set_dns_over_tls, error);
1721 }
1722
1723 static int bus_method_set_link_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1724 return call_link_method(userdata, message, bus_link_method_set_dnssec, error);
1725 }
1726
1727 static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1728 return call_link_method(userdata, message, bus_link_method_set_dnssec_negative_trust_anchors, error);
1729 }
1730
1731 static int bus_method_revert_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1732 return call_link_method(userdata, message, bus_link_method_revert, error);
1733 }
1734
1735 static int bus_method_get_link(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1736 _cleanup_free_ char *p = NULL;
1737 Manager *m = userdata;
1738 int r, ifindex;
1739 Link *l;
1740
1741 assert(message);
1742 assert(m);
1743
1744 r = bus_message_read_ifindex(message, error, &ifindex);
1745 if (r < 0)
1746 return r;
1747
1748 r = get_any_link(m, ifindex, &l, error);
1749 if (r < 0)
1750 return r;
1751
1752 p = link_bus_path(l);
1753 if (!p)
1754 return -ENOMEM;
1755
1756 return sd_bus_reply_method_return(message, "o", p);
1757 }
1758
1759 static int bus_method_flush_caches(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1760 Manager *m = userdata;
1761
1762 assert(message);
1763 assert(m);
1764
1765 manager_flush_caches(m);
1766
1767 return sd_bus_reply_method_return(message, NULL);
1768 }
1769
1770 static int bus_method_reset_server_features(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1771 Manager *m = userdata;
1772
1773 assert(message);
1774 assert(m);
1775
1776 manager_reset_server_features(m);
1777
1778 return sd_bus_reply_method_return(message, NULL);
1779 }
1780
1781 static int dnssd_service_on_bus_track(sd_bus_track *t, void *userdata) {
1782 DnssdService *s = userdata;
1783
1784 assert(t);
1785 assert(s);
1786
1787 log_debug("Client of active request vanished, destroying DNS-SD service.");
1788 dnssd_service_free(s);
1789
1790 return 0;
1791 }
1792
1793 static int bus_method_register_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1794 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1795 _cleanup_(dnssd_service_freep) DnssdService *service = NULL;
1796 _cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL;
1797 _cleanup_free_ char *path = NULL;
1798 Manager *m = userdata;
1799 DnssdService *s = NULL;
1800 const char *name;
1801 const char *name_template;
1802 const char *type;
1803 uid_t euid;
1804 int r;
1805
1806 assert(message);
1807 assert(m);
1808
1809 if (m->mdns_support != RESOLVE_SUPPORT_YES)
1810 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled");
1811
1812 service = new0(DnssdService, 1);
1813 if (!service)
1814 return log_oom();
1815
1816 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
1817 if (r < 0)
1818 return r;
1819
1820 r = sd_bus_creds_get_euid(creds, &euid);
1821 if (r < 0)
1822 return r;
1823 service->originator = euid;
1824
1825 r = sd_bus_message_read(message, "sssqqq", &name, &name_template, &type,
1826 &service->port, &service->priority,
1827 &service->weight);
1828 if (r < 0)
1829 return r;
1830
1831 s = hashmap_get(m->dnssd_services, name);
1832 if (s)
1833 return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", name);
1834
1835 if (!dnssd_srv_type_is_valid(type))
1836 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type);
1837
1838 r = dnssd_render_instance_name(name_template, NULL);
1839 if (r < 0)
1840 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service name '%s' is invalid", name_template);
1841
1842 service->name = strdup(name);
1843 if (!service->name)
1844 return log_oom();
1845
1846 service->name_template = strdup(name_template);
1847 if (!service->name_template)
1848 return log_oom();
1849
1850 service->type = strdup(type);
1851 if (!service->type)
1852 return log_oom();
1853
1854 r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "a{say}");
1855 if (r < 0)
1856 return r;
1857
1858 while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{say}")) > 0) {
1859 _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
1860 DnsTxtItem *last = NULL;
1861
1862 txt_data = new0(DnssdTxtData, 1);
1863 if (!txt_data)
1864 return log_oom();
1865
1866 while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "say")) > 0) {
1867 const char *key;
1868 const void *value;
1869 size_t size;
1870 DnsTxtItem *i;
1871
1872 r = sd_bus_message_read(message, "s", &key);
1873 if (r < 0)
1874 return r;
1875
1876 if (isempty(key))
1877 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Keys in DNS-SD TXT RRs can't be empty");
1878
1879 if (!ascii_is_valid(key))
1880 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TXT key '%s' contains non-ASCII symbols", key);
1881
1882 r = sd_bus_message_read_array(message, 'y', &value, &size);
1883 if (r < 0)
1884 return r;
1885
1886 r = dnssd_txt_item_new_from_data(key, value, size, &i);
1887 if (r < 0)
1888 return r;
1889
1890 LIST_INSERT_AFTER(items, txt_data->txt, last, i);
1891 last = i;
1892
1893 r = sd_bus_message_exit_container(message);
1894 if (r < 0)
1895 return r;
1896
1897 }
1898 if (r < 0)
1899 return r;
1900
1901 r = sd_bus_message_exit_container(message);
1902 if (r < 0)
1903 return r;
1904
1905 if (txt_data->txt) {
1906 LIST_PREPEND(items, service->txt_data_items, txt_data);
1907 txt_data = NULL;
1908 }
1909 }
1910 if (r < 0)
1911 return r;
1912
1913 r = sd_bus_message_exit_container(message);
1914 if (r < 0)
1915 return r;
1916
1917 if (!service->txt_data_items) {
1918 _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
1919
1920 txt_data = new0(DnssdTxtData, 1);
1921 if (!txt_data)
1922 return log_oom();
1923
1924 r = dns_txt_item_new_empty(&txt_data->txt);
1925 if (r < 0)
1926 return r;
1927
1928 LIST_PREPEND(items, service->txt_data_items, txt_data);
1929 txt_data = NULL;
1930 }
1931
1932 r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &path);
1933 if (r < 0)
1934 return r;
1935
1936 r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
1937 "org.freedesktop.resolve1.register-service",
1938 NULL, false, UID_INVALID,
1939 &m->polkit_registry, error);
1940 if (r < 0)
1941 return r;
1942 if (r == 0)
1943 return 1; /* Polkit will call us back */
1944
1945 r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
1946 if (r < 0)
1947 return r;
1948
1949 r = hashmap_put(m->dnssd_services, service->name, service);
1950 if (r < 0)
1951 return r;
1952
1953 r = sd_bus_track_new(sd_bus_message_get_bus(message), &bus_track, dnssd_service_on_bus_track, service);
1954 if (r < 0)
1955 return r;
1956
1957 r = sd_bus_track_add_sender(bus_track, message);
1958 if (r < 0)
1959 return r;
1960
1961 service->manager = m;
1962
1963 service = NULL;
1964
1965 manager_refresh_rrs(m);
1966
1967 return sd_bus_reply_method_return(message, "o", path);
1968 }
1969
1970 static int call_dnssd_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) {
1971 _cleanup_free_ char *name = NULL;
1972 DnssdService *s = NULL;
1973 const char *path;
1974 int r;
1975
1976 assert(m);
1977 assert(message);
1978 assert(handler);
1979
1980 r = sd_bus_message_read(message, "o", &path);
1981 if (r < 0)
1982 return r;
1983
1984 r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/dnssd", &name);
1985 if (r == 0)
1986 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DNSSD_SERVICE, "DNS-SD service with object path '%s' does not exist", path);
1987 if (r < 0)
1988 return r;
1989
1990 s = hashmap_get(m->dnssd_services, name);
1991 if (!s)
1992 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DNSSD_SERVICE, "DNS-SD service '%s' not known", name);
1993
1994 return handler(message, s, error);
1995 }
1996
1997 static int bus_method_unregister_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1998 Manager *m = userdata;
1999
2000 assert(message);
2001 assert(m);
2002
2003 return call_dnssd_method(m, message, bus_dnssd_method_unregister, error);
2004 }
2005
2006 static const sd_bus_vtable resolve_vtable[] = {
2007 SD_BUS_VTABLE_START(0),
2008 SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2009 SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Manager, llmnr_support), 0),
2010 SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Manager, mdns_support), 0),
2011 SD_BUS_PROPERTY("DNSOverTLS", "s", bus_property_get_dns_over_tls_mode, 0, 0),
2012 SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2013 SD_BUS_PROPERTY("DNSEx", "a(iiayqs)", bus_property_get_dns_servers_ex, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2014 SD_BUS_PROPERTY("FallbackDNS", "a(iiay)", bus_property_get_fallback_dns_servers, offsetof(Manager, fallback_dns_servers), SD_BUS_VTABLE_PROPERTY_CONST),
2015 SD_BUS_PROPERTY("FallbackDNSEx", "a(iiayqs)", bus_property_get_fallback_dns_servers_ex, offsetof(Manager, fallback_dns_servers), SD_BUS_VTABLE_PROPERTY_CONST),
2016 SD_BUS_PROPERTY("CurrentDNSServer", "(iiay)", bus_property_get_current_dns_server, offsetof(Manager, current_dns_server), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2017 SD_BUS_PROPERTY("CurrentDNSServerEx", "(iiayqs)", bus_property_get_current_dns_server_ex, offsetof(Manager, current_dns_server), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2018 SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains, 0, 0),
2019 SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0),
2020 SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0),
2021 SD_BUS_PROPERTY("DNSSEC", "s", bus_property_get_dnssec_mode, 0, 0),
2022 SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
2023 SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
2024 SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
2025 SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
2026 SD_BUS_PROPERTY("ResolvConfMode", "s", bus_property_get_resolv_conf_mode, 0, 0),
2027
2028 SD_BUS_METHOD_WITH_ARGS("ResolveHostname",
2029 SD_BUS_ARGS("i", ifindex, "s", name, "i", family, "t", flags),
2030 SD_BUS_RESULT("a(iiay)", addresses, "s", canonical, "t", flags),
2031 bus_method_resolve_hostname,
2032 SD_BUS_VTABLE_UNPRIVILEGED),
2033 SD_BUS_METHOD_WITH_ARGS("ResolveAddress",
2034 SD_BUS_ARGS("i", ifindex, "i", family, "ay", address, "t", flags),
2035 SD_BUS_RESULT("a(is)", names, "t", flags),
2036 bus_method_resolve_address,
2037 SD_BUS_VTABLE_UNPRIVILEGED),
2038 SD_BUS_METHOD_WITH_ARGS("ResolveRecord",
2039 SD_BUS_ARGS("i", ifindex, "s", name, "q", class, "q", type, "t", flags),
2040 SD_BUS_RESULT("a(iqqay)", records, "t", flags),
2041 bus_method_resolve_record,
2042 SD_BUS_VTABLE_UNPRIVILEGED),
2043 SD_BUS_METHOD_WITH_ARGS("ResolveService",
2044 SD_BUS_ARGS("i", ifindex,
2045 "s", name,
2046 "s", type,
2047 "s", domain,
2048 "i", family,
2049 "t", flags),
2050 SD_BUS_RESULT("a(qqqsa(iiay)s)", srv_data,
2051 "aay", txt_data,
2052 "s", canonical_name,
2053 "s", canonical_type,
2054 "s", canonical_domain,
2055 "t", flags),
2056 bus_method_resolve_service,
2057 SD_BUS_VTABLE_UNPRIVILEGED),
2058 SD_BUS_METHOD_WITH_ARGS("GetLink",
2059 SD_BUS_ARGS("i", ifindex),
2060 SD_BUS_RESULT("o", path),
2061 bus_method_get_link,
2062 SD_BUS_VTABLE_UNPRIVILEGED),
2063 SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
2064 SD_BUS_ARGS("i", ifindex, "a(iay)", addresses),
2065 SD_BUS_NO_RESULT,
2066 bus_method_set_link_dns_servers,
2067 SD_BUS_VTABLE_UNPRIVILEGED),
2068 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx",
2069 SD_BUS_ARGS("i", ifindex, "a(iayqs)", addresses),
2070 SD_BUS_NO_RESULT,
2071 bus_method_set_link_dns_servers_ex,
2072 SD_BUS_VTABLE_UNPRIVILEGED),
2073 SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
2074 SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
2075 SD_BUS_NO_RESULT,
2076 bus_method_set_link_domains,
2077 SD_BUS_VTABLE_UNPRIVILEGED),
2078 SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
2079 SD_BUS_ARGS("i", ifindex, "b", enable),
2080 SD_BUS_NO_RESULT,
2081 bus_method_set_link_default_route,
2082 SD_BUS_VTABLE_UNPRIVILEGED),
2083 SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
2084 SD_BUS_ARGS("i", ifindex, "s", mode),
2085 SD_BUS_NO_RESULT,
2086 bus_method_set_link_llmnr,
2087 SD_BUS_VTABLE_UNPRIVILEGED),
2088 SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
2089 SD_BUS_ARGS("i", ifindex, "s", mode),
2090 SD_BUS_NO_RESULT,
2091 bus_method_set_link_mdns,
2092 SD_BUS_VTABLE_UNPRIVILEGED),
2093 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
2094 SD_BUS_ARGS("i", ifindex, "s", mode),
2095 SD_BUS_NO_RESULT,
2096 bus_method_set_link_dns_over_tls,
2097 SD_BUS_VTABLE_UNPRIVILEGED),
2098 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
2099 SD_BUS_ARGS("i", ifindex, "s", mode),
2100 SD_BUS_NO_RESULT,
2101 bus_method_set_link_dnssec,
2102 SD_BUS_VTABLE_UNPRIVILEGED),
2103 SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
2104 SD_BUS_ARGS("i", ifindex, "as", names),
2105 SD_BUS_NO_RESULT,
2106 bus_method_set_link_dnssec_negative_trust_anchors,
2107 SD_BUS_VTABLE_UNPRIVILEGED),
2108 SD_BUS_METHOD_WITH_ARGS("RevertLink",
2109 SD_BUS_ARGS("i", ifindex),
2110 SD_BUS_NO_RESULT,
2111 bus_method_revert_link,
2112 SD_BUS_VTABLE_UNPRIVILEGED),
2113 SD_BUS_METHOD_WITH_ARGS("RegisterService",
2114 SD_BUS_ARGS("s", name,
2115 "s", name_template,
2116 "s", type,
2117 "q", service_port,
2118 "q", service_priority,
2119 "q", service_weight,
2120 "aa{say}", txt_datas),
2121 SD_BUS_RESULT("o", service_path),
2122 bus_method_register_service,
2123 SD_BUS_VTABLE_UNPRIVILEGED),
2124 SD_BUS_METHOD_WITH_ARGS("UnregisterService",
2125 SD_BUS_ARGS("o", service_path),
2126 SD_BUS_NO_RESULT,
2127 bus_method_unregister_service,
2128 SD_BUS_VTABLE_UNPRIVILEGED),
2129 SD_BUS_METHOD_WITH_ARGS("ResetStatistics",
2130 SD_BUS_NO_ARGS,
2131 SD_BUS_NO_RESULT,
2132 bus_method_reset_statistics,
2133 SD_BUS_VTABLE_UNPRIVILEGED),
2134 SD_BUS_METHOD_WITH_ARGS("FlushCaches",
2135 SD_BUS_NO_ARGS,
2136 SD_BUS_NO_RESULT,
2137 bus_method_flush_caches,
2138 SD_BUS_VTABLE_UNPRIVILEGED),
2139 SD_BUS_METHOD_WITH_ARGS("ResetServerFeatures",
2140 SD_BUS_NO_ARGS,
2141 SD_BUS_NO_RESULT,
2142 bus_method_reset_server_features,
2143 SD_BUS_VTABLE_UNPRIVILEGED),
2144
2145 SD_BUS_VTABLE_END,
2146 };
2147
2148 const BusObjectImplementation manager_object = {
2149 "/org/freedesktop/resolve1",
2150 "org.freedesktop.resolve1.Manager",
2151 .vtables = BUS_VTABLES(resolve_vtable),
2152 .children = BUS_IMPLEMENTATIONS(&link_object,
2153 &dnssd_object),
2154 };
2155
2156 static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
2157 Manager *m = userdata;
2158 int b, r;
2159
2160 assert(message);
2161 assert(m);
2162
2163 r = sd_bus_message_read(message, "b", &b);
2164 if (r < 0) {
2165 bus_log_parse_error(r);
2166 return 0;
2167 }
2168
2169 if (b)
2170 return 0;
2171
2172 log_debug("Coming back from suspend, verifying all RRs...");
2173
2174 manager_verify_all(m);
2175 return 0;
2176 }
2177
2178 int manager_connect_bus(Manager *m) {
2179 int r;
2180
2181 assert(m);
2182
2183 if (m->bus)
2184 return 0;
2185
2186 r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-resolve");
2187 if (r < 0)
2188 return log_error_errno(r, "Failed to connect to system bus: %m");
2189
2190 r = bus_add_implementation(m->bus, &manager_object, m);
2191 if (r < 0)
2192 return r;
2193
2194 r = bus_log_control_api_register(m->bus);
2195 if (r < 0)
2196 return r;
2197
2198 r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL, NULL);
2199 if (r < 0)
2200 return log_error_errno(r, "Failed to request name: %m");
2201
2202 r = sd_bus_attach_event(m->bus, m->event, 0);
2203 if (r < 0)
2204 return log_error_errno(r, "Failed to attach bus to event loop: %m");
2205
2206 r = sd_bus_match_signal_async(
2207 m->bus,
2208 NULL,
2209 "org.freedesktop.login1",
2210 "/org/freedesktop/login1",
2211 "org.freedesktop.login1.Manager",
2212 "PrepareForSleep",
2213 match_prepare_for_sleep,
2214 NULL,
2215 m);
2216 if (r < 0)
2217 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
2218
2219 return 0;
2220 }
2221
2222 int _manager_send_changed(Manager *manager, const char *property, ...) {
2223 assert(manager);
2224
2225 char **l = strv_from_stdarg_alloca(property);
2226
2227 int r = sd_bus_emit_properties_changed_strv(
2228 manager->bus,
2229 "/org/freedesktop/resolve1",
2230 "org.freedesktop.resolve1.Manager",
2231 l);
2232 if (r < 0)
2233 log_notice_errno(r, "Failed to emit notification about changed property %s: %m", property);
2234 return r;
2235 }