diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in index 77a3852108..9425ef370d 100644 --- a/clients/common/settings-docs.h.in +++ b/clients/common/settings-docs.h.in @@ -220,7 +220,7 @@ #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\".") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") @@ -242,7 +242,7 @@ #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\".") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index a2569fdcb7..30e7a97b99 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -5609,6 +5609,10 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) * "no-ip6-dotint", "no-reload", "no-tld-query", "rotate", "single-request", * "single-request-reopen", "timeout", "trust-ad", "use-vc". * + * The "trust-ad" setting is only honored if the profile contributes + * name servers to resolv.conf, and if all contributing profiles have + * "trust-ad" enabled. + * * Since: 1.2 **/ obj_properties[PROP_DNS_OPTIONS] = diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index b40dd6b656..7686bb4baa 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -62,6 +62,7 @@ typedef struct { GPtrArray *options; const char *nis_domain; GPtrArray *nis_servers; + NMTernary has_trust_ad; } NMResolvConfData; /*****************************************************************************/ @@ -410,8 +411,11 @@ merge_one_ip_config (NMResolvConfData *rc, const NMIPConfig *ip_config) { int addr_family; - guint num, i; char buf[NM_UTILS_INET_ADDRSTRLEN + 50]; + gboolean has_trust_ad; + guint num_nameservers; + guint num; + guint i; addr_family = nm_ip_config_get_addr_family (ip_config); @@ -419,8 +423,8 @@ merge_one_ip_config (NMResolvConfData *rc, nm_assert (ifindex > 0); nm_assert (ifindex == nm_ip_config_get_ifindex (ip_config)); - num = nm_ip_config_get_num_nameservers (ip_config); - for (i = 0; i < num; i++) { + num_nameservers = nm_ip_config_get_num_nameservers (ip_config); + for (i = 0; i < num_nameservers; i++) { const NMIPAddr *addr; addr = nm_ip_config_get_nameserver (ip_config, i); @@ -446,11 +450,28 @@ merge_one_ip_config (NMResolvConfData *rc, add_dns_domains (rc->searches, ip_config, FALSE, TRUE); + has_trust_ad = FALSE; num = nm_ip_config_get_num_dns_options (ip_config); for (i = 0; i < num; i++) { + const char *option = nm_ip_config_get_dns_option (ip_config, i); + + if (nm_streq (option, NM_SETTING_DNS_OPTION_TRUST_AD)) { + has_trust_ad = TRUE; + continue; + } add_dns_option_item (rc->options, nm_ip_config_get_dns_option (ip_config, i)); } + if (num_nameservers == 0) { + /* If the @ip_config contributes no DNS servers, ignore whether trust-ad is set or unset + * for this @ip_config. */ + } else if (has_trust_ad) { + /* We only set has_trust_ad to TRUE, if all IP configs agree (or don't contribute). + * Once set to FALSE, it doesn't get reset. */ + if (rc->has_trust_ad == NM_TERNARY_DEFAULT) + rc->has_trust_ad = NM_TERNARY_TRUE; + } else + rc->has_trust_ad = NM_TERNARY_FALSE; if (addr_family == AF_INET) { const NMIP4Config *ip4_config = (const NMIP4Config *) ip_config; @@ -1106,11 +1127,12 @@ _collect_resolv_conf_data (NMDnsManager *self, { NMDnsManagerPrivate *priv; NMResolvConfData rc = { - .nameservers = g_ptr_array_new (), - .searches = g_ptr_array_new (), - .options = g_ptr_array_new (), - .nis_domain = NULL, - .nis_servers = g_ptr_array_new (), + .nameservers = g_ptr_array_new (), + .searches = g_ptr_array_new (), + .options = g_ptr_array_new (), + .nis_domain = NULL, + .nis_servers = g_ptr_array_new (), + .has_trust_ad = NM_TERNARY_DEFAULT, }; priv = NM_DNS_MANAGER_GET_PRIVATE (self); @@ -1174,6 +1196,9 @@ _collect_resolv_conf_data (NMDnsManager *self, } } + if (rc.has_trust_ad == NM_TERNARY_TRUE) + g_ptr_array_add (rc.options, NM_SETTING_DNS_OPTION_TRUST_AD); + *out_searches = _ptrarray_to_strv (rc.searches); *out_options = _ptrarray_to_strv (rc.options); *out_nameservers = _ptrarray_to_strv (rc.nameservers);