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:
Dan Williams
2009-05-11 20:02:07 -04:00
parent fd4bdc5c54
commit b4767a5c1f
4 changed files with 103 additions and 48 deletions

View File

@@ -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);
} }

View File

@@ -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 {
/* If no search domains were specified, add the 'domain' list to /* Add the 'domain' list to searches as well since overloading the
* search domains. * 'domain_name' DHCP field used to be the way you got searches
* 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));
}
} }
@@ -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

View File

@@ -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

View File

@@ -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);