-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-message-util.h"
#include "bus-polkit.h"
#include "dns-domain.h"
+#include "format-util.h"
#include "memory-util.h"
#include "missing_capability.h"
#include "resolved-bus.h"
* thus quickly know that we cannot resolve an in-addr.arpa or ip6.arpa address. */
return sd_bus_reply_method_errorf(q->bus_request, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", dns_query_string(q));
+ case DNS_TRANSACTION_NO_SOURCE:
+ return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_NO_SOURCE, "All suitable resolution sources turned off");
+
+ case DNS_TRANSACTION_STUB_LOOP:
+ return sd_bus_reply_method_errorf(q->bus_request, BUS_ERROR_STUB_LOOP, "Configured DNS server loops back to us");
+
case DNS_TRANSACTION_RCODE_FAILURE: {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
goto finish;
}
- r = dns_query_process_cname(q);
+ r = dns_query_process_cname_many(q);
if (r == -ELOOP) {
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));
goto finish;
}
if (r < 0)
goto finish;
- if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+ if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
return;
r = sd_bus_message_new_method_return(q->bus_request, &reply);
r = sd_bus_message_append(
reply, "st",
normalized,
- SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
+ dns_query_reply_flags_make(q));
if (r < 0)
goto finish;
*
* 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive
*
- * 2. Only the protocols flags and the NO_CNAME flag are set, at most. Plus additional flags specific
- * to our method, passed in the "ok" parameter.
+ * 2. Only the protocols flags and a bunch of NO_XYZ flags are set, at most. Plus additional flags
+ * specific to our method, passed in the "ok" parameter.
*
* 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way
* clients can simply pass 0 as flags and all will work as it should. They can also use this so
* to mean "all supported protocols".
*/
- if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
+ if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|
+ SD_RESOLVED_NO_CNAME|
+ SD_RESOLVED_NO_VALIDATE|
+ SD_RESOLVED_NO_SYNTHESIZE|
+ SD_RESOLVED_NO_CACHE|
+ SD_RESOLVED_NO_ZONE|
+ SD_RESOLVED_NO_TRUST_ANCHOR|
+ SD_RESOLVED_NO_NETWORK|
+ ok))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
return r;
r = sd_bus_message_append(reply, "st", canonical,
- SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true));
+ SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true, true) |
+ SD_RESOLVED_SYNTHETIC);
if (r < 0)
return r;
return sd_bus_send(sd_bus_message_get_bus(m), reply, NULL);
}
+void bus_client_log(sd_bus_message *m, const char *what) {
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ const char *comm = NULL;
+ uid_t uid = UID_INVALID;
+ pid_t pid = 0;
+ int r;
+
+ assert(m);
+ assert(what);
+
+ if (!DEBUG_LOGGING)
+ return;
+
+ r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
+ if (r < 0)
+ return (void) log_debug_errno(r, "Failed to query client credentials, ignoring: %m");
+
+ (void) sd_bus_creds_get_uid(creds, &uid);
+ (void) sd_bus_creds_get_pid(creds, &pid);
+ (void) sd_bus_creds_get_comm(creds, &comm);
+
+ log_debug("D-Bus %s request from client PID " PID_FMT " (%s) with UID " UID_FMT,
+ what, pid, strna(comm), uid);
+}
+
static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL;
Manager *m = userdata;
if (r < 0 && r != -EALREADY)
return r;
- r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, ifindex, flags);
+ bus_client_log(message, "hostname resolution");
+
+ r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, NULL, ifindex, flags);
if (r < 0)
return r;
goto finish;
}
- r = dns_query_process_cname(q);
+ r = dns_query_process_cname_many(q);
if (r == -ELOOP) {
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));
goto finish;
}
if (r < 0)
goto finish;
- if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+ if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
return;
r = sd_bus_message_new_method_return(q->bus_request, &reply);
if (r < 0)
goto finish;
- r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
+ r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q));
if (r < 0)
goto finish;
if (r < 0)
return r;
- r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
+ bus_client_log(message, "address resolution");
+
+ r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
if (r < 0)
return r;
goto finish;
}
- r = dns_query_process_cname(q);
+ r = dns_query_process_cname_many(q);
if (r == -ELOOP) {
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));
goto finish;
}
if (r < 0)
goto finish;
- if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+ if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
return;
r = sd_bus_message_new_method_return(q->bus_request, &reply);
if (r < 0)
goto finish;
- r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
+ r = sd_bus_message_append(reply, "t", dns_query_reply_flags_make(q));
if (r < 0)
goto finish;
if (r < 0)
return r;
- r = dns_query_new(m, &q, question, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
+ bus_client_log(message, "resource record resolution");
+
+ /* Setting SD_RESOLVED_CLAMP_TTL: let's request that the TTL is fixed up for locally cached entries,
+ * after all we return it in the wire format blob. */
+ r = dns_query_new(m, &q, question, question, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH|SD_RESOLVED_CLAMP_TTL);
if (r < 0)
return r;
- /* Let's request that the TTL is fixed up for locally cached entries, after all we return it in the wire format
- * blob */
- q->clamp_ttl = true;
-
q->bus_request = sd_bus_message_ref(message);
q->complete = bus_method_resolve_record_complete;
reply,
"ssst",
name, type, domain,
- SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q)));
+ dns_query_reply_flags_make(q));
if (r < 0)
goto finish;
return;
}
- r = dns_query_process_cname(q);
- if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+ r = dns_query_process_cname_many(q);
+ if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
return;
/* This auxiliary lookup is finished or failed, let's see if all are finished now. */
if (r < 0)
return r;
- r = dns_query_new(q->manager, &aux, question, question, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
+ r = dns_query_new(q->manager, &aux, question, question, NULL, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
if (r < 0)
return r;
goto finish;
}
- r = dns_query_process_cname(q);
+ r = dns_query_process_cname_many(q);
if (r == -ELOOP) {
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));
goto finish;
}
if (r < 0)
goto finish;
- if (r == DNS_QUERY_RESTARTED) /* This was a cname, and the query was restarted. */
+ if (r == DNS_QUERY_CNAME) /* This was a cname, and the query was restarted. */
return;
question = dns_query_question_for_protocol(q, q->answer_protocol);
if (r < 0)
return r;
- r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags|SD_RESOLVED_NO_SEARCH);
+ bus_client_log(message, "service resolution");
+
+ r = dns_query_new(m, &q, question_utf8, question_idna, NULL, ifindex, flags|SD_RESOLVED_NO_SEARCH);
if (r < 0)
return r;
assert(message);
assert(m);
+ bus_client_log(message, "statistics reset");
+
LIST_FOREACH(scopes, s, m->dns_scopes)
s->cache.n_hit = s->cache.n_miss = 0;
assert(message);
assert(m);
- manager_flush_caches(m);
+ bus_client_log(message, "cache flush");
+
+ manager_flush_caches(m, LOG_INFO);
return sd_bus_reply_method_return(message, NULL);
}
assert(message);
assert(m);
+ bus_client_log(message, "server feature reset");
+
manager_reset_server_features(m);
return sd_bus_reply_method_return(message, NULL);
_cleanup_(dnssd_service_freep) DnssdService *service = NULL;
_cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL;
_cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *instance_name = NULL;
Manager *m = userdata;
DnssdService *s = NULL;
const char *name;
if (!dnssd_srv_type_is_valid(type))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type);
- r = dnssd_render_instance_name(name_template, NULL);
- if (r < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service name '%s' is invalid", name_template);
-
service->name = strdup(name);
if (!service->name)
return log_oom();
if (!service->type)
return log_oom();
+ r = dnssd_render_instance_name(service, &instance_name);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "a{say}");
if (r < 0)
return r;
if (r == 0)
return 1; /* Polkit will call us back */
- r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
- if (r < 0)
- return r;
-
- r = hashmap_put(m->dnssd_services, service->name, service);
+ r = hashmap_ensure_put(&m->dnssd_services, &string_hash_ops, service->name, service);
if (r < 0)
return r;