diff --git a/src/config/Makefile.am b/src/config/Makefile.am index 20e0ae133..3aa0a3b4f 100644 --- a/src/config/Makefile.am +++ b/src/config/Makefile.am @@ -14,7 +14,8 @@ libnm_config_la_CPPFLAGS = \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/logging \ - -DNMCONFDIR=\"$(nmconfdir)\" + -DNMCONFDIR=\"$(nmconfdir)\" \ + -DNMSTATEDIR=\"$(nmstatedir)\" libnm_config_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ diff --git a/src/config/nm-config.c b/src/config/nm-config.c index 2bc4676f4..2ec1aebea 100644 --- a/src/config/nm-config.c +++ b/src/config/nm-config.c @@ -25,14 +25,19 @@ #include "nm-config.h" #include "nm-logging.h" +#include "nm-utils.h" #include -#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" -#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" +#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" +#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" +#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state" typedef struct { char *path; + char *no_auto_default_file; + GKeyFile *keyfile; + char **plugins; char *dhcp_client; char **dns_plugins; @@ -41,6 +46,7 @@ typedef struct { char *connectivity_uri; gint connectivity_interval; char *connectivity_response; + char **no_auto_default; } NMConfigPrivate; static NMConfig *singleton = NULL; @@ -126,9 +132,101 @@ nm_config_get_connectivity_response (NMConfig *config) return NM_CONFIG_GET_PRIVATE (config)->connectivity_response; } +char * +nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + return g_key_file_get_string (priv->keyfile, group, key, error); +} + +/************************************************************************/ + +static void +merge_no_auto_default_state (NMConfig *config) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GPtrArray *updated; + char **list; + int i, j; + char *data; + + /* If the config already matches everything, we don't need to do anything else. */ + if (priv->no_auto_default && !g_strcmp0 (priv->no_auto_default[0], "*")) + return; + + updated = g_ptr_array_new (); + if (priv->no_auto_default) { + for (i = 0; priv->no_auto_default[i]; i++) + g_ptr_array_add (updated, priv->no_auto_default[i]); + g_free (priv->no_auto_default); + } + + if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) { + list = g_strsplit (data, "\n", -1); + for (i = 0; list[i]; i++) { + if (!*list[i]) + continue; + for (j = 0; j < updated->len; j++) { + if (!strcmp (list[i], updated->pdata[j])) + break; + } + if (j == updated->len) + g_ptr_array_add (updated, list[i]); + } + g_free (list); + g_free (data); + } + + g_ptr_array_add (updated, NULL); + priv->no_auto_default = (char **) g_ptr_array_free (updated, FALSE); +} + +gboolean +nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + return !nm_config_device_spec_match_list (device, (const char **) priv->no_auto_default); +} + +void +nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + char *current; + GString *updated; + GError *error = NULL; + + if (!nm_config_get_ethernet_can_auto_default (config, device)) + return; + + updated = g_string_new (NULL); + if (g_file_get_contents (priv->no_auto_default_file, ¤t, NULL, NULL)) { + g_string_append (updated, current); + g_free (current); + if (updated->str[updated->len - 1] != '\n') + g_string_append_c (updated, '\n'); + } + + g_string_append (updated, nm_config_device_get_hwaddr (device)); + g_string_append_c (updated, '\n'); + + if (!g_file_set_contents (priv->no_auto_default_file, updated->str, updated->len, &error)) { + nm_log_warn (LOGD_SETTINGS, "Could not update no-auto-default.state file: %s", + error->message); + g_error_free (error); + } + + g_string_free (updated, TRUE); + + merge_no_auto_default_state (config); +} + /************************************************************************/ static char *cli_config_path; +static char *cli_no_auto_default_file; static char *cli_plugins; static char *cli_log_level; static char *cli_log_domains; @@ -138,6 +236,7 @@ static char *cli_connectivity_response; static GOptionEntry config_options[] = { { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") }, + { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli_no_auto_default_file, "no-auto-default.state location", NULL }, { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") }, { "log-level", 0, 0, G_OPTION_ARG_STRING, &cli_log_level, N_("Log level: one of [%s]"), "INFO" }, { "log-domains", 0, 0, G_OPTION_ARG_STRING, &cli_log_domains, @@ -216,10 +315,14 @@ read_config (NMConfig *config, const char *path, GError **error) if (!priv->connectivity_response) priv->connectivity_response = g_key_file_get_value (kf, "connectivity", "response", NULL); - success = TRUE; - } + if (!priv->no_auto_default) + priv->no_auto_default = g_key_file_get_string_list (kf, "main", "no-auto-default", NULL, NULL); + + priv->keyfile = kf; + success = TRUE; + } else + g_key_file_free (kf); - g_key_file_free (kf); return success; } @@ -268,8 +371,9 @@ nm_config_new (GError **error) if (!read_config (singleton, cli_config_path, error)) { g_object_unref (singleton); singleton = NULL; + return NULL; } - return singleton; + goto got_config; } /* Even though we prefer NetworkManager.conf, we need to check the @@ -281,7 +385,7 @@ nm_config_new (GError **error) /* Try deprecated nm-system-settings.conf first */ if (read_config (singleton, NM_OLD_SYSTEM_CONF_FILE, &local)) - return singleton; + goto got_config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { fprintf (stderr, "Default config file %s invalid: (%d) %s\n", @@ -293,7 +397,7 @@ nm_config_new (GError **error) /* Try the standard config file location next */ if (read_config (singleton, NM_DEFAULT_SYSTEM_CONF_FILE, &local)) - return singleton; + goto got_config; if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND) == FALSE) { fprintf (stderr, "Default config file %s invalid: (%d) %s\n", @@ -316,6 +420,15 @@ nm_config_new (GError **error) /* ignore error if config file not found */ g_clear_error (&local); + + got_config: + /* Handle no-auto-default state file */ + if (cli_no_auto_default_file) + priv->no_auto_default_file = g_strdup (cli_no_auto_default_file); + else + priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE); + merge_no_auto_default_state (singleton); + return singleton; } @@ -331,6 +444,7 @@ finalize (GObject *gobject) NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject); g_free (priv->path); + g_clear_pointer (&priv->keyfile, g_key_file_unref); g_strfreev (priv->plugins); g_free (priv->dhcp_client); g_strfreev (priv->dns_plugins); diff --git a/src/config/nm-config.h b/src/config/nm-config.h index dbdc2f0ae..e18018d10 100644 --- a/src/config/nm-config.h +++ b/src/config/nm-config.h @@ -25,6 +25,8 @@ #include #include +#include "nm-config-device.h" + G_BEGIN_DECLS #define NM_TYPE_CONFIG (nm_config_get_type ()) @@ -56,6 +58,11 @@ const char *nm_config_get_connectivity_uri (NMConfig *config); const guint nm_config_get_connectivity_interval (NMConfig *config); const char *nm_config_get_connectivity_response (NMConfig *config); +gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device); +void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device); + +char *nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error); + /* for main.c only */ GOptionEntry *nm_config_get_options (void); NMConfig *nm_config_new (GError **error); diff --git a/src/config/tests/Makefile.am b/src/config/tests/Makefile.am index cf91697ef..c99c3848e 100644 --- a/src/config/tests/Makefile.am +++ b/src/config/tests/Makefile.am @@ -1,11 +1,19 @@ if ENABLE_TESTS INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/src/config noinst_PROGRAMS = \ test-config +test_config_SOURCES = \ + nm-test-device.c \ + nm-test-device.h \ + test-config.c + test_config_CPPFLAGS = \ -DSRCDIR=\""$(srcdir)"\" \ $(GLIB_CFLAGS) diff --git a/src/config/tests/NetworkManager.conf b/src/config/tests/NetworkManager.conf index 3261e4063..401ba48a7 100644 --- a/src/config/tests/NetworkManager.conf +++ b/src/config/tests/NetworkManager.conf @@ -1,6 +1,7 @@ [main] dhcp=dhclient plugins=foo,bar,baz +no-auto-default=11:11:11:11:11:11 [logging] level=INFO diff --git a/src/config/tests/nm-test-device.c b/src/config/tests/nm-test-device.c new file mode 100644 index 000000000..b671f2558 --- /dev/null +++ b/src/config/tests/nm-test-device.c @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-test-device.h" +#include "nm-config-device.h" +#include "nm-utils.h" + +static void nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMTestDevice, nm_test_device, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONFIG_DEVICE, nm_test_device_config_device_interface_init)) + +static void +nm_test_device_init (NMTestDevice *self) +{ +} + +static void +finalize (GObject *object) +{ + NMTestDevice *self = NM_TEST_DEVICE (object); + + g_free (self->hwaddr); + g_free (self->hwaddr_bytes); + + G_OBJECT_CLASS (nm_test_device_parent_class)->finalize (object); +} + +static void +nm_test_device_class_init (NMTestDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = finalize; +} + +static gboolean +spec_match_list (NMConfigDevice *device, const GSList *specs) +{ + NMTestDevice *self = NM_TEST_DEVICE (device); + const GSList *iter; + const char *spec; + + for (iter = specs; iter; iter = iter->next) { + spec = iter->data; + if (g_str_has_prefix (spec, "mac:") && !strcmp (spec + 4, self->hwaddr)) + return TRUE; + } + return FALSE; +} + +static const guint8 * +get_hw_address (NMConfigDevice *device, guint *out_len) +{ + NMTestDevice *self = NM_TEST_DEVICE (device); + + if (out_len) + *out_len = ETH_ALEN; + return self->hwaddr_bytes; +} + +static void +nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface) +{ + iface->spec_match_list = spec_match_list; + iface->get_hw_address = get_hw_address; +} + +NMTestDevice * +nm_test_device_new (const char *hwaddr) +{ + NMTestDevice *self = g_object_new (NM_TYPE_TEST_DEVICE, NULL); + + self->hwaddr = g_strdup (hwaddr); + self->hwaddr_bytes = g_malloc (ETH_ALEN); + nm_utils_hwaddr_aton (hwaddr, ARPHRD_ETHER, self->hwaddr_bytes); + + return self; +} diff --git a/src/config/tests/nm-test-device.h b/src/config/tests/nm-test-device.h new file mode 100644 index 000000000..ad63bf5fd --- /dev/null +++ b/src/config/tests/nm-test-device.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef NM_TEST_DEVICE_H +#define NM_TEST_DEVICE_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_TEST_DEVICE (nm_test_device_get_type ()) +#define NM_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEST_DEVICE, NMTestDevice)) +#define NM_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) +#define NM_IS_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_TEST_DEVICE)) +#define NM_IS_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_TEST_DEVICE)) +#define NM_TEST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) + +typedef struct { + GObject parent; + + char *hwaddr; + guint8 *hwaddr_bytes; +} NMTestDevice; + +typedef struct { + GObjectClass parent; +} NMTestDeviceClass; + +GType nm_test_device_get_type (void); + +NMTestDevice *nm_test_device_new (const char *hwaddr); + +G_END_DECLS + +#endif /* NM_DEVICE_H */ diff --git a/src/config/tests/test-config.c b/src/config/tests/test-config.c index e2da79ffd..f8df2709c 100644 --- a/src/config/tests/test-config.c +++ b/src/config/tests/test-config.c @@ -18,9 +18,14 @@ * */ +#include "config.h" + +#include + #include #include +#include "nm-test-device.h" static void setup_config (const char *config_file, ...) @@ -58,6 +63,7 @@ test_config_simple (void) NMConfig *config; GError *error = NULL; const char **plugins; + char *value; setup_config (SRCDIR "/NetworkManager.conf", NULL); config = nm_config_new (&error); @@ -74,6 +80,18 @@ test_config_simple (void) g_assert_cmpstr (plugins[1], ==, "bar"); g_assert_cmpstr (plugins[2], ==, "baz"); + value = nm_config_get_value (config, "extra-section", "extra-key", NULL); + g_assert_cmpstr (value, ==, "some value"); + g_free (value); + + value = nm_config_get_value (config, "extra-section", "no-key", &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_clear_error (&error); + + value = nm_config_get_value (config, "no-section", "no-key", &error); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_clear_error (&error); + g_object_unref (config); } @@ -106,7 +124,7 @@ test_config_override (void) GError *error = NULL; const char **plugins; - setup_config (SRCDIR "/NetworkManager.conf", + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", "--plugins", "alpha,beta,gamma,delta", "--connectivity-interval", "12", NULL); @@ -128,6 +146,67 @@ test_config_override (void) g_object_unref (config); } +static void +test_config_no_auto_default (void) +{ + NMConfig *config; + GError *error = NULL; + int fd, nwrote; + char *state_file; + NMTestDevice *dev1, *dev2, *dev3, *dev4; + + fd = g_file_open_tmp (NULL, &state_file, &error); + g_assert_no_error (error); + + nwrote = write (fd, "22:22:22:22:22:22\n", 18); + g_assert_cmpint (nwrote, ==, 18); + nwrote = write (fd, "44:44:44:44:44:44\n", 18); + g_assert_cmpint (nwrote, ==, 18); + close (fd); + + setup_config (SRCDIR "/NetworkManager.conf", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + dev1 = nm_test_device_new ("11:11:11:11:11:11"); + dev2 = nm_test_device_new ("22:22:22:22:22:22"); + dev3 = nm_test_device_new ("33:33:33:33:33:33"); + dev4 = nm_test_device_new ("44:44:44:44:44:44"); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); + g_assert (nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); + + nm_config_set_ethernet_no_auto_default (config, NM_CONFIG_DEVICE (dev3)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + + g_object_unref (config); + + setup_config (SRCDIR "/NetworkManager.conf", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); + g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); + + g_object_unref (config); + + g_object_unref (dev1); + g_object_unref (dev2); + g_object_unref (dev3); + g_object_unref (dev4); + + unlink (state_file); + g_free (state_file); +} + int main (int argc, char **argv) { @@ -137,6 +216,7 @@ main (int argc, char **argv) g_test_add_func ("/config/simple", test_config_simple); g_test_add_func ("/config/non-existent", test_config_non_existent); g_test_add_func ("/config/parse-error", test_config_parse_error); + g_test_add_func ("/config/no-auto-default", test_config_no_auto_default); /* This one has to come last, because it leaves its values in * nm-config.c's global variables, and there's no way to reset diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 1c3a05b1b..5d01c8444 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -71,8 +70,6 @@ #include "nm-connection-provider.h" #include "nm-config.h" -#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" - /* LINKER CRACKROCK */ #define EXPORT(sym) void * __export_##sym = &sym; @@ -1305,7 +1302,7 @@ impl_settings_save_hostname (NMSettings *self, } static gboolean -have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) +have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; @@ -1313,10 +1310,13 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) NMSettingConnection *s_con; NMSettingWired *s_wired; const GByteArray *setting_mac; + const guint8 *hwaddr; + guint hwaddr_len = 0; gboolean ret = FALSE; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - g_return_val_if_fail (mac != NULL, FALSE); + + hwaddr = nm_device_get_hw_address (device, &hwaddr_len); /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); @@ -1353,8 +1353,8 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* A connection mac-locked to this device */ - if (mac->len == setting_mac->len && - !memcmp (setting_mac->data, mac->data, mac->len)) { + if (hwaddr_len == setting_mac->len && + !memcmp (setting_mac->data, hwaddr, hwaddr_len)) { ret = TRUE; break; } @@ -1368,54 +1368,6 @@ have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device) return ret; } -/* Search through the list of blacklisted MAC addresses in the config file. */ -static gboolean -is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) -{ - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char *config_file; - GKeyFile *config; - char **list, **iter; - gboolean found = FALSE; - int hwaddr_type; - - g_return_val_if_fail (mac != NULL, FALSE); - - config_file = nm_config_get_path (priv->config); - if (!config_file) - return FALSE; - - config = g_key_file_new (); - g_key_file_set_list_separator (config, ','); - if (!g_key_file_load_from_file (config, config_file, G_KEY_FILE_NONE, NULL)) - goto out; - - hwaddr_type = nm_utils_hwaddr_type (mac->len); - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); - for (iter = list; iter && *iter; iter++) { - guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX]; - - if (strcmp (g_strstrip (*iter), "*") == 0) { - found = TRUE; - break; - } - - candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer); - if (candidate && !memcmp (mac->data, candidate, mac->len)) { - found = TRUE; - break; - } - } - - if (list) - g_strfreev (list); - -out: - g_key_file_free (config); - return found; -} - #define DEFAULT_WIRED_TAG "default-wired" static void @@ -1425,29 +1377,10 @@ default_wired_deleted (NMDefaultWiredConnection *wired, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMDevice *device; NMSettingConnection *s_con; - const guint8 *hw_addr_bytes; - char *hw_addr; - const char *config_file; - GKeyFile *config; - char **list, **iter, **updated; - gboolean found = FALSE; - gsize len = 0, i; - char *data; device = nm_default_wired_connection_get_device (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, NULL); - /* If there was no config file specified, there's nothing to do */ - config_file = nm_config_get_path (priv->config); - if (!config_file) - return; - - /* When the default wired connection is removed (either deleted or saved - * to a new persistent connection by a plugin), write the MAC address of - * the wired device to the config file and don't create a new default wired - * connection for that device again. - */ - s_con = nm_connection_get_setting_connection (NM_CONNECTION (wired)); g_assert (s_con); @@ -1457,51 +1390,12 @@ default_wired_deleted (NMDefaultWiredConnection *wired, if (nm_setting_connection_get_read_only (s_con)) return; - hw_addr_bytes = nm_device_get_hw_address (device, NULL); - hw_addr = nm_utils_hwaddr_ntoa (hw_addr_bytes, ARPHRD_ETHER); - - config = g_key_file_new (); - - g_key_file_set_list_separator (config, ','); - g_key_file_load_from_file (config, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL); - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); - for (iter = list; iter && *iter; iter++) { - if ( strcmp (*iter, "*") == 0 - || strcmp (*iter, hw_addr) == 0) { - found = TRUE; - break; - } - } - - /* Add this device's MAC to the list */ - if (!found) { - /* New list; size + 1 for the new element, + 1 again for ending NULL */ - updated = g_malloc0 (sizeof (char*) * (len + 2)); - - /* Copy original list and add new MAC */ - for (i = 0; list && list[i]; i++) - updated[i] = list[i]; - updated[i++] = hw_addr; - updated[i] = NULL; - - g_key_file_set_string_list (config, - "main", CONFIG_KEY_NO_AUTO_DEFAULT, - (const char **) updated, - len + 2); - /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */ - g_free (updated); - - data = g_key_file_to_data (config, &len, NULL); - if (data) { - g_file_set_contents (config_file, data, len, NULL); - g_free (data); - } - } - - g_free (hw_addr); - g_strfreev (list); - g_key_file_free (config); + /* When the default wired connection is removed (either deleted or saved + * to a new persistent connection by a plugin), write the MAC address of + * the wired device to the config file and don't create a new default wired + * connection for that device again. + */ + nm_config_set_ethernet_no_auto_default (priv->config, NM_CONFIG_DEVICE (device)); } static void @@ -1557,9 +1451,6 @@ void nm_settings_device_added (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GByteArray *mac = NULL; - const guint8 *hwaddr; - guint hwaddr_len = 0; NMDefaultWiredConnection *wired; gboolean read_only = TRUE; const char *id; @@ -1572,18 +1463,11 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) * ignore it. */ if ( !nm_device_get_managed (device) - || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG)) + || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG) + || have_connection_for_device (self, device) + || !nm_config_get_ethernet_can_auto_default (priv->config, NM_CONFIG_DEVICE (device))) return; - hwaddr = nm_device_get_hw_address (device, &hwaddr_len); - - mac = g_byte_array_sized_new (hwaddr_len); - g_byte_array_append (mac, hwaddr, hwaddr_len); - - if ( have_connection_for_device (self, mac, device) - || is_mac_auto_wired_blacklisted (self, mac)) - goto ignore; - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) read_only = FALSE; @@ -1591,7 +1475,7 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) wired = nm_default_wired_connection_new (device, defname, read_only); g_free (defname); if (!wired) - goto ignore; + return; id = nm_connection_get_id (NM_CONNECTION (wired)); g_assert (id); @@ -1605,9 +1489,6 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) g_object_unref (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired); - -ignore: - g_byte_array_free (mac, TRUE); } void diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index f37366afe..97b487439 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -223,34 +223,6 @@ destroy_connection_config (GHashTable * conn) g_hash_table_destroy (conn); } -/* Read settings from NetworkManager's config file */ -const char * -ifnet_get_global_setting (const char *group, const char *key) -{ - GError *error = NULL; - GKeyFile *keyfile = g_key_file_new (); - gchar *result = NULL; - const char *conf_file; - - /* Get confing file name from plugin. */ - conf_file = ifnet_plugin_get_conf_file (); - - if (!g_key_file_load_from_file (keyfile, - conf_file, - G_KEY_FILE_NONE, &error)) { - PLUGIN_WARN (IFNET_PLUGIN_NAME, - "loading system config file (%s) caused error: (%d) %s", - conf_file, - error ? error->code : -1, error - && error->message ? error->message : "(unknown)"); - } else { - result = g_key_file_get_string (keyfile, group, key, &error); - } - g_key_file_free (keyfile); - - return result; -} - static void strip_function (GIOChannel * channel, gchar * line) { diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h index 47086c762..005207adf 100644 --- a/src/settings/plugins/ifnet/net_parser.h +++ b/src/settings/plugins/ifnet/net_parser.h @@ -34,7 +34,6 @@ void ifnet_destroy (void); GList *ifnet_get_connection_names (void); const char *ifnet_get_data (const char *conn_name, const char *key); const char *ifnet_get_global_data (const char *key); -const char *ifnet_get_global_setting (const char *group, const char *key); gboolean ifnet_has_network (const char *conn_name); /* Writer functions */ diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index c2e3a376a..ae2307f91 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "net_utils.h" #include "wpa_parser.h" @@ -800,7 +801,7 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) *hostname = NULL; *client_id = NULL; - dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + dhcp_client = nm_config_get_dhcp_client (nm_config_get ()); if (dhcp_client) { if (!strcmp (dhcp_client, "dhclient")) g_file_get_contents (dhclient_conf, &contents, NULL, diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index d0c9ccc72..89e1d42e4 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -119,13 +119,18 @@ write_system_hostname (NMSystemConfigInterface * config, } static gboolean -is_managed_plugin () +is_managed_plugin (void) { - const char *result = NULL; + char *result = NULL; - result = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED); - if (result) - return is_true (result); + result = nm_config_get_value (nm_config_get (), + IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED, + NULL); + if (result) { + gboolean ret = is_true (result); + g_free (result); + return ret; + } return IFNET_MANAGE_WELL_KNOWN_DEFAULT; } @@ -272,9 +277,11 @@ reload_connections (gpointer config) old = g_hash_table_lookup (priv->config_connections, conn_name); if (old && new) { - const char *auto_refresh; + char *auto_refresh; - auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh"); + auto_refresh = nm_config_get_value (nm_config_get (), + IFNET_KEY_FILE_GROUP, "auto_refresh", + NULL); if (auto_refresh && is_true (auto_refresh)) { if (!nm_connection_compare (NM_CONNECTION (old), NM_CONNECTION (new), @@ -296,6 +303,7 @@ reload_connections (gpointer config) commit_cb, NULL); g_object_unref (new); } + g_free (auto_refresh); g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } else if (new) { g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); @@ -568,12 +576,6 @@ sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class) NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } -const char * -ifnet_plugin_get_conf_file (void) -{ - return nm_config_get_path (nm_config_get ()); -} - G_MODULE_EXPORT GObject * nm_system_config_factory (void) { diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h index 27e71eead..6ac0f482f 100644 --- a/src/settings/plugins/ifnet/plugin.h +++ b/src/settings/plugins/ifnet/plugin.h @@ -43,7 +43,5 @@ struct _SCPluginIfnetClass { GObjectClass parent; }; -const char * ifnet_plugin_get_conf_file (void); - GType sc_plugin_ifnet_get_type (void); #endif diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am index 19ee13c86..0bfb5b3da 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.am +++ b/src/settings/plugins/ifnet/tests/Makefile.am @@ -8,6 +8,7 @@ INCLUDES=-I$(srcdir)/../ \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ + -I$(top_srcdir)/src/config \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/src/wifi diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index 4c3126010..3e36b0fa7 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -33,16 +33,22 @@ #include "net_utils.h" #include "wpa_parser.h" #include "connection_parser.h" +#include "nm-config.h" -/* Fake config file function to make the linker happy */ -const char *ifnet_plugin_get_conf_file (void); - -const char * -ifnet_plugin_get_conf_file (void) +/* Fake NMConfig handling; the values it returns don't matter, so this + * is easier than forcing it to read our own config file, etc. + */ +NMConfig * +nm_config_get (void) { - return "/etc/foo/barasdfasdfasdfasdf"; + return NULL; } +const char * +nm_config_get_dhcp_client (NMConfig *config) +{ + return "dhclient"; +} static void test_getdata () diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c index 321440b0f..9efbd51b0 100644 --- a/src/settings/plugins/ifupdown/plugin.c +++ b/src/settings/plugins/ifupdown/plugin.c @@ -80,7 +80,6 @@ typedef struct { GHashTable *well_known_interfaces; GHashTable *well_known_ifaces; gboolean unmanage_well_known; - const char *conf_file; gulong inotify_event_id; int inotify_system_hostname_wd; @@ -311,7 +310,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) GHashTable *auto_ifaces; if_block *block = NULL; NMInotifyHelper *inotify_helper; - GKeyFile* keyfile; + char *value; GError *error = NULL; GList *keys, *iter; const char *subsys[2] = { "net", NULL }; @@ -443,36 +442,23 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) g_list_free (keys); g_hash_table_destroy (auto_ifaces); - /* Read the config file to find out whether to manage interfaces */ - keyfile = g_key_file_new (); - if (!g_key_file_load_from_file (keyfile, - priv->conf_file, - G_KEY_FILE_NONE, - &error)) { - nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s", - priv->conf_file, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + /* Check the config file to find out whether to manage interfaces */ + value = nm_config_get_value (nm_config_get (), + IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, + &error); + if (error) { + nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: %s", + nm_config_get_path (nm_config_get ()), + error->message); } else { gboolean manage_well_known; error = NULL; - manage_well_known = g_key_file_get_boolean (keyfile, - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - &error); - if (error) { - nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s", - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } else - priv->unmanage_well_known = !manage_well_known; + manage_well_known = !g_strcmp0 (value, "true") || !g_strcmp0 (value, "1"); + priv->unmanage_well_known = !manage_well_known; + g_free (value); } PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); - if (keyfile) - g_key_file_free (keyfile); /* Add well-known interfaces */ keys = g_udev_client_query_by_subsystem (priv->client, "net"); @@ -715,7 +701,6 @@ nm_system_config_factory (void) if (!singleton) { singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL)); priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (singleton); - priv->conf_file = nm_config_get_path (nm_config_get ()); } else g_object_ref (singleton);