diff --git a/src/gconf-helpers/gconf-helpers.c b/src/gconf-helpers/gconf-helpers.c
index a299ccc..e2be77f 100644
--- a/src/gconf-helpers/gconf-helpers.c
+++ b/src/gconf-helpers/gconf-helpers.c
@@ -443,6 +443,56 @@ out:
 	return success;
 }
 
+gboolean
+nm_gconf_get_ip4_dns_helper (GConfClient *client,
+                                const char *path,
+                                const char *key,
+                                const char *setting,
+                                GArray **value)
+{
+	char *gc_key;
+	GConfValue *gc_value;
+	GArray *array;
+	struct in_addr dns_addr;
+	gboolean success = FALSE;
+
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (setting != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+
+	gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+	if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+		goto out;
+
+	if (gc_value->type == GCONF_VALUE_LIST
+	    && gconf_value_get_list_type (gc_value) == GCONF_VALUE_STRING)
+	{
+		GSList *elt;
+
+		array = g_array_new (FALSE, FALSE, sizeof (gint));
+		for (elt = gconf_value_get_list (gc_value); elt != NULL; elt = g_slist_next (elt))
+		{
+			const char *addr_str = gconf_value_get_string ((GConfValue *) elt->data);
+			if (inet_pton (AF_INET, addr_str, &dns_addr) <= 0) {
+				g_warning ("%s: %s contained bad DNS address: %s",
+						   __func__, gc_key, addr_str);
+				continue;
+			}
+
+			g_array_append_val (array, dns_addr.s_addr);
+		}
+
+		*value = array;
+		success = TRUE;
+	}
+	
+out:
+	if (gc_value)
+		gconf_value_free (gc_value);
+	g_free (gc_key);
+	return success;
+}
+
 #if UNUSED
 static void
 property_value_destroy (gpointer data)
@@ -606,30 +656,62 @@ nm_gconf_get_ip4_helper (GConfClient *client,
 		goto out;
 
 	if (   (gc_value->type != GCONF_VALUE_LIST)
-	    || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_INT))
+	    || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_STRING))
 		goto out;
 
 	values = gconf_value_get_list (gc_value);
-	if (g_slist_length (values) % tuple_len != 0) {
-		g_warning ("%s: %s format invalid; # elements not divisible by %d",
-		           __func__, gc_key, tuple_len);
-		goto out;
-	}
 
 	array = g_ptr_array_sized_new (1);
 	for (iter = values; iter; iter = g_slist_next (iter)) {
-		int i = gconf_value_get_int ((GConfValue *) iter->data);
+		const char *addr_str = gconf_value_get_string ((GConfValue *) iter->data);
+		char **parts, *addr, *p;
+		guint prefix, metric;
+		struct in_addr rawaddr, gateway;
 
-		if (tuple == NULL)
-			tuple = g_array_sized_new (FALSE, TRUE, sizeof (guint32), tuple_len);
+		parts = g_strsplit (addr_str, ",", -1);
+		if (g_strv_length (parts) != tuple_len - 1) {
+			g_warning ("%s: %s contained bad address/route: %s",
+					   __func__, gc_key, addr_str);
+			g_strfreev (parts);
+			continue;
+		}
 
-		g_array_append_val (tuple, i);
+		addr = parts[0];
+		p = strchr (addr, '/');
+		if (!p) {
+			g_warning ("%s: %s contained bad address/prefix: %s",
+					   __func__, gc_key, addr);
+			g_strfreev (parts);
+			continue;
+		}
+		*p++ = '\0';
+		prefix = strtoul (p, NULL, 10);
 
-		/* Got all members; add to the array */
-		if (tuple->len == tuple_len) {
-			g_ptr_array_add (array, tuple);
-			tuple = NULL;
+		if (inet_pton (AF_INET, addr, &rawaddr) <= 0 && prefix > 32) {
+			g_warning ("%s: %s contained bad address: %s",
+					   __func__, gc_key, addr);
+			g_strfreev (parts);
+			continue;
+		}
+
+		if (inet_pton (AF_INET, parts[1], &gateway) <= 0) {
+			g_warning ("%s: %s contained bad address: %s",
+					   __func__, gc_key, parts[1]);
+			g_strfreev (parts);
+			continue;
 		}
+
+		if (tuple_len == 4)
+			metric = strtoul (parts[2], NULL, 10);
+
+		tuple = g_array_sized_new (FALSE, TRUE, sizeof (guint32), tuple_len);
+
+		g_array_append_val (tuple, rawaddr.s_addr);
+		g_array_append_val (tuple, prefix);
+		g_array_append_val (tuple, gateway.s_addr);
+		if (tuple_len == 4)
+			g_array_append_val (tuple, metric);
+		g_ptr_array_add (array, tuple);
 	}
 
 	*value = array;
@@ -844,7 +926,7 @@ nm_gconf_get_ip6route_array_helper (GConfClient *client,
 
 		if (inet_pton (AF_INET6, parts[1], &rawaddr) <= 0 && prefix > 128) {
 			g_warning ("%s: %s contained bad address: %s",
-					   __func__, gc_key, addr);
+					   __func__, gc_key, parts[1]);
 			g_byte_array_free (dest, TRUE);
 			g_strfreev (parts);
 			continue;
@@ -1118,6 +1200,48 @@ nm_gconf_set_uint_array_helper (GConfClient *client,
 	return TRUE;
 }
 
+gboolean
+nm_gconf_set_ip4_dns_helper (GConfClient *client,
+                             const char *path,
+                             const char *key,
+                             const char *setting,
+                             GArray *value)
+{
+	char *gc_key;
+	int i;
+	GSList *list = NULL, *l;
+	char addr[INET_ADDRSTRLEN];
+
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (setting != NULL, FALSE);
+
+	if (!value)
+		return TRUE;
+
+	gc_key = g_strdup_printf ("%s/%s/%s", path, setting, key);
+	if (!gc_key) {
+		g_warning ("Not enough memory to create gconf path");
+		return FALSE;
+	}
+
+	for (i = 0; i < value->len; i++) {
+		if (!inet_ntop (AF_INET, &g_array_index (value, guint, i), addr, sizeof (addr))) {
+			g_warning ("%s: invalid IPv4 DNS server address!", __func__);
+			continue;
+		}
+		list = g_slist_append (list, g_strdup (addr));
+	}
+
+	gconf_client_set_list (client, gc_key, GCONF_VALUE_STRING, list, NULL);
+
+	for (l = list; l; l = l->next)
+		g_free (l->data);
+	g_slist_free (list);
+	g_free (gc_key);
+	return TRUE;
+}
+
+
 typedef struct {
 	GConfClient *client;
 	char *path;
@@ -1264,7 +1388,10 @@ nm_gconf_set_ip4_helper (GConfClient *client,
 {
 	char *gc_key;
 	int i;
-	GSList *list = NULL;
+	GSList *list = NULL, *l;
+	char addr[INET_ADDRSTRLEN];
+	char gateway[INET_ADDRSTRLEN];
+	guint32 prefix, metric;
 	gboolean success = FALSE;
 
 	g_return_val_if_fail (key != NULL, FALSE);
@@ -1282,21 +1409,38 @@ nm_gconf_set_ip4_helper (GConfClient *client,
 
 	for (i = 0; i < value->len; i++) {
 		GArray *tuple = g_ptr_array_index (value, i);
-		int j;
 
 		if (tuple->len != tuple_len) {
 			g_warning ("%s: invalid IPv4 address/route structure!", __func__);
 			goto out;
 		}
 
-		for (j = 0; j < tuple_len; j++)
-			list = g_slist_append (list, GUINT_TO_POINTER (g_array_index (tuple, guint32, j)));
+		if (!inet_ntop (AF_INET, &g_array_index (tuple, guint32, 0), addr, sizeof (addr))) {
+			g_warning ("%s: invalid IPv4 address!", __func__);
+			continue;
+		}
+
+		prefix = g_array_index (tuple, guint32, 1);
+
+		if (!inet_ntop (AF_INET, &g_array_index (tuple, guint32, 2), gateway, sizeof (gateway))) {
+			g_warning ("%s: invalid IPv4 gateway address!", __func__);
+			continue;
+		}
+		if (tuple_len == 4)
+			metric = g_array_index (tuple, guint32, 3);
+
+		if (tuple_len == 3)
+			list = g_slist_append (list, g_strdup_printf ("%s/%u,%s", addr, prefix, gateway));
+		else if (tuple_len == 4)
+			list = g_slist_append (list, g_strdup_printf ("%s/%u,%s,%u", addr, prefix, gateway, metric));
 	}
 
-	gconf_client_set_list (client, gc_key, GCONF_VALUE_INT, list, NULL);
+	gconf_client_set_list (client, gc_key, GCONF_VALUE_STRING, list, NULL);
 	success = TRUE;
 
 out:
+	for (l = list; l; l = l->next)
+		g_free (l->data);
 	g_slist_free (list);
 	g_free (gc_key);
 	return success;
@@ -1718,9 +1862,16 @@ read_one_setting_value_from_gconf (NMSetting *setting,
 	} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
 		GArray *a_val = NULL;
 
-		if (nm_gconf_get_uint_array_helper (info->client, info->dir, key, setting_name, &a_val)) {
-			g_object_set (setting, key, a_val, NULL);
-			g_array_free (a_val, TRUE);
+		if (!strcmp (key, NM_SETTING_IP4_CONFIG_DNS)) {
+			if (nm_gconf_get_ip4_dns_helper (info->client, info->dir, key, setting_name, &a_val)) {
+				g_object_set (setting, key, a_val, NULL);
+				g_array_free (a_val, TRUE);
+			}
+		} else {
+			if (nm_gconf_get_uint_array_helper (info->client, info->dir, key, setting_name, &a_val)) {
+				g_object_set (setting, key, a_val, NULL);
+				g_array_free (a_val, TRUE);
+			}
 		}
 	} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
 		GPtrArray *pa_val = NULL;
@@ -2411,9 +2562,14 @@ copy_one_setting_value_to_gconf (NMSetting *setting,
 		                                setting_name,
 		                                (GHashTable *) g_value_get_boxed (value));
 	} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
-		nm_gconf_set_uint_array_helper (info->client, info->dir,
-								  key, setting_name,
-								  (GArray *) g_value_get_boxed (value));
+		if (!strcmp (key, NM_SETTING_IP4_CONFIG_DNS))
+			nm_gconf_set_ip4_dns_helper (info->client, info->dir,
+			                                key, setting_name,
+			                                (GArray *) g_value_get_boxed (value));
+		else
+			nm_gconf_set_uint_array_helper (info->client, info->dir,
+			                                key, setting_name,
+			                                (GArray *) g_value_get_boxed (value));
 	} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
 		guint32 tuple_len = 0;
 
diff --git a/src/gconf-helpers/gconf-helpers.h b/src/gconf-helpers/gconf-helpers.h
index 17d1ce8..0f746ac 100644
--- a/src/gconf-helpers/gconf-helpers.h
+++ b/src/gconf-helpers/gconf-helpers.h
@@ -93,6 +93,12 @@ nm_gconf_get_uint_array_helper (GConfClient *client,
 				const char *setting,
 				GArray **value);
 
+gboolean
+nm_gconf_get_ip4_dns_helper (GConfClient *client,
+                             const char *path,
+                             const char *key,
+                             const char *setting,
+		             GArray **value);
 
 #if UNUSED
 gboolean
@@ -187,6 +193,12 @@ nm_gconf_set_uint_array_helper (GConfClient *client,
 				const char *key,
 				const char *setting,
 				GArray *value);
+gboolean
+nm_gconf_set_ip4_dns_helper (GConfClient *client,
+                             const char *path,
+                             const char *key,
+                             const char *setting,
+                             GArray *value);
 
 #if UNUSED
 gboolean
