diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-06-15 09:11:28 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-06-15 09:44:19 +0200 |
commit | 827ee1f878bf09d96a6bb1991e1b6b092b826ea2 (patch) | |
tree | 898a4898fb981fdd92f154fd1932ccee2d7a8268 | |
parent | 886fac03264a1b41b5232fa2af0f45bc66110d82 (diff) | |
download | NetworkManager-827ee1f878bf09d96a6bb1991e1b6b092b826ea2.tar.gz |
manager: introduce new SetGlobalDnsConfig D-Bus method
-rw-r--r-- | introspection/nm-manager.xml | 13 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/nm-config-data.c | 156 | ||||
-rw-r--r-- | src/nm-config-data.h | 7 | ||||
-rw-r--r-- | src/nm-config.h | 2 | ||||
-rw-r--r-- | src/nm-manager.c | 30 |
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); |