summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-06-15 09:11:28 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-06-15 09:44:19 +0200
commit827ee1f878bf09d96a6bb1991e1b6b092b826ea2 (patch)
tree898a4898fb981fdd92f154fd1932ccee2d7a8268
parent886fac03264a1b41b5232fa2af0f45bc66110d82 (diff)
downloadNetworkManager-827ee1f878bf09d96a6bb1991e1b6b092b826ea2.tar.gz
manager: introduce new SetGlobalDnsConfig D-Bus method
-rw-r--r--introspection/nm-manager.xml13
-rw-r--r--src/main.c3
-rw-r--r--src/nm-config-data.c156
-rw-r--r--src/nm-config-data.h7
-rw-r--r--src/nm-config.h2
-rw-r--r--src/nm-manager.c30
6 files changed, 208 insertions, 3 deletions
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index d0682e5cac..3620a2df92 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -261,6 +261,19 @@
<arg name="state" type="u" direction="out" tp:type="NM_STATE"/>
</method>
+ <method name="SetGlobalDnsConfig">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_set_global_dns_config"/>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <tp:docstring>
+ Change the global static DNS configuration.
+ </tp:docstring>
+ <arg name="config" type="a{sv}" direction="in">
+ <tp:docstring>
+ The new global DNS configuration.
+ </tp:docstring>
+ </arg>
+ </method>
+
<property name="Devices" type="ao" access="read">
<tp:docstring>
The list of network devices/interfaces NetworkManager knows about.
diff --git a/src/main.c b/src/main.c
index bc800cefda..3fab6b70e5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -272,6 +272,7 @@ main (int argc, char *argv[])
gboolean wrote_pidfile = FALSE;
char *bad_domains = NULL;
NMConfigCmdLineOptions *config_cli;
+ char *atomic_section_prefixes[] = { "global-dns", NULL };
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
@@ -343,7 +344,7 @@ main (int argc, char *argv[])
}
/* Read the config file and CLI overrides */
- config = nm_config_setup (config_cli, NULL, &error);
+ config = nm_config_setup (config_cli, atomic_section_prefixes, &error);
nm_config_cmd_line_options_free (config_cli);
config_cli = NULL;
if (config == NULL) {
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 3f76e1ba8d..1992e2e718 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -31,6 +31,9 @@
#include "nm-macros-internal.h"
#include "nm-logging.h"
+#define GLOBAL_DNS_GROUP "global-dns"
+#define GLOBAL_DNS_DOMAIN_PREFIX "global-dns-domain-"
+
typedef struct {
char *group_name;
gboolean stop_match;
@@ -363,8 +366,22 @@ strv_to_slist (char **strv)
return g_slist_reverse (list);
}
-#define GLOBAL_DNS_GROUP "global-dns"
-#define GLOBAL_DNS_DOMAIN_PREFIX "global-dns-domain-"
+static char **
+slist_to_strv (GSList *slist)
+{
+ GSList *iter;
+ char **strv;
+ int len, i;
+
+ len = g_slist_length (slist);
+ strv = g_new (char *, len + 1);
+
+ for (i = 0, iter = slist; iter; iter = iter->next, i++)
+ strv[i] = g_strdup (iter->data);
+ strv[i] = NULL;
+
+ return strv;
+}
static GlobalDnsConf *
load_global_dns_config (GKeyFile *keyfile)
@@ -444,6 +461,141 @@ load_global_dns_config (GKeyFile *keyfile)
return conf;
}
+GKeyFile *
+nm_config_data_global_dns_config_update_keyfile (NMConfigData *self, GlobalDnsConf *dns_conf)
+{
+ GKeyFile *keyfile;
+ GHashTableIter iter;
+ char **groups;
+ int g;
+ gpointer key, value;
+ char **values;
+
+ g_return_val_if_fail (NM_IS_CONFIG_DATA (self), NULL);
+ g_return_val_if_fail (dns_conf, NULL);
+
+ keyfile = nm_config_data_clone_keyfile_intern (self);
+
+ values = slist_to_strv (dns_conf->searches);
+ g_key_file_set_string_list (keyfile, GLOBAL_DNS_GROUP, "searches",
+ (const char *const *) values, g_strv_length (values));
+ g_strfreev (values);
+
+ values = slist_to_strv (dns_conf->options);
+ g_key_file_set_string_list (keyfile, GLOBAL_DNS_GROUP, "options",
+ (const char *const *) values, g_strv_length (values));
+ g_strfreev (values);
+
+ groups = nm_config_data_get_groups (self);
+ for (g = 0; groups[g]; g++) {
+ if (g_str_has_prefix (groups[g], GLOBAL_DNS_DOMAIN_PREFIX)) {
+ /* Override domains from user config and clear ones from internal config */
+ g_key_file_remove_group (keyfile, groups[g], NULL);
+ g_key_file_set_string (keyfile, groups[g], NM_CONFIG_KEYFILE_KEYPREFIX_WAS, "");
+ }
+ }
+ g_strfreev (groups);
+
+ g = 0;
+ g_hash_table_iter_init (&iter, dns_conf->domains);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ char group_name[32];
+ GlobalDnsDomainConf *domain_conf = (GlobalDnsDomainConf *) value;
+
+ snprintf (group_name, sizeof (group_name), GLOBAL_DNS_DOMAIN_PREFIX "%u", (unsigned int) g++);
+ g_key_file_set_string (keyfile, group_name, "domain", (char *) key);
+
+ if (domain_conf->servers) {
+ values = slist_to_strv (domain_conf->servers);
+ g_key_file_set_string_list (keyfile, group_name, "servers",
+ (const char *const *) values, g_strv_length (values));
+ g_strfreev (values);
+ }
+
+ if (domain_conf->options) {
+ values = slist_to_strv (domain_conf->options);
+ g_key_file_set_string_list (keyfile, group_name, "options",
+ (const char *const *) values, g_strv_length (values));
+ g_strfreev (values);
+ }
+ }
+
+ return keyfile;
+}
+
+static GlobalDnsDomainConf *
+build_dns_global_domain_from_hash (const char *name, GHashTable *hash)
+{
+ GlobalDnsDomainConf *domain;
+ char **strv, **ptr;
+
+ domain = g_malloc0 (sizeof (GlobalDnsDomainConf));
+
+ strv = g_hash_table_lookup (hash, "servers");
+ if (strv) {
+ for (ptr = strv; *ptr; ptr++)
+ domain->servers = g_slist_prepend (domain->servers, *ptr);
+ domain->servers = g_slist_reverse (domain->servers);
+ }
+
+ strv = g_hash_table_lookup (hash, "options");
+ if (strv) {
+ for (ptr = strv; *ptr; ptr++)
+ domain->options = g_slist_prepend (domain->options, *ptr);
+ domain->options = g_slist_reverse (domain->options);
+ }
+
+ return domain;
+}
+
+GlobalDnsConf *
+nm_config_data_global_dns_config_from_dbus (const NMConfigData *self,
+ GHashTable *hash,
+ GError **error)
+{
+ GlobalDnsConf *conf;
+ GValue *val;
+ char **strv, **ptr;
+
+ conf = g_malloc0 (sizeof (GlobalDnsConf));
+
+ conf->domains = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, free_global_dns_domain);
+
+ val = g_hash_table_lookup (hash, "searches");
+ if (val) {
+ strv = (char **) g_value_get_boxed (val);
+ for (ptr = strv; *ptr; ptr++)
+ conf->searches = g_slist_prepend (conf->searches, *ptr);
+ conf->searches = g_slist_reverse (conf->searches);
+ }
+
+ val = g_hash_table_lookup (hash, "options");
+ if (val) {
+ strv = (char **) g_value_get_boxed (val);
+ for (ptr = strv; *ptr; ptr++)
+ conf->options = g_slist_prepend (conf->options, *ptr);
+ conf->options = g_slist_reverse (conf->options);
+ }
+
+ val = g_hash_table_lookup (hash, "domains");
+ if (val) {
+ GHashTable *table = (GHashTable *) g_value_get_boxed (val);
+ GHashTableIter iter;
+ gpointer key, value;
+ GlobalDnsDomainConf *domain;
+
+ g_hash_table_iter_init (&iter, table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ domain = build_dns_global_domain_from_hash ((char *)key, (GHashTable *) value);
+ if (domain)
+ g_hash_table_insert (conf->domains, g_strdup ((char *) key), domain);
+ }
+ }
+
+ return conf;
+}
+
/************************************************************************/
static GKeyFile *
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index 2f9b4f4c32..4bdfb8b910 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -125,6 +125,13 @@ gboolean nm_config_data_is_atomic_group (const NMConfigData *self, const char *g
GKeyFile *nm_config_data_clone_keyfile_intern (const NMConfigData *self);
+GlobalDnsConf *nm_config_data_global_dns_config_from_dbus (const NMConfigData *self,
+ GHashTable *hash,
+ GError **error);
+
+GKeyFile *nm_config_data_global_dns_config_update_keyfile (NMConfigData *self,
+ GlobalDnsConf *dns_conf);
+
/* private accessors */
GKeyFile *_nm_config_data_get_keyfile (const NMConfigData *self);
GKeyFile *_nm_config_data_get_keyfile_user (const NMConfigData *self);
diff --git a/src/nm-config.h b/src/nm-config.h
index b4f106c091..581eb21c8d 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -133,6 +133,8 @@ gint nm_config_keyfile_get_boolean (GKeyFile *keyfile,
gint default_value);
GSList *nm_config_get_device_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key);
+gboolean nm_config_write_global_dns_config (NMConfig *config, GlobalDnsConf *dns_conf);
+
G_END_DECLS
#endif /* __NETWORKMANAGER_CONFIG_H__ */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index bf9e69a368..02aacc9ea3 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -111,6 +111,10 @@ static void impl_manager_get_logging (NMManager *manager,
static void impl_manager_check_connectivity (NMManager *manager,
DBusGMethodInvocation *context);
+static void impl_manager_set_global_dns_config (NMManager *manager,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+
#include "nm-manager-glue.h"
static void add_device (NMManager *self, NMDevice *device, gboolean try_assume);
@@ -3945,6 +3949,32 @@ impl_manager_check_connectivity (NMManager *manager,
}
static void
+impl_manager_set_global_dns_config (NMManager *manager,
+ GHashTable *settings,
+ DBusGMethodInvocation *context)
+{
+ GlobalDnsConf *dns_conf;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
+ NMConfigData *data;
+ GError *error = NULL;
+ GKeyFile *keyfile;
+
+ // FIXME: check permissions
+ data = nm_config_get_data (priv->config);
+ dns_conf = nm_config_data_global_dns_config_from_dbus (data, settings, &error);
+ keyfile = nm_config_data_global_dns_config_update_keyfile (data, dns_conf);
+
+ nm_config_data_set_global_dns_config (data, dns_conf);
+ nm_config_set_values (priv->config, keyfile, TRUE, FALSE);
+
+ if (error) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ } else
+ dbus_g_method_return (context);
+}
+
+static void
start_factory (NMDeviceFactory *factory, gpointer user_data)
{
nm_device_factory_start (factory);