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