dns: fix handling of searches and domains in resolv.conf
Fix a few issues here: - nm_utils_merge_ip4_config() didn't reset domains, which would cause domains to still be used even if the user elected to ignore DHCP-provided DNS - nm_ip4_config_add_domain() and nm_ip4_config_add_search() didn't filter duplicates - nm_ip4_config_reset_searches() leaked everything - If the user had specified an appended search in the connection, that search would be added to the 'searches' field in resolv.conf, but any server returned domains in 'domain_name' would be ignored because at least one search existed.
This commit is contained in:
@@ -204,6 +204,7 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
|
|||||||
|
|
||||||
if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) {
|
if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) {
|
||||||
nm_ip4_config_reset_nameservers (ip4_config);
|
nm_ip4_config_reset_nameservers (ip4_config);
|
||||||
|
nm_ip4_config_reset_domains (ip4_config);
|
||||||
nm_ip4_config_reset_searches (ip4_config);
|
nm_ip4_config_reset_searches (ip4_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -107,16 +107,15 @@ merge_one_ip4_config (NMIP4Config *dst, NMIP4Config *src)
|
|||||||
nm_ip4_config_add_domain (dst, nm_ip4_config_get_domain (src, i));
|
nm_ip4_config_add_domain (dst, nm_ip4_config_get_domain (src, i));
|
||||||
|
|
||||||
num = nm_ip4_config_get_num_searches (src);
|
num = nm_ip4_config_get_num_searches (src);
|
||||||
if (num > 0) {
|
for (i = 0; i < num; i++)
|
||||||
for (i = 0; i < num; i++)
|
nm_ip4_config_add_search (dst, nm_ip4_config_get_search (src, i));
|
||||||
nm_ip4_config_add_search (dst, nm_ip4_config_get_search (src, i));
|
|
||||||
} else {
|
/* Add the 'domain' list to searches as well since overloading the
|
||||||
/* If no search domains were specified, add the 'domain' list to
|
* 'domain_name' DHCP field used to be the way you got searches
|
||||||
* search domains.
|
* into resolv.conf.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < num_domains; i++)
|
for (i = 0; i < num_domains; i++)
|
||||||
nm_ip4_config_add_search (dst, nm_ip4_config_get_domain (src, i));
|
nm_ip4_config_add_search (dst, nm_ip4_config_get_domain (src, i));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,10 +168,10 @@ write_to_netconfig (gint fd, const char *key, const char *value)
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
dispatch_netconfig (const char *domain,
|
dispatch_netconfig (const char *domain,
|
||||||
char **searches,
|
char **searches,
|
||||||
char **nameservers,
|
char **nameservers,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gint fd;
|
gint fd;
|
||||||
char *str;
|
char *str;
|
||||||
@@ -213,9 +212,9 @@ dispatch_netconfig (const char *domain,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
write_resolv_conf (FILE *f, const char *domain,
|
write_resolv_conf (FILE *f, const char *domain,
|
||||||
char **searches,
|
char **searches,
|
||||||
char **nameservers,
|
char **nameservers,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
char *domain_str = NULL;
|
char *domain_str = NULL;
|
||||||
char *searches_str = NULL;
|
char *searches_str = NULL;
|
||||||
@@ -283,10 +282,10 @@ write_resolv_conf (FILE *f, const char *domain,
|
|||||||
#ifdef RESOLVCONF_PATH
|
#ifdef RESOLVCONF_PATH
|
||||||
static gboolean
|
static gboolean
|
||||||
dispatch_resolvconf (const char *domain,
|
dispatch_resolvconf (const char *domain,
|
||||||
char **searches,
|
char **searches,
|
||||||
char **nameservers,
|
char **nameservers,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
char *cmd;
|
char *cmd;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -324,10 +323,10 @@ dispatch_resolvconf (const char *domain,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
update_resolv_conf (const char *domain,
|
update_resolv_conf (const char *domain,
|
||||||
char **searches,
|
char **searches,
|
||||||
char **nameservers,
|
char **nameservers,
|
||||||
const char *iface,
|
const char *iface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
|
const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
|
||||||
char tmp_resolv_conf_realpath [PATH_MAX];
|
char tmp_resolv_conf_realpath [PATH_MAX];
|
||||||
@@ -381,6 +380,35 @@ update_resolv_conf (const char *domain,
|
|||||||
return *error ? FALSE : TRUE;
|
return *error ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
compute_searches (guint32 num, NMIP4Config *config, gboolean searches)
|
||||||
|
{
|
||||||
|
GPtrArray *array;
|
||||||
|
size_t len, elem_len;
|
||||||
|
const char *elem;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Search list is limited to 6 domains total per 'man resolv.conf' */
|
||||||
|
if (num > 6)
|
||||||
|
num = 6;
|
||||||
|
|
||||||
|
array = g_ptr_array_sized_new (num + 1);
|
||||||
|
for (i = 0, len = 0; i < num; i++) {
|
||||||
|
elem = searches ? nm_ip4_config_get_search (config, i)
|
||||||
|
: nm_ip4_config_get_domain (config, i);
|
||||||
|
elem_len = strlen (elem);
|
||||||
|
|
||||||
|
/* The search list is limited to 256 characters per 'man resolv.conf' */
|
||||||
|
if (len + elem_len > 255)
|
||||||
|
break;
|
||||||
|
|
||||||
|
g_ptr_array_add (array, g_strdup (elem));
|
||||||
|
len += elem_len + 1; /* +1 for spaces */
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (array, NULL);
|
||||||
|
return (char **) g_ptr_array_free (array, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
||||||
@@ -433,21 +461,10 @@ rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
|||||||
domain = nm_ip4_config_get_domain (composite, 0);
|
domain = nm_ip4_config_get_domain (composite, 0);
|
||||||
|
|
||||||
/* Searches */
|
/* Searches */
|
||||||
if (num_searches > 0) {
|
if (num_searches > 0)
|
||||||
array = g_ptr_array_sized_new (num_searches + 1);
|
searches = compute_searches (num_searches, composite, TRUE);
|
||||||
for (i = 0; i < num_searches; i++)
|
else if (num_domains > 0)
|
||||||
g_ptr_array_add (array, g_strdup (nm_ip4_config_get_search (composite, i)));
|
searches = compute_searches (num_searches, composite, FALSE);
|
||||||
|
|
||||||
g_ptr_array_add (array, NULL);
|
|
||||||
searches = (char **) g_ptr_array_free (array, FALSE);
|
|
||||||
} else if (num_domains > 0) {
|
|
||||||
array = g_ptr_array_sized_new (num_domains + 1);
|
|
||||||
for (i = 0; i < num_domains; i++)
|
|
||||||
g_ptr_array_add (array, g_strdup (nm_ip4_config_get_domain (composite, i)));
|
|
||||||
|
|
||||||
g_ptr_array_add (array, NULL);
|
|
||||||
searches = (char **) g_ptr_array_free (array, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Name servers */
|
/* Name servers */
|
||||||
num_nameservers = nm_ip4_config_get_num_nameservers (composite);
|
num_nameservers = nm_ip4_config_get_num_nameservers (composite);
|
||||||
@@ -473,6 +490,8 @@ rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
|||||||
nameservers = (char **) g_ptr_array_free (array, FALSE);
|
nameservers = (char **) g_ptr_array_free (array, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_unref (composite);
|
||||||
|
|
||||||
#ifdef RESOLVCONF_PATH
|
#ifdef RESOLVCONF_PATH
|
||||||
success = dispatch_resolvconf (domain, searches, nameservers, iface, error);
|
success = dispatch_resolvconf (domain, searches, nameservers, iface, error);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -352,14 +352,21 @@ void nm_ip4_config_reset_routes (NMIP4Config *config)
|
|||||||
|
|
||||||
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain)
|
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain)
|
||||||
{
|
{
|
||||||
|
NMIP4ConfigPrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
||||||
g_return_if_fail (domain != NULL);
|
g_return_if_fail (domain != NULL);
|
||||||
g_return_if_fail (strlen (domain) > 0);
|
g_return_if_fail (strlen (domain) > 0);
|
||||||
|
|
||||||
if (!strlen (domain))
|
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
return;
|
|
||||||
|
|
||||||
g_ptr_array_add (NM_IP4_CONFIG_GET_PRIVATE (config)->domains, g_strdup (domain));
|
for (i = 0; i < priv->domains->len; i++) {
|
||||||
|
if (!strcmp (g_ptr_array_index (priv->domains, i), domain))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (priv->domains, g_strdup (domain));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *nm_ip4_config_get_domain (NMIP4Config *config, guint i)
|
const char *nm_ip4_config_get_domain (NMIP4Config *config, guint i)
|
||||||
@@ -376,13 +383,37 @@ guint32 nm_ip4_config_get_num_domains (NMIP4Config *config)
|
|||||||
return NM_IP4_CONFIG_GET_PRIVATE (config)->domains->len;
|
return NM_IP4_CONFIG_GET_PRIVATE (config)->domains->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nm_ip4_config_reset_domains (NMIP4Config *config)
|
||||||
|
{
|
||||||
|
NMIP4ConfigPrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
||||||
|
|
||||||
|
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
|
for (i = 0; i < priv->domains->len; i++)
|
||||||
|
g_free (g_ptr_array_index (priv->domains, i));
|
||||||
|
g_ptr_array_free (priv->domains, TRUE);
|
||||||
|
priv->domains = g_ptr_array_sized_new (3);
|
||||||
|
}
|
||||||
|
|
||||||
void nm_ip4_config_add_search (NMIP4Config *config, const char *search)
|
void nm_ip4_config_add_search (NMIP4Config *config, const char *search)
|
||||||
{
|
{
|
||||||
|
NMIP4ConfigPrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (config != NULL);
|
g_return_if_fail (config != NULL);
|
||||||
g_return_if_fail (search != NULL);
|
g_return_if_fail (search != NULL);
|
||||||
g_return_if_fail (strlen (search) > 0);
|
g_return_if_fail (strlen (search) > 0);
|
||||||
|
|
||||||
g_ptr_array_add (NM_IP4_CONFIG_GET_PRIVATE (config)->searches, g_strdup (search));
|
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->searches->len; i++) {
|
||||||
|
if (!strcmp (g_ptr_array_index (priv->searches, i), search))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (priv->searches, g_strdup (search));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *nm_ip4_config_get_search (NMIP4Config *config, guint i)
|
const char *nm_ip4_config_get_search (NMIP4Config *config, guint i)
|
||||||
@@ -402,12 +433,15 @@ guint32 nm_ip4_config_get_num_searches (NMIP4Config *config)
|
|||||||
void nm_ip4_config_reset_searches (NMIP4Config *config)
|
void nm_ip4_config_reset_searches (NMIP4Config *config)
|
||||||
{
|
{
|
||||||
NMIP4ConfigPrivate *priv;
|
NMIP4ConfigPrivate *priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
||||||
|
|
||||||
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
if (priv->searches->len)
|
for (i = 0; i < priv->searches->len; i++)
|
||||||
g_ptr_array_remove_range (priv->searches, 0, priv->searches->len);
|
g_free (g_ptr_array_index (priv->searches, i));
|
||||||
|
g_ptr_array_free (priv->searches, TRUE);
|
||||||
|
priv->searches = g_ptr_array_sized_new (3);
|
||||||
}
|
}
|
||||||
|
|
||||||
guint32 nm_ip4_config_get_mtu (NMIP4Config *config)
|
guint32 nm_ip4_config_get_mtu (NMIP4Config *config)
|
||||||
@@ -696,8 +730,8 @@ nm_ip4_config_init (NMIP4Config *config)
|
|||||||
|
|
||||||
priv->nameservers = g_array_new (FALSE, TRUE, sizeof (guint32));
|
priv->nameservers = g_array_new (FALSE, TRUE, sizeof (guint32));
|
||||||
priv->wins = g_array_new (FALSE, TRUE, sizeof (guint32));
|
priv->wins = g_array_new (FALSE, TRUE, sizeof (guint32));
|
||||||
priv->domains = g_ptr_array_new ();
|
priv->domains = g_ptr_array_sized_new (3);
|
||||||
priv->searches = g_ptr_array_new ();
|
priv->searches = g_ptr_array_sized_new (3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -83,6 +83,7 @@ void nm_ip4_config_reset_routes (NMIP4Config *config);
|
|||||||
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain);
|
void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain);
|
||||||
const char * nm_ip4_config_get_domain (NMIP4Config *config, guint i);
|
const char * nm_ip4_config_get_domain (NMIP4Config *config, guint i);
|
||||||
guint32 nm_ip4_config_get_num_domains (NMIP4Config *config);
|
guint32 nm_ip4_config_get_num_domains (NMIP4Config *config);
|
||||||
|
void nm_ip4_config_reset_domains (NMIP4Config *config);
|
||||||
|
|
||||||
void nm_ip4_config_add_search (NMIP4Config *config, const char *search);
|
void nm_ip4_config_add_search (NMIP4Config *config, const char *search);
|
||||||
const char * nm_ip4_config_get_search (NMIP4Config *config, guint i);
|
const char * nm_ip4_config_get_search (NMIP4Config *config, guint i);
|
||||||
|
Reference in New Issue
Block a user