NetworkManager/src/settings/nm-settings.c

1598 lines
50 KiB
C
Raw Normal View History

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
* Dan Williams <dcbw@redhat.com>
* Tambet Ingo <tambet@gmail.com>
*
* 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.
*
2010-04-07 11:31:02 -07:00
* (C) Copyright 2007 - 2010 Red Hat, Inc.
* (C) Copyright 2008 Novell, Inc.
*/
#include <unistd.h>
#include <string.h>
#include <gmodule.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <pwd.h>
#include <NetworkManager.h>
#include <nm-connection.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <nm-setting-8021x.h>
#include <nm-setting-bluetooth.h>
#include <nm-setting-cdma.h>
#include <nm-setting-connection.h>
#include <nm-setting-gsm.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
#include <nm-setting-olpc-mesh.h>
#include <nm-setting-ppp.h>
#include <nm-setting-pppoe.h>
#include <nm-setting-serial.h>
#include <nm-setting-vpn.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include "../nm-device-ethernet.h"
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
#include "nm-dbus-glib-types.h"
#include "nm-settings.h"
#include "nm-settings-connection.h"
2008-05-08 Tambet Ingo <tambet@gmail.com> Use PolicyKit to authorize the system settings' AddConnection method and the system settings connections' Update and Delete methods. * libnm-glib/nm-settings.c (impl_exported_connection_update) (impl_exported_connection_delete, nm_exported_connection_update) (nm_exported_connection_delete): Return boolean and fill GError to notify the callers of the reasons why it might have failed. * libnm-glib/nm-dbus-settings-system.c (nm_dbus_settings_system_add_connection): Return the error from dbus call so that the callers can see why it failed. * libnm-glib/nm-dbus-connection.c (update, delete): Update the signatures. * system-settings/src/nm-polkit-helpers.[ch]: Implement. * system-settings/src/nm-sysconfig-connection.[ch]: Implement. New abstract base class that checks PolicyKit permissions. * system-settings/src/dbus-settings.c: (impl_settings_add_connection): Check the policy before carring out the request. * system-settings/plugins/keyfile/nm-keyfile-connection.c: Inherit from NMSysconfigConnection, check the policies before allowing updating or removing. * system-settings/plugins/ifcfg-suse/nm-suse-connection.c: Inherit from NMSysconfigConnection. * introspection/nm-exported-connection.xml: Annotate "Update" and "Delete" methods with async flag so that the implementations can get access to DBusGMethodInvocation. * system-settings/src/dbus-settings.c (settings_add_connection_check_privileges): Implement. (impl_settings_add_connection): Check the privileges before adding a new connection. Improve error reporting. * introspection/nm-settings-system.xml: Make the 'AddConnection' method async so that the implementation can access DBusGMethodInvocation. * configure.in: Check for PolicyKit. * policy/org.freedesktop.network-manager-settings.system.policy: New file. * policy/Makefile.am: Install the policy file. * configure.in: Add 'policy' subdir. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3646 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-05-09 06:33:30 +00:00
#include "nm-polkit-helpers.h"
#include "nm-settings-error.h"
#include "nm-default-wired-connection.h"
2010-04-07 11:31:02 -07:00
#include "nm-logging.h"
#include "nm-dbus-manager.h"
#include "nm-manager-auth.h"
#include "nm-session-monitor.h"
#include "system-settings/plugins/keyfile/plugin.h"
#include "nm-agent-manager.h"
#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
/* LINKER CRACKROCK */
#define EXPORT(sym) void * __export_##sym = &sym;
#include "nm-inotify-helper.h"
EXPORT(nm_inotify_helper_get_type)
EXPORT(nm_inotify_helper_get)
EXPORT(nm_inotify_helper_add_watch)
EXPORT(nm_inotify_helper_remove_watch)
EXPORT(nm_settings_connection_get_type)
EXPORT(nm_settings_connection_replace_settings)
EXPORT(nm_settings_connection_replace_and_commit)
/* END LINKER CRACKROCK */
static void claim_connection (NMSettings *self,
NMSettingsConnection *connection,
gboolean do_export);
static gboolean impl_settings_list_connections (NMSettings *self,
GPtrArray **connections,
GError **error);
static void impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_save_hostname (NMSettings *self,
const char *hostname,
DBusGMethodInvocation *context);
#include "nm-settings-glue.h"
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
typedef struct {
NMDBusManager *dbus_mgr;
DBusGConnection *bus;
NMAgentManager *agent_mgr;
PolkitAuthority *authority;
guint auth_changed_id;
char *config_file;
NMSessionMonitor *session_monitor;
GSList *auths;
GSList *plugins;
gboolean connections_loaded;
GHashTable *connections;
GSList *unmanaged_specs;
} NMSettingsPrivate;
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT)
#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
enum {
PROPERTIES_CHANGED,
CONNECTION_ADDED,
CONNECTION_UPDATED,
CONNECTION_REMOVED,
CONNECTION_VISIBILITY_CHANGED,
CONNECTIONS_LOADED,
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
NEW_CONNECTION, /* exported, not used internally */
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_UNMANAGED_SPECS,
PROP_HOSTNAME,
PROP_CAN_MODIFY,
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
LAST_PROP
};
static void
load_connections (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
if (priv->connections_loaded)
return;
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
GSList *plugin_connections;
GSList *elt;
plugin_connections = nm_system_config_interface_get_connections (plugin);
// FIXME: ensure connections from plugins loaded with a lower priority
// get rejected when they conflict with connections from a higher
// priority plugin.
for (elt = plugin_connections; elt; elt = g_slist_next (elt))
claim_connection (self, NM_SETTINGS_CONNECTION (elt->data), TRUE);
g_slist_free (plugin_connections);
}
priv->connections_loaded = TRUE;
/* FIXME: Bad hack */
unmanaged_specs_changed (NULL, self);
g_signal_emit (self, signals[CONNECTIONS_LOADED], 0);
}
void
nm_settings_for_each_connection (NMSettings *self,
NMSettingsForEachFunc for_each_func,
gpointer user_data)
{
NMSettingsPrivate *priv;
GHashTableIter iter;
gpointer data;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_SETTINGS (self));
g_return_if_fail (for_each_func != NULL);
priv = NM_SETTINGS_GET_PRIVATE (self);
load_connections (self);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &data))
for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
}
static gboolean
impl_settings_list_connections (NMSettings *self,
GPtrArray **connections,
GError **error)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GHashTableIter iter;
gpointer key;
load_connections (self);
*connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, &key, NULL))
g_ptr_array_add (*connections, g_strdup ((const char *) key));
return TRUE;
}
static int
connection_sort (gconstpointer pa, gconstpointer pb)
{
NMConnection *a = NM_CONNECTION (pa);
NMSettingConnection *con_a;
NMConnection *b = NM_CONNECTION (pb);
NMSettingConnection *con_b;
con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION);
g_assert (con_a);
con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
g_assert (con_b);
if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) {
if (nm_setting_connection_get_autoconnect (con_a))
return -1;
return 1;
}
if (nm_setting_connection_get_timestamp (con_a) > nm_setting_connection_get_timestamp (con_b))
return -1;
else if (nm_setting_connection_get_timestamp (con_a) == nm_setting_connection_get_timestamp (con_b))
return 0;
return 1;
}
/* Returns a list of NMSettingsConnections. Caller must free the list with
* g_slist_free().
*/
GSList *
nm_settings_get_connections (NMSettings *self)
{
GHashTableIter iter;
gpointer data = NULL;
GSList *list = NULL;
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections);
while (g_hash_table_iter_next (&iter, NULL, &data))
list = g_slist_insert_sorted (list, data, connection_sort);
return list;
}
NMSettingsConnection *
nm_settings_get_connection_by_path (NMSettings *self, const char *path)
{
NMSettingsPrivate *priv;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
g_return_val_if_fail (path != NULL, NULL);
priv = NM_SETTINGS_GET_PRIVATE (self);
load_connections (self);
return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path);
}
static void
clear_unmanaged_specs (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL);
g_slist_free (priv->unmanaged_specs);
priv->unmanaged_specs = NULL;
}
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
static char*
uscore_to_wincaps (const char *uscore)
{
const char *p;
GString *str;
gboolean last_was_uscore;
last_was_uscore = TRUE;
str = g_string_new (NULL);
p = uscore;
while (p && *p) {
if (*p == '-' || *p == '_')
last_was_uscore = TRUE;
else {
if (last_was_uscore) {
g_string_append_c (str, g_ascii_toupper (*p));
last_was_uscore = FALSE;
} else
g_string_append_c (str, *p);
}
++p;
}
return g_string_free (str, FALSE);
}
static void
notify (GObject *object, GParamSpec *pspec)
{
GValue *value;
GHashTable *hash;
value = g_slice_new0 (GValue);
hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
g_value_init (value, pspec->value_type);
g_object_get_property (object, pspec->name, value);
g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value);
g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash);
g_hash_table_destroy (hash);
g_value_unset (value);
g_slice_free (GValue, value);
}
const GSList *
nm_settings_get_unmanaged_specs (NMSettings *self)
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
load_connections (self);
return priv->unmanaged_specs;
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
}
static NMSystemConfigInterface *
get_plugin (NMSettings *self, guint32 capability)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
g_return_val_if_fail (self != NULL, NULL);
/* Do any of the plugins support setting the hostname? */
for (iter = priv->plugins; iter; iter = iter->next) {
NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & capability)
return NM_SYSTEM_CONFIG_INTERFACE (iter->data);
}
return NULL;
}
system-settings: fix use-after-free causing crashes when hostname is empty Should be returning NULL here since the actual hostname is returned in the for() loop if the plugin supports hostnames. But if the plugin for some reason returns an empty string (which they aren't supposed to do) then hostname would be left assigned to an already-freed value, which was then returned to higher layers. ==12331== Invalid free() / delete / delete[] ==12331== at 0x4024B3A: free (vg_replace_malloc.c:366) ==12331== by 0x448BFC5: g_free (gmem.c:191) ==12331== by 0x43E0E05: value_free_string (gvaluetypes.c:268) ==12331== by 0x43DC587: g_value_unset (gvalue.c:276) ==12331== by 0x80B297F: notify (nm-sysconfig-settings.c:229) ==12331== by 0x43C64E7: g_cclosure_marshal_VOID__PARAM (gmarshal.c:531) ==12331== by 0x43B78B8: g_type_class_meta_marshal (gclosure.c:878) ==12331== by 0x43B9251: g_closure_invoke (gclosure.c:767) ==12331== by 0x43CD239: signal_emit_unlocked_R (gsignal.c:3178) ==12331== by 0x43CEDB3: g_signal_emit_valist (gsignal.c:2981) ==12331== by 0x43CF255: g_signal_emit (gsignal.c:3038) ==12331== by 0x43BD630: g_object_dispatch_properties_changed (gobject.c:801) ==12331== Address 0x479f208 is 0 bytes inside a block of size 1 free'd ==12331== at 0x4024B3A: free (vg_replace_malloc.c:366) ==12331== by 0x448BFC5: g_free (gmem.c:191) ==12331== by 0x80B1A08: nm_sysconfig_settings_get_hostname (nm-sysconfig-settings.c:280) ==12331== by 0x80B27C7: get_property (nm-sysconfig-settings.c:1415) ==12331== by 0x43BC707: g_object_get_property (gobject.c:935) ==12331== by 0x80B288D: notify (nm-sysconfig-settings.c:225) ==12331== by 0x43C64E7: g_cclosure_marshal_VOID__PARAM (gmarshal.c:531) ==12331== by 0x43B78B8: g_type_class_meta_marshal (gclosure.c:878) ==12331== by 0x43B9251: g_closure_invoke (gclosure.c:767) ==12331== by 0x43CD239: signal_emit_unlocked_R (gsignal.c:3178) ==12331== by 0x43CEDB3: g_signal_emit_valist (gsignal.c:2981) ==12331== by 0x43CF255: g_signal_emit (gsignal.c:3038)
2010-09-24 18:25:45 -05:00
/* Returns an allocated string which the caller owns and must eventually free */
char *
nm_settings_get_hostname (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
char *hostname = NULL;
/* Hostname returned is the hostname returned from the first plugin
* that provides one.
*/
for (iter = priv->plugins; iter; iter = iter->next) {
NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
if (hostname && strlen (hostname))
return hostname;
g_free (hostname);
}
}
system-settings: fix use-after-free causing crashes when hostname is empty Should be returning NULL here since the actual hostname is returned in the for() loop if the plugin supports hostnames. But if the plugin for some reason returns an empty string (which they aren't supposed to do) then hostname would be left assigned to an already-freed value, which was then returned to higher layers. ==12331== Invalid free() / delete / delete[] ==12331== at 0x4024B3A: free (vg_replace_malloc.c:366) ==12331== by 0x448BFC5: g_free (gmem.c:191) ==12331== by 0x43E0E05: value_free_string (gvaluetypes.c:268) ==12331== by 0x43DC587: g_value_unset (gvalue.c:276) ==12331== by 0x80B297F: notify (nm-sysconfig-settings.c:229) ==12331== by 0x43C64E7: g_cclosure_marshal_VOID__PARAM (gmarshal.c:531) ==12331== by 0x43B78B8: g_type_class_meta_marshal (gclosure.c:878) ==12331== by 0x43B9251: g_closure_invoke (gclosure.c:767) ==12331== by 0x43CD239: signal_emit_unlocked_R (gsignal.c:3178) ==12331== by 0x43CEDB3: g_signal_emit_valist (gsignal.c:2981) ==12331== by 0x43CF255: g_signal_emit (gsignal.c:3038) ==12331== by 0x43BD630: g_object_dispatch_properties_changed (gobject.c:801) ==12331== Address 0x479f208 is 0 bytes inside a block of size 1 free'd ==12331== at 0x4024B3A: free (vg_replace_malloc.c:366) ==12331== by 0x448BFC5: g_free (gmem.c:191) ==12331== by 0x80B1A08: nm_sysconfig_settings_get_hostname (nm-sysconfig-settings.c:280) ==12331== by 0x80B27C7: get_property (nm-sysconfig-settings.c:1415) ==12331== by 0x43BC707: g_object_get_property (gobject.c:935) ==12331== by 0x80B288D: notify (nm-sysconfig-settings.c:225) ==12331== by 0x43C64E7: g_cclosure_marshal_VOID__PARAM (gmarshal.c:531) ==12331== by 0x43B78B8: g_type_class_meta_marshal (gclosure.c:878) ==12331== by 0x43B9251: g_closure_invoke (gclosure.c:767) ==12331== by 0x43CD239: signal_emit_unlocked_R (gsignal.c:3178) ==12331== by 0x43CEDB3: g_signal_emit_valist (gsignal.c:2981) ==12331== by 0x43CF255: g_signal_emit (gsignal.c:3038)
2010-09-24 18:25:45 -05:00
return NULL;
}
static void
plugin_connection_added (NMSystemConfigInterface *config,
NMSettingsConnection *connection,
gpointer user_data)
{
claim_connection (NM_SETTINGS (user_data), connection, TRUE);
}
static gboolean
find_unmanaged_device (NMSettings *self, const char *needle)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) {
if (!strcmp ((const char *) iter->data, needle))
return TRUE;
}
return FALSE;
}
static void
unmanaged_specs_changed (NMSystemConfigInterface *config,
gpointer user_data)
{
NMSettings *self = NM_SETTINGS (user_data);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
clear_unmanaged_specs (self);
/* Ask all the plugins for their unmanaged specs */
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
GSList *specs, *specs_iter;
specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) {
if (!find_unmanaged_device (self, (const char *) specs_iter->data)) {
priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data);
} else
g_free (specs_iter->data);
}
g_slist_free (specs);
}
g_object_notify (G_OBJECT (self), NM_SETTINGS_UNMANAGED_SPECS);
}
static void
hostname_changed (NMSystemConfigInterface *config,
GParamSpec *pspec,
gpointer user_data)
{
g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME);
}
static void
add_plugin (NMSettings *self, NMSystemConfigInterface *plugin)
{
NMSettingsPrivate *priv;
char *pname = NULL;
char *pinfo = NULL;
g_return_if_fail (NM_IS_SETTINGS (self));
g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
priv = NM_SETTINGS_GET_PRIVATE (self);
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
G_CALLBACK (plugin_connection_added), self);
g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
nm_system_config_interface_init (plugin, NULL);
g_object_get (G_OBJECT (plugin),
NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo,
NULL);
g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
G_CALLBACK (unmanaged_specs_changed), self);
2010-12-10 12:32:22 -06:00
nm_log_info (LOGD_SETTINGS, "Loaded plugin %s: %s", pname, pinfo);
g_free (pname);
g_free (pinfo);
}
static GObject *
find_plugin (GSList *list, const char *pname)
{
GSList *iter;
GObject *obj = NULL;
g_return_val_if_fail (pname != NULL, FALSE);
for (iter = list; iter && !obj; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
char *list_pname = NULL;
g_object_get (G_OBJECT (plugin),
NM_SYSTEM_CONFIG_INTERFACE_NAME,
&list_pname,
NULL);
if (list_pname && !strcmp (pname, list_pname))
obj = G_OBJECT (plugin);
g_free (list_pname);
}
return obj;
}
static gboolean
load_plugins (NMSettings *self, const char *plugins, GError **error)
{
GSList *list = NULL;
char **plist;
char **iter;
gboolean success = TRUE;
plist = g_strsplit (plugins, ",", 0);
if (!plist)
return FALSE;
for (iter = plist; *iter; iter++) {
GModule *plugin;
char *full_name, *path;
const char *pname = g_strstrip (*iter);
GObject *obj;
GObject * (*factory_func) (void);
/* keyfile plugin built in now */
if (!strcmp (pname, "keyfile"))
continue;
/* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */
if (!strcmp (pname, "ifcfg-fedora"))
pname = "ifcfg-rh";
obj = find_plugin (list, pname);
if (obj)
continue;
full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
path = g_module_build_path (PLUGINDIR, full_name);
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
if (!plugin) {
g_set_error (error, 0, 0,
"Could not load plugin '%s': %s",
pname, g_module_error ());
g_free (full_name);
g_free (path);
success = FALSE;
break;
}
g_free (full_name);
g_free (path);
if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
g_set_error (error, 0, 0,
"Could not find plugin '%s' factory function.",
pname);
success = FALSE;
break;
}
obj = (*factory_func) ();
if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
g_set_error (error, 0, 0,
"Plugin '%s' returned invalid system config object.",
pname);
success = FALSE;
break;
}
g_module_make_resident (plugin);
g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
}
g_strfreev (plist);
g_slist_foreach (list, (GFunc) g_object_unref, NULL);
g_slist_free (list);
return success;
}
#define REMOVED_ID_TAG "removed-id-tag"
#define UPDATED_ID_TAG "updated-id-tag"
#define VISIBLE_ID_TAG "visible-id-tag"
static void
connection_removed (NMSettingsConnection *obj, gpointer user_data)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data);
GObject *connection = G_OBJECT (obj);
guint id;
g_object_ref (connection);
/* Disconnect signal handlers, as plugins might still keep references
* to the connection (and thus the signal handlers would still be live)
* even after NMSettings has dropped all its references.
*/
id = GPOINTER_TO_UINT (g_object_get_data (connection, REMOVED_ID_TAG));
if (id)
g_signal_handler_disconnect (connection, id);
id = GPOINTER_TO_UINT (g_object_get_data (connection, UPDATED_ID_TAG));
if (id)
g_signal_handler_disconnect (connection, id);
id = GPOINTER_TO_UINT (g_object_get_data (connection, VISIBLE_ID_TAG));
if (id)
g_signal_handler_disconnect (connection, id);
/* Unregister the connection with D-Bus and forget about it */
dbus_g_connection_unregister_g_object (priv->bus, connection);
g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections,
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)));
/* Re-emit for listeners like NMPolicy */
g_signal_emit (NM_SETTINGS (user_data),
signals[CONNECTION_REMOVED],
0,
connection);
g_object_unref (connection);
}
static void
connection_updated (NMSettingsConnection *connection, gpointer user_data)
{
/* Re-emit for listeners like NMPolicy */
g_signal_emit (NM_SETTINGS (user_data),
signals[CONNECTION_UPDATED],
0,
connection);
}
static void
connection_visibility_changed (NMSettingsConnection *connection,
GParamSpec *pspec,
gpointer user_data)
{
/* Re-emit for listeners like NMPolicy */
g_signal_emit (NM_SETTINGS (user_data),
signals[CONNECTION_VISIBILITY_CHANGED],
0,
connection);
}
static void
claim_connection (NMSettings *self,
NMSettingsConnection *connection,
gboolean do_export)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
static guint32 ec_counter = 0;
GError *error = NULL;
GHashTableIter iter;
gpointer data;
char *path;
guint id;
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &data)) {
/* prevent duplicates */
if (data == connection)
return;
}
if (!nm_connection_verify (NM_CONNECTION (connection), &error)) {
2010-12-10 12:32:22 -06:00
nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: '%s' / '%s' invalid: %d",
g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
error->message, error->code);
g_error_free (error);
return;
}
/* Ensure it's initial visibility is up-to-date */
nm_settings_connection_recheck_visibility (connection);
id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED,
G_CALLBACK (connection_removed),
self);
g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id));
id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED,
G_CALLBACK (connection_updated),
self);
g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id));
id = g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
G_CALLBACK (connection_visibility_changed),
self);
g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id));
/* Export the connection over D-Bus */
g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
nm_connection_set_path (NM_CONNECTION (connection), path);
dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection));
g_free (path);
g_hash_table_insert (priv->connections,
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)),
g_object_ref (connection));
/* Only emit the individual connection-added signal after connections
* have been initially loaded. While getting the first list of connections
* we suppress it, then send the connections-loaded signal after we're all
* done to minimize processing.
*/
if (priv->connections_loaded) {
/* Internal added signal */
g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
/* Exported D-Bus signal */
g_signal_emit (self, signals[NEW_CONNECTION], 0, connection);
}
}
// TODO it seems that this is only ever used to remove a
// NMDefaultWiredConnection, and it probably needs to stay that way. So this
// *needs* a better name!
static void
remove_default_wired_connection (NMSettings *self,
NMSettingsConnection *connection,
gboolean do_signal)
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
const char *path = nm_connection_get_path (NM_CONNECTION (connection));
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
if (g_hash_table_lookup (priv->connections, path)) {
g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_SIGNAL_CONNECTION_REMOVED);
g_hash_table_remove (priv->connections, path);
2008-04-07 Dan Williams <dcbw@redhat.com> * introspection/nm-settings-system.xml introspection/Makefile.am - Define the unmanaged devices interface for the system settings service * system-settings/src/nm-system-config-hal-manager.c system-settings/src/nm-system-config-hal-manager.h system-settings/src/nm-system-config-hal-manager-private.h system-settings/src/Makefile.am - Add a lightweight HAL manager object for tracking network devices for the purpose of determining unmanaged devices and which devices need the default DHCP connections * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - (nm_system_config_interface_init): add the HAL manager as an argument - (nm_system_config_interface_get_unmanaged_devices): implement - Define 'unmanaged-devices-changed' signal * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - Implement the unmanaged devices interface; some cleanups * system-settings/plugins/ifcfg-suse/plugin.c - Fixup for plugin interface changes * system-settings/plugins/ifcfg-fedora/plugin.c - (get_ether_device_udi): new function; find the device that has a specified MAC address and return its UDI - (get_udi_for_connection): new function; try to find the specific device a connection is locked to, if any - (device_added_cb, device_removed_cb): update unmanaged device list in response to HAL events - (get_unmanaged_devices): new function; return unmanaged device list - (build_one_connection): set the connection's locked device, if any - (write_auto_wired_connection): remove - (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found - (handle_connection_changed): alert listeners that the unmanaged device list has changed - (init): fixup for plugin interface changes, implement unmanaged devices * system-settings/plugins/ifcfg-fedora/parser.c system-settings/plugins/ifcfg-fedora/parser.h - (connection_data_free): clean up connection UDI git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 01:36:39 +00:00
}
}
static NMSettingsConnection *
add_new_connection (NMSettings *self,
NMConnection *connection,
GError **error)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
NMSettingsConnection *added = NULL;
/* 1) plugin writes the NMConnection to disk
* 2) plugin creates a new NMSettingsConnection subclass with the settings
* from the NMConnection and returns it to the settings service
* 3) settings service exports the new NMSettingsConnection subclass
* 4) plugin notices that something on the filesystem has changed
* 5) plugin reads the changes and ignores them because they will
* contain the same data as the connection it already knows about
*/
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
GError *add_error = NULL;
g_clear_error (error);
added = nm_system_config_interface_add_connection (plugin, connection, &add_error);
if (added) {
claim_connection (self, added, TRUE);
return added;
}
g_propagate_error (error, add_error);
}
return NULL;
}
static void
pk_add_cb (NMAuthChain *chain,
GError *chain_error,
DBusGMethodInvocation *context,
gpointer user_data)
{
NMSettings *self = NM_SETTINGS (user_data);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthCallResult result;
GError *error = NULL, *add_error = NULL;
NMConnection *connection;
NMSettingsConnection *added = NULL;
gulong caller_uid = G_MAXULONG;
char *error_desc = NULL;
NMSettingsAddCallback callback;
gpointer callback_data;
priv->auths = g_slist_remove (priv->auths, chain);
if (chain_error) {
error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_GENERAL,
"Error checking authorization: %s",
chain_error->message ? chain_error->message : "(unknown)");
goto done;
}
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY);
/* Caller didn't successfully authenticate */
if (result != NM_AUTH_CALL_RESULT_YES) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
"Insufficient privileges.");
goto done;
}
/* If the caller isn't root, make sure the connection can be viewed by
* the user that's adding it.
*/
if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) {
error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
"Unable to determine UID of request: %s.",
error_desc ? error_desc : "(unknown)");
g_free (error_desc);
goto done;
}
connection = nm_auth_chain_get_data (chain, "connection");
/* Ensure the caller's username exists in the connection's permissions,
* or that the permissions is empty (ie, visible by everyone).
*/
if (0 != caller_uid) {
if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
error_desc);
g_free (error_desc);
goto done;
}
/* Caller is allowed to add this connection */
}
added = add_new_connection (self, connection, &add_error);
if (!added) {
error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_ADD_FAILED,
"Saving connection failed: (%d) %s",
add_error ? add_error->code : -1,
(add_error && add_error->message) ? add_error->message : "(unknown)");
g_error_free (add_error);
}
done:
callback = nm_auth_chain_get_data (chain, "callback");
callback_data = nm_auth_chain_get_data (chain, "callback-data");
callback (self, added, error, context, callback_data);
g_clear_error (&error);
nm_auth_chain_unref (chain);
}
static void
add_cb (NMSettings *self,
NMSettingsConnection *connection,
GError *error,
DBusGMethodInvocation *context,
gpointer user_data)
{
if (error)
dbus_g_method_return_error (context, error);
else
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
}
void
nm_settings_add_connection (NMSettings *self,
NMConnection *connection,
DBusGMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthChain *chain;
GError *error;
/* Do any of the plugins support adding? */
if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
"None of the registered plugins support add.");
callback (self, NULL, error, context, user_data);
g_error_free (error);
return;
2008-05-08 Tambet Ingo <tambet@gmail.com> Use PolicyKit to authorize the system settings' AddConnection method and the system settings connections' Update and Delete methods. * libnm-glib/nm-settings.c (impl_exported_connection_update) (impl_exported_connection_delete, nm_exported_connection_update) (nm_exported_connection_delete): Return boolean and fill GError to notify the callers of the reasons why it might have failed. * libnm-glib/nm-dbus-settings-system.c (nm_dbus_settings_system_add_connection): Return the error from dbus call so that the callers can see why it failed. * libnm-glib/nm-dbus-connection.c (update, delete): Update the signatures. * system-settings/src/nm-polkit-helpers.[ch]: Implement. * system-settings/src/nm-sysconfig-connection.[ch]: Implement. New abstract base class that checks PolicyKit permissions. * system-settings/src/dbus-settings.c: (impl_settings_add_connection): Check the policy before carring out the request. * system-settings/plugins/keyfile/nm-keyfile-connection.c: Inherit from NMSysconfigConnection, check the policies before allowing updating or removing. * system-settings/plugins/ifcfg-suse/nm-suse-connection.c: Inherit from NMSysconfigConnection. * introspection/nm-exported-connection.xml: Annotate "Update" and "Delete" methods with async flag so that the implementations can get access to DBusGMethodInvocation. * system-settings/src/dbus-settings.c (settings_add_connection_check_privileges): Implement. (impl_settings_add_connection): Check the privileges before adding a new connection. Improve error reporting. * introspection/nm-settings-system.xml: Make the 'AddConnection' method async so that the implementation can access DBusGMethodInvocation. * configure.in: Check for PolicyKit. * policy/org.freedesktop.network-manager-settings.system.policy: New file. * policy/Makefile.am: Install the policy file. * configure.in: Add 'policy' subdir. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3646 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-05-09 06:33:30 +00:00
}
/* Otherwise validate the user request */
chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self);
g_assert (chain);
priv->auths = g_slist_append (priv->auths, chain);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE);
nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref);
nm_auth_chain_set_data (chain, "callback", callback, NULL);
nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
}
static void
impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context)
{
NMConnection *connection;
GError *error = NULL;
connection = nm_connection_new_from_hash (settings, &error);
if (connection) {
nm_settings_add_connection (self, connection, context, add_cb, NULL);
g_object_unref (connection);
} else {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
}
}
static void
pk_hostname_cb (NMAuthChain *chain,
GError *chain_error,
DBusGMethodInvocation *context,
gpointer user_data)
{
NMSettings *self = NM_SETTINGS (user_data);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthCallResult result;
gboolean success = FALSE;
GError *error = NULL;
GSList *iter;
const char *hostname;
priv->auths = g_slist_remove (priv->auths, chain);
/* If our NMSettingsConnection is already gone, do nothing */
if (chain_error) {
error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_GENERAL,
"Error checking authorization: %s",
chain_error->message ? chain_error->message : "(unknown)");
goto done;
}
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY);
/* Caller didn't successfully authenticate */
if (result != NM_AUTH_CALL_RESULT_YES) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
"Insufficient privileges.");
goto done;
}
2008-09-18 Dan Williams <dcbw@redhat.com> Implement support for honoring configured and automatic hostnames, and for setting the configured hostname. * introspection/nm-ip4-config.xml src/nm-ip4-config.c src/nm-ip4-config.h src/dhcp-manager/nm-dhcp-manager.c - Remove useless hostname property; it's not really part of the IPv4 config * introspection/nm-settings-system.xml libnm-glib/nm-dbus-settings-system.c libnm-glib/nm-dbus-settings-system.h - Add SetHostname() call to system settings D-Bus interface - Add Hostname property to system settings D-Bus interface - (nm_dbus_settings_system_save_hostname, nm_dbus_settings_system_get_hostname): implement * src/nm-device.c src/nm-device.h - (nm_device_get_dhcp4_config): implement * src/nm-manager.c src/nm-manager.h - Fetch and track system settings service hostname changes, and proxy the changes via a GObject property of the manager * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - Replace nm_system_config_interface_supports_add() with a capabilities bitfield * system-settings/src/nm-system-config-error.c system-settings/src/nm-system-config-error.h - Add additional errors * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - (get_property, nm_sysconfig_settings_class_init): add hostname property; first plugin returning a hostname wins - (impl_settings_add_connection): use plugin capabilities instead of nm_system_config_interface_supports_add() - (impl_settings_save_hostname): implement hostname saving * src/NetworkManagerPolicy.c - (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new, lookup_thread_die): implement an asynchronous hostname lookup thread which given an IPv4 address tries to look up the hostname for that address with reverse DNS - (get_best_device): split out best device code from update_routing_and_dns() - (update_etc_hosts): update /etc/hosts with the machine's new hostname to preserve the 127.0.0.1 reverse mapping that so many things require - (set_system_hostname): set a given hostname - (update_system_hostname): implement hostname policy; a configured hostname (from the system settings service) is used if available, otherwise an automatically determined hostname from DHCP, VPN, etc. If there was no automatically determined hostname, reverse DNS of the best device's IP address will be used, and as a last resort the hostname 'localhost.localdomain' is set. - (update_routing_and_dns): use get_best_device(); update the system hostname when the network config changes - (hostname_changed): update system hostname if the system settings service signals a hostname change - (nm_policy_new): list for system settings service hostname changes - (nm_policy_destroy): ensure that an in-progress hostname lookup thread gets told to die * system-settings/plugins/keyfile/plugin.c system-settings/plugins/ifcfg-suse/plugin.c - (get_property, sc_plugin_ifcfg_class_init): implement hostname and capabilities properties * system-settings/plugins/ifcfg-fedora/shvar.c - (svOpenFile): re-enable R/W access of ifcfg files since the plugin writes out /etc/sysconfig/network now * system-settings/plugins/ifcfg-fedora/plugin.c - (plugin_get_hostname): get hostname from /etc/sysconfig/network - (plugin_set_hostname): save hostname to /etc/sysconfig/network - (sc_network_changed_cb): handle changes to /etc/sysconfig/network - (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes - (get_property, set_property, sc_plugin_ifcfg_class_init): implement hostname get/set and capabilities get git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
/* Set the hostname in all plugins */
hostname = nm_auth_chain_get_data (chain, "hostname");
2008-09-18 Dan Williams <dcbw@redhat.com> Implement support for honoring configured and automatic hostnames, and for setting the configured hostname. * introspection/nm-ip4-config.xml src/nm-ip4-config.c src/nm-ip4-config.h src/dhcp-manager/nm-dhcp-manager.c - Remove useless hostname property; it's not really part of the IPv4 config * introspection/nm-settings-system.xml libnm-glib/nm-dbus-settings-system.c libnm-glib/nm-dbus-settings-system.h - Add SetHostname() call to system settings D-Bus interface - Add Hostname property to system settings D-Bus interface - (nm_dbus_settings_system_save_hostname, nm_dbus_settings_system_get_hostname): implement * src/nm-device.c src/nm-device.h - (nm_device_get_dhcp4_config): implement * src/nm-manager.c src/nm-manager.h - Fetch and track system settings service hostname changes, and proxy the changes via a GObject property of the manager * system-settings/src/nm-system-config-interface.c system-settings/src/nm-system-config-interface.h - Replace nm_system_config_interface_supports_add() with a capabilities bitfield * system-settings/src/nm-system-config-error.c system-settings/src/nm-system-config-error.h - Add additional errors * system-settings/src/dbus-settings.c system-settings/src/dbus-settings.h - (get_property, nm_sysconfig_settings_class_init): add hostname property; first plugin returning a hostname wins - (impl_settings_add_connection): use plugin capabilities instead of nm_system_config_interface_supports_add() - (impl_settings_save_hostname): implement hostname saving * src/NetworkManagerPolicy.c - (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new, lookup_thread_die): implement an asynchronous hostname lookup thread which given an IPv4 address tries to look up the hostname for that address with reverse DNS - (get_best_device): split out best device code from update_routing_and_dns() - (update_etc_hosts): update /etc/hosts with the machine's new hostname to preserve the 127.0.0.1 reverse mapping that so many things require - (set_system_hostname): set a given hostname - (update_system_hostname): implement hostname policy; a configured hostname (from the system settings service) is used if available, otherwise an automatically determined hostname from DHCP, VPN, etc. If there was no automatically determined hostname, reverse DNS of the best device's IP address will be used, and as a last resort the hostname 'localhost.localdomain' is set. - (update_routing_and_dns): use get_best_device(); update the system hostname when the network config changes - (hostname_changed): update system hostname if the system settings service signals a hostname change - (nm_policy_new): list for system settings service hostname changes - (nm_policy_destroy): ensure that an in-progress hostname lookup thread gets told to die * system-settings/plugins/keyfile/plugin.c system-settings/plugins/ifcfg-suse/plugin.c - (get_property, sc_plugin_ifcfg_class_init): implement hostname and capabilities properties * system-settings/plugins/ifcfg-fedora/shvar.c - (svOpenFile): re-enable R/W access of ifcfg files since the plugin writes out /etc/sysconfig/network now * system-settings/plugins/ifcfg-fedora/plugin.c - (plugin_get_hostname): get hostname from /etc/sysconfig/network - (plugin_set_hostname): save hostname to /etc/sysconfig/network - (sc_network_changed_cb): handle changes to /etc/sysconfig/network - (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes - (get_property, set_property, sc_plugin_ifcfg_class_init): implement hostname get/set and capabilities get git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
for (iter = priv->plugins; iter; iter = iter->next) {
NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL);
success = TRUE;
}
}
if (!success) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
"Saving the hostname failed.");
}
done:
if (error)
dbus_g_method_return_error (context, error);
else
dbus_g_method_return (context);
g_clear_error (&error);
nm_auth_chain_unref (chain);
}
static void
impl_settings_save_hostname (NMSettings *self,
const char *hostname,
DBusGMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthChain *chain;
GError *error = NULL;
/* Do any of the plugins support setting the hostname? */
if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
"None of the registered plugins support setting the hostname.");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
/* Otherwise validate the user request */
chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self);
g_assert (chain);
priv->auths = g_slist_append (priv->auths, chain);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, TRUE);
nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free);
}
static gboolean
have_connection_for_device (NMSettings *self, GByteArray *mac)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GHashTableIter iter;
gpointer data;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
const GByteArray *setting_mac;
gboolean ret = FALSE;
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
g_return_val_if_fail (mac != NULL, FALSE);
/* Find a wired connection locked to the given MAC address, if any */
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &data)) {
NMConnection *connection = NM_CONNECTION (data);
const char *connection_type;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
connection_type = nm_setting_connection_get_connection_type (s_con);
if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
&& strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
continue;
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
/* No wired setting; therefore the PPPoE connection applies to any device */
if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
ret = TRUE;
break;
}
setting_mac = nm_setting_wired_get_mac_address (s_wired);
if (setting_mac) {
/* A connection mac-locked to this device */
if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) {
ret = TRUE;
break;
}
} else {
/* A connection that applies to any wired device */
ret = TRUE;
break;
}
}
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);
GKeyFile *config;
char **list, **iter;
gboolean found = FALSE;
g_return_val_if_fail (mac != NULL, FALSE);
if (!priv->config_file)
return FALSE;
config = g_key_file_new ();
if (!config) {
2010-12-10 12:32:22 -06:00
nm_log_warn (LOGD_SETTINGS, "not enough memory to load config file.");
return FALSE;
}
g_key_file_set_list_separator (config, ',');
if (!g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_NONE, NULL))
goto out;
list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL);
for (iter = list; iter && *iter; iter++) {
struct ether_addr *candidate;
if (strcmp(g_strstrip(*iter), "*") == 0) {
found = TRUE;
break;
}
candidate = ether_aton (*iter);
if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
found = TRUE;
break;
}
}
if (list)
g_strfreev (list);
out:
g_key_file_free (config);
return found;
}
#define DEFAULT_WIRED_TAG "default-wired"
static void
default_wired_deleted (NMDefaultWiredConnection *wired,
const GByteArray *mac,
NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMSettingConnection *s_con;
char *tmp;
GKeyFile *config;
char **list, **iter, **updated;
gboolean found = FALSE;
gsize len = 0, i;
char *data;
/* If there was no config file specified, there's nothing to do */
if (!priv->config_file)
goto cleanup;
/* 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 = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
/* Ignore removals of read-only connections, since they couldn't have
* been removed by the user.
*/
if (nm_setting_connection_get_read_only (s_con))
goto cleanup;
config = g_key_file_new ();
if (!config)
goto cleanup;
g_key_file_set_list_separator (config, ',');
g_key_file_load_from_file (config, priv->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++) {
struct ether_addr *candidate;
if (strcmp(g_strstrip(*iter), "*") == 0) {
found = TRUE;
break;
}
candidate = ether_aton (*iter);
if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
found = TRUE;
break;
}
}
/* Add this device's MAC to the list */
if (!found) {
tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
mac->data[0], mac->data[1], mac->data[2],
mac->data[3], mac->data[4], mac->data[5]);
/* 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++] = tmp;
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);
g_free (tmp);
data = g_key_file_to_data (config, &len, NULL);
if (data) {
g_file_set_contents (priv->config_file, data, len, NULL);
g_free (data);
}
}
if (list)
g_strfreev (list);
g_key_file_free (config);
cleanup:
g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
DEFAULT_WIRED_TAG,
NULL);
}
static void
delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data)
{
}
static gboolean
default_wired_try_update (NMDefaultWiredConnection *wired,
NMSettings *self)
{
GError *error = NULL;
NMSettingConnection *s_con;
const char *id;
NMSettingsConnection *added;
/* Try to move this default wired conneciton to a plugin so that it has
* persistent storage.
*/
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE);
added = add_new_connection (self, NM_CONNECTION (wired), &error);
if (added) {
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (wired), delete_cb, NULL);
g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
DEFAULT_WIRED_TAG,
NULL);
2010-12-10 12:32:22 -06:00
nm_log_info (LOGD_SETTINGS, "Saved default wired connection '%s' to persistent storage", id);
return FALSE;
}
2010-12-10 12:32:22 -06:00
nm_log_warn (LOGD_SETTINGS, "couldn't save default wired connection '%s': %d / %s",
2010-04-07 11:31:02 -07:00
id,
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
g_clear_error (&error);
/* If there was an error, don't destroy the default wired connection,
* but add it back to the system settings service. Connection is already
* exported on the bus, don't export it again, thus do_export == FALSE.
*/
claim_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE);
return TRUE;
}
void
nm_settings_device_added (NMSettings *self, NMDevice *device)
{
GByteArray *mac = NULL;
struct ether_addr tmp;
NMDefaultWiredConnection *wired;
NMSettingConnection *s_con;
gboolean read_only = TRUE;
const char *id;
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
return;
/* If the device isn't managed or it already has a default wired connection,
* ignore it.
*/
if ( !nm_device_get_managed (device)
|| g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG))
return;
nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp);
mac = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN);
if ( have_connection_for_device (self, mac)
|| is_mac_auto_wired_blacklisted (self, mac))
goto ignore;
if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
read_only = FALSE;
wired = nm_default_wired_connection_new (mac, device, read_only);
if (!wired)
goto ignore;
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
2010-12-10 12:32:22 -06:00
nm_log_info (LOGD_SETTINGS, "Added default wired connection '%s' for %s",
2010-04-07 11:31:02 -07:00
id, nm_device_get_udi (device));
g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self);
g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self);
claim_connection (self, NM_SETTINGS_CONNECTION (wired), TRUE);
g_object_unref (wired);
g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired);
ignore:
g_byte_array_free (mac, TRUE);
}
void
nm_settings_device_removed (NMSettings *self, NMDevice *device)
{
NMDefaultWiredConnection *connection;
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
return;
connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
if (connection)
remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (connection), TRUE);
}
/***************************************************************/
NMSettings *
nm_settings_new (const char *config_file,
const char *plugins,
GError **error)
{
NMSettings *self;
NMSettingsPrivate *priv;
GObject *keyfile_plugin;
self = g_object_new (NM_TYPE_SETTINGS, NULL);
if (!self)
return NULL;
priv = NM_SETTINGS_GET_PRIVATE (self);
priv->config_file = g_strdup (config_file);
priv->dbus_mgr = nm_dbus_manager_get ();
priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
if (plugins) {
/* Load the plugins; fail if a plugin is not found. */
if (!load_plugins (self, plugins, error)) {
g_object_unref (self);
return NULL;
}
unmanaged_specs_changed (NULL, self);
}
/* Add the keyfile plugin last */
keyfile_plugin = nm_settings_keyfile_plugin_new ();
g_assert (keyfile_plugin);
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin));
dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self));
return self;
}
static void
nm_settings_init (NMSettings *self)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GError *error = NULL;
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
priv->authority = polkit_authority_get_sync (NULL, &error);
if (!priv->authority) {
2010-12-10 12:32:22 -06:00
nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
g_clear_error (&error);
}
priv->session_monitor = nm_session_monitor_get ();
/* Hold a reference to the agent manager so it stays alive; the only
* other holders are NMSettingsConnection objects which are often
* transient, and we don't want the agent manager to get destroyed and
* recreated often.
*/
priv->agent_mgr = nm_agent_manager_get ();
}
static void
dispose (GObject *object)
{
NMSettings *self = NM_SETTINGS (object);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
if (priv->auth_changed_id) {
g_signal_handler_disconnect (priv->authority, priv->auth_changed_id);
priv->auth_changed_id = 0;
}
for (iter = priv->auths; iter; iter = g_slist_next (iter))
nm_auth_chain_unref ((NMAuthChain *) iter->data);
g_slist_free (priv->auths);
g_object_unref (priv->dbus_mgr);
g_object_unref (priv->session_monitor);
g_object_unref (priv->agent_mgr);
G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
NMSettings *self = NM_SETTINGS (object);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
g_hash_table_destroy (priv->connections);
clear_unmanaged_specs (self);
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
g_slist_free (priv->plugins);
g_free (priv->config_file);
G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettings *self = NM_SETTINGS (object);
const GSList *specs, *iter;
GSList *copy = NULL;
switch (prop_id) {
case PROP_UNMANAGED_SPECS:
specs = nm_settings_get_unmanaged_specs (self);
for (iter = specs; iter; iter = g_slist_next (iter))
copy = g_slist_append (copy, g_strdup (iter->data));
g_value_take_boxed (value, copy);
break;
case PROP_HOSTNAME:
g_value_take_string (value, nm_settings_get_hostname (self));
/* Don't ever pass NULL through D-Bus */
if (!g_value_get_string (value))
g_value_set_static_string (value, "");
break;
case PROP_CAN_MODIFY:
g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_settings_class_init (NMSettingsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
g_type_class_add_private (class, sizeof (NMSettingsPrivate));
/* virtual methods */
object_class->notify = notify;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_UNMANAGED_SPECS,
g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS,
"Unamanged device specs",
"Unmanaged device specs",
DBUS_TYPE_G_LIST_OF_STRING,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_HOSTNAME,
g_param_spec_string (NM_SETTINGS_HOSTNAME,
"Hostname",
"Persistent hostname",
NULL,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_CAN_MODIFY,
g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY,
"CanModify",
"Can modify anything (hostname, connections, etc)",
FALSE,
G_PARAM_READABLE));
/* signals */
signals[PROPERTIES_CHANGED] =
g_signal_new ("properties-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, properties_changed),
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
signals[CONNECTION_ADDED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, connection_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
signals[CONNECTION_UPDATED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, connection_updated),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
signals[CONNECTION_REMOVED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, connection_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
signals[CONNECTION_VISIBILITY_CHANGED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
signals[CONNECTIONS_LOADED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSettingsClass, connections_loaded),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[NEW_CONNECTION] =
g_signal_new ("new-connection",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 0);
dbus_g_error_domain_register (NM_SETTINGS_ERROR,
NM_DBUS_IFACE_SETTINGS,
NM_TYPE_SETTINGS_ERROR);
/* And register all the settings errors with D-Bus */
dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR);
dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR);
dbus_g_error_domain_register (NM_SETTING_BLUETOOTH_ERROR, NULL, NM_TYPE_SETTING_BLUETOOTH_ERROR);
dbus_g_error_domain_register (NM_SETTING_CDMA_ERROR, NULL, NM_TYPE_SETTING_CDMA_ERROR);
dbus_g_error_domain_register (NM_SETTING_CONNECTION_ERROR, NULL, NM_TYPE_SETTING_CONNECTION_ERROR);
dbus_g_error_domain_register (NM_SETTING_GSM_ERROR, NULL, NM_TYPE_SETTING_GSM_ERROR);
dbus_g_error_domain_register (NM_SETTING_IP4_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP4_CONFIG_ERROR);
dbus_g_error_domain_register (NM_SETTING_IP6_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP6_CONFIG_ERROR);
dbus_g_error_domain_register (NM_SETTING_OLPC_MESH_ERROR, NULL, NM_TYPE_SETTING_OLPC_MESH_ERROR);
dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR);
dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR);
dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR);
dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR);
dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR);
dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR);
dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR);
dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR);
dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info);
}