2008-08-12 18:39:03 +00:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
2007-11-21 06:24:15 +00:00
|
|
|
/* NetworkManager system settings service
|
|
|
|
|
*
|
|
|
|
|
* Søren Sandmann <sandmann@daimi.au.dk>
|
2008-08-12 18:39:03 +00:00
|
|
|
* Dan Williams <dcbw@redhat.com>
|
|
|
|
|
* Tambet Ingo <tambet@gmail.com>
|
2007-11-21 06:24:15 +00:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2008-06-26 18:31:52 +00:00
|
|
|
* 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.
|
2007-11-21 06:24:15 +00:00
|
|
|
*
|
2011-03-02 15:08:17 +01:00
|
|
|
* (C) Copyright 2007 - 2011 Red Hat, Inc.
|
2008-08-12 18:39:03 +00:00
|
|
|
* (C) Copyright 2008 Novell, Inc.
|
2007-11-21 06:24:15 +00:00
|
|
|
*/
|
|
|
|
|
|
2011-03-14 01:00:56 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
|
2008-10-01 22:59:21 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string.h>
|
2011-09-22 10:16:07 -05:00
|
|
|
#include <ctype.h>
|
2009-06-11 00:39:12 -04:00
|
|
|
#include <gmodule.h>
|
2011-10-14 10:13:49 -04:00
|
|
|
#include <net/if_arp.h>
|
2010-11-18 12:53:24 -06:00
|
|
|
#include <pwd.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
#include <dbus/dbus.h>
|
2009-07-23 09:20:52 -04:00
|
|
|
#include <dbus/dbus-glib-lowlevel.h>
|
2010-02-15 17:26:55 -08:00
|
|
|
|
2011-03-27 16:57:14 -05:00
|
|
|
#include <NetworkManager.h>
|
|
|
|
|
#include <nm-connection.h>
|
2010-02-15 17:26:55 -08:00
|
|
|
#include <nm-setting-8021x.h>
|
|
|
|
|
#include <nm-setting-bluetooth.h>
|
|
|
|
|
#include <nm-setting-cdma.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
#include <nm-setting-connection.h>
|
2010-02-15 17:26:55 -08:00
|
|
|
#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>
|
2009-07-09 11:06:31 -04:00
|
|
|
#include <nm-setting-pppoe.h>
|
2010-02-15 17:26:55 -08:00
|
|
|
#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>
|
2011-10-18 13:48:45 +02:00
|
|
|
#include <nm-setting-bond.h>
|
2011-10-14 10:13:49 -04:00
|
|
|
#include <nm-utils.h>
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
#include "../nm-device-ethernet.h"
|
2011-10-14 10:13:49 -04:00
|
|
|
#include "../nm-device-wired.h"
|
2008-04-08 01:36:39 +00:00
|
|
|
#include "nm-dbus-glib-types.h"
|
2010-10-27 20:05:23 -05:00
|
|
|
#include "nm-settings.h"
|
2011-01-26 11:38:12 -06:00
|
|
|
#include "nm-settings-connection.h"
|
2010-10-27 20:38:26 -05:00
|
|
|
#include "nm-settings-error.h"
|
2009-07-09 11:06:31 -04:00
|
|
|
#include "nm-default-wired-connection.h"
|
2010-04-07 11:31:02 -07:00
|
|
|
#include "nm-logging.h"
|
2010-08-06 15:47:36 -04:00
|
|
|
#include "nm-dbus-manager.h"
|
2010-08-26 14:26:12 -05:00
|
|
|
#include "nm-manager-auth.h"
|
2010-10-26 11:15:19 -05:00
|
|
|
#include "nm-session-monitor.h"
|
2011-02-15 11:55:34 -06:00
|
|
|
#include "plugins/keyfile/plugin.h"
|
2011-01-27 10:41:02 -06:00
|
|
|
#include "nm-agent-manager.h"
|
2011-03-30 12:02:50 -05:00
|
|
|
#include "nm-settings-utils.h"
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
|
2009-06-11 00:39:12 -04:00
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
EXPORT(nm_settings_connection_get_type)
|
|
|
|
|
EXPORT(nm_settings_connection_replace_settings)
|
|
|
|
|
EXPORT(nm_settings_connection_replace_and_commit)
|
2009-06-11 00:39:12 -04:00
|
|
|
/* END LINKER CRACKROCK */
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
static void claim_connection (NMSettings *self,
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *connection,
|
2009-07-23 09:20:52 -04:00
|
|
|
gboolean do_export);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
static gboolean impl_settings_list_connections (NMSettings *self,
|
2010-07-29 00:11:21 -04:00
|
|
|
GPtrArray **connections,
|
|
|
|
|
GError **error);
|
|
|
|
|
|
2011-04-22 11:55:52 -05:00
|
|
|
static gboolean impl_settings_get_connection_by_uuid (NMSettings *self,
|
|
|
|
|
const char *uuid,
|
|
|
|
|
char **out_object_path,
|
|
|
|
|
GError **error);
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
static void impl_settings_add_connection (NMSettings *self,
|
2010-07-29 00:11:21 -04:00
|
|
|
GHashTable *settings,
|
|
|
|
|
DBusGMethodInvocation *context);
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
static void impl_settings_save_hostname (NMSettings *self,
|
2009-07-23 09:20:52 -04:00
|
|
|
const char *hostname,
|
|
|
|
|
DBusGMethodInvocation *context);
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2010-07-29 00:11:21 -04:00
|
|
|
#include "nm-settings-glue.h"
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
|
2008-05-07 09:48:12 +00:00
|
|
|
|
2008-04-08 01:36:39 +00:00
|
|
|
typedef struct {
|
2010-10-27 16:17:44 -05:00
|
|
|
NMDBusManager *dbus_mgr;
|
2010-07-29 00:11:21 -04:00
|
|
|
DBusGConnection *bus;
|
|
|
|
|
|
2011-01-27 10:41:02 -06:00
|
|
|
NMAgentManager *agent_mgr;
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
char *config_file;
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2010-11-18 14:05:33 -06:00
|
|
|
NMSessionMonitor *session_monitor;
|
2010-11-17 17:44:33 -06:00
|
|
|
GSList *auths;
|
2009-10-21 14:19:01 -07:00
|
|
|
|
2008-04-22 14:48:02 +00:00
|
|
|
GSList *plugins;
|
|
|
|
|
gboolean connections_loaded;
|
2010-10-26 16:33:47 -05:00
|
|
|
GHashTable *connections;
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *unmanaged_specs;
|
2010-10-27 20:05:23 -05:00
|
|
|
} NMSettingsPrivate;
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT)
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
|
2008-04-08 01:36:39 +00:00
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
PROPERTIES_CHANGED,
|
2010-10-27 15:47:10 -05:00
|
|
|
CONNECTION_ADDED,
|
|
|
|
|
CONNECTION_UPDATED,
|
|
|
|
|
CONNECTION_REMOVED,
|
|
|
|
|
CONNECTION_VISIBILITY_CHANGED,
|
|
|
|
|
CONNECTIONS_LOADED,
|
2011-06-28 15:48:12 +02:00
|
|
|
AGENT_REGISTERED,
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2010-10-27 16:20:41 -05:00
|
|
|
NEW_CONNECTION, /* exported, not used internally */
|
2008-04-08 01:36:39 +00:00
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
PROP_0,
|
2009-06-11 00:39:12 -04:00
|
|
|
PROP_UNMANAGED_SPECS,
|
2010-08-03 13:23:30 -04:00
|
|
|
PROP_HOSTNAME,
|
|
|
|
|
PROP_CAN_MODIFY,
|
2008-04-08 01:36:39 +00:00
|
|
|
|
|
|
|
|
LAST_PROP
|
|
|
|
|
};
|
|
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
load_connections (NMSettings *self)
|
2008-05-11 20:20:52 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2008-05-11 20:20:52 +00:00
|
|
|
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))
|
2011-01-26 11:38:12 -06:00
|
|
|
claim_connection (self, NM_SETTINGS_CONNECTION (elt->data), TRUE);
|
2008-05-11 20:20:52 +00:00
|
|
|
|
|
|
|
|
g_slist_free (plugin_connections);
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-18 14:46:57 +00:00
|
|
|
priv->connections_loaded = TRUE;
|
|
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
/* FIXME: Bad hack */
|
2009-07-23 09:20:52 -04:00
|
|
|
unmanaged_specs_changed (NULL, self);
|
2010-10-27 15:47:10 -05:00
|
|
|
|
|
|
|
|
g_signal_emit (self, signals[CONNECTIONS_LOADED], 0);
|
2008-05-07 09:48:12 +00:00
|
|
|
}
|
|
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
void
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_for_each_connection (NMSettings *self,
|
|
|
|
|
NMSettingsForEachFunc for_each_func,
|
|
|
|
|
gpointer user_data)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv;
|
2009-07-23 09:20:52 -04:00
|
|
|
GHashTableIter iter;
|
2010-10-27 15:47:10 -05:00
|
|
|
gpointer data;
|
2008-05-07 09:48:12 +00:00
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
g_return_if_fail (self != NULL);
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_if_fail (NM_IS_SETTINGS (self));
|
2010-08-26 18:05:33 -05:00
|
|
|
g_return_if_fail (for_each_func != NULL);
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
load_connections (self);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2010-10-26 16:33:47 -05:00
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
2010-10-27 15:47:10 -05:00
|
|
|
while (g_hash_table_iter_next (&iter, NULL, &data))
|
2011-01-26 11:38:12 -06:00
|
|
|
for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2010-07-29 00:11:21 -04:00
|
|
|
static gboolean
|
2010-10-27 20:05:23 -05:00
|
|
|
impl_settings_list_connections (NMSettings *self,
|
2010-07-29 00:11:21 -04:00
|
|
|
GPtrArray **connections,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-08-26 18:05:33 -05:00
|
|
|
GHashTableIter iter;
|
2010-10-27 16:23:47 -05:00
|
|
|
gpointer key;
|
2010-07-29 00:11:21 -04:00
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
load_connections (self);
|
|
|
|
|
|
2010-10-26 16:33:47 -05:00
|
|
|
*connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
2010-10-27 16:23:47 -05:00
|
|
|
while (g_hash_table_iter_next (&iter, &key, NULL))
|
|
|
|
|
g_ptr_array_add (*connections, g_strdup ((const char *) key));
|
2010-07-29 00:11:21 -04:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-13 17:20:06 -06:00
|
|
|
NMSettingsConnection *
|
|
|
|
|
nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid)
|
2011-04-22 11:55:52 -05:00
|
|
|
{
|
2012-01-13 17:20:06 -06:00
|
|
|
NMSettingsPrivate *priv;
|
|
|
|
|
NMSettingsConnection *candidate;
|
2011-04-22 11:55:52 -05:00
|
|
|
GHashTableIter iter;
|
2012-01-13 17:20:06 -06:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
|
|
|
|
|
g_return_val_if_fail (uuid != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2011-04-22 11:55:52 -05:00
|
|
|
|
|
|
|
|
load_connections (self);
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
|
2012-01-13 17:20:06 -06:00
|
|
|
if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
|
|
|
|
|
return candidate;
|
2011-04-22 11:55:52 -05:00
|
|
|
}
|
|
|
|
|
|
2012-01-13 17:20:06 -06:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
impl_settings_get_connection_by_uuid (NMSettings *self,
|
|
|
|
|
const char *uuid,
|
|
|
|
|
char **out_object_path,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsConnection *connection = NULL;
|
|
|
|
|
|
|
|
|
|
connection = nm_settings_get_connection_by_uuid (self, uuid);
|
|
|
|
|
if (connection)
|
|
|
|
|
*out_object_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
|
|
|
|
|
else {
|
2011-04-22 11:55:52 -05:00
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"No connection with the UUID was found.");
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-13 17:20:06 -06:00
|
|
|
return !!connection;
|
2011-04-22 11:55:52 -05:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
static int
|
|
|
|
|
connection_sort (gconstpointer pa, gconstpointer pb)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *a = NM_CONNECTION (pa);
|
|
|
|
|
NMSettingConnection *con_a;
|
|
|
|
|
NMConnection *b = NM_CONNECTION (pb);
|
|
|
|
|
NMSettingConnection *con_b;
|
2011-03-02 15:08:17 +01:00
|
|
|
guint64 ts_a, ts_b;
|
2010-10-27 15:47:10 -05:00
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
con_a = nm_connection_get_setting_connection (a);
|
2010-10-27 15:47:10 -05:00
|
|
|
g_assert (con_a);
|
2011-12-05 12:27:47 +01:00
|
|
|
con_b = nm_connection_get_setting_connection (b);
|
2010-10-27 15:47:10 -05:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-02 15:08:17 +01:00
|
|
|
ts_a = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pa));
|
|
|
|
|
ts_b = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pb));
|
|
|
|
|
if (ts_a > ts_b)
|
2010-10-27 15:47:10 -05:00
|
|
|
return -1;
|
2011-03-02 15:08:17 +01:00
|
|
|
else if (ts_a == ts_b)
|
2010-10-27 15:47:10 -05:00
|
|
|
return 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
/* Returns a list of NMSettingsConnections. Caller must free the list with
|
2010-11-17 17:42:22 -06:00
|
|
|
* g_slist_free().
|
2010-10-27 15:47:10 -05:00
|
|
|
*/
|
|
|
|
|
GSList *
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_get_connections (NMSettings *self)
|
2010-10-27 15:47:10 -05:00
|
|
|
{
|
|
|
|
|
GHashTableIter iter;
|
2010-10-27 16:24:48 -05:00
|
|
|
gpointer data = NULL;
|
2010-10-27 15:47:10 -05:00
|
|
|
GSList *list = NULL;
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
|
2010-10-27 15:47:10 -05:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections);
|
2010-10-27 16:24:48 -05:00
|
|
|
while (g_hash_table_iter_next (&iter, NULL, &data))
|
|
|
|
|
list = g_slist_insert_sorted (list, data, connection_sort);
|
2010-11-17 17:42:22 -06:00
|
|
|
return list;
|
2010-10-27 15:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_get_connection_by_path (NMSettings *self, const char *path)
|
2010-07-29 00:11:21 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv;
|
2010-07-29 00:11:21 -04:00
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
|
2010-08-03 13:23:30 -04:00
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-07-29 00:11:21 -04:00
|
|
|
|
2010-08-26 18:05:33 -05:00
|
|
|
load_connections (self);
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path);
|
2010-07-29 00:11:21 -04:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
clear_unmanaged_specs (NMSettings *self)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
|
|
|
|
g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL);
|
|
|
|
|
g_slist_free (priv->unmanaged_specs);
|
|
|
|
|
priv->unmanaged_specs = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
const GSList *
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_get_unmanaged_specs (NMSettings *self)
|
2008-04-08 01:36:39 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2008-05-11 20:20:52 +00:00
|
|
|
load_connections (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
return priv->unmanaged_specs;
|
2008-04-08 01:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static NMSystemConfigInterface *
|
2010-10-27 20:05:23 -05:00
|
|
|
get_plugin (NMSettings *self, guint32 capability)
|
2008-11-14 18:24:38 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2008-11-14 18:24:38 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-24 18:25:45 -05:00
|
|
|
/* Returns an allocated string which the caller owns and must eventually free */
|
2009-06-11 00:39:12 -04:00
|
|
|
char *
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_get_hostname (NMSettings *self)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-24 18:25:45 -05:00
|
|
|
return NULL;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2008-04-22 14:48:02 +00:00
|
|
|
static void
|
|
|
|
|
plugin_connection_added (NMSystemConfigInterface *config,
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *connection,
|
2009-03-02 12:58:45 -05:00
|
|
|
gpointer user_data)
|
2007-11-21 06:24:15 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
claim_connection (NM_SETTINGS (user_data), connection, TRUE);
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static gboolean
|
2010-10-27 20:05:23 -05:00
|
|
|
find_unmanaged_device (NMSettings *self, const char *needle)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
if (!strcmp ((const char *) iter->data, needle))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
static void
|
2009-07-23 09:20:52 -04:00
|
|
|
unmanaged_specs_changed (NMSystemConfigInterface *config,
|
|
|
|
|
gpointer user_data)
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2007-11-27 19:25:46 +00:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
clear_unmanaged_specs (self);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
/* Ask all the plugins for their unmanaged specs */
|
2008-04-22 14:48:02 +00:00
|
|
|
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
2009-06-11 00:39:12 -04:00
|
|
|
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);
|
2008-04-22 14:48:02 +00:00
|
|
|
} else
|
2009-06-11 00:39:12 -04:00
|
|
|
g_free (specs_iter->data);
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
g_slist_free (specs);
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_object_notify (G_OBJECT (self), NM_SETTINGS_UNMANAGED_SPECS);
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2008-09-18 14:46:57 +00:00
|
|
|
static void
|
|
|
|
|
hostname_changed (NMSystemConfigInterface *config,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME);
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
add_plugin (NMSettings *self, NMSystemConfigInterface *plugin)
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv;
|
2008-04-22 14:48:02 +00:00
|
|
|
char *pname = NULL;
|
|
|
|
|
char *pinfo = NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_if_fail (NM_IS_SETTINGS (self));
|
2008-04-22 14:48:02 +00:00
|
|
|
g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2008-02-20 22:37:39 +00:00
|
|
|
|
2008-04-22 14:48:02 +00:00
|
|
|
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
|
|
|
|
G_CALLBACK (plugin_connection_added), self);
|
2008-09-18 14:46:57 +00:00
|
|
|
g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
nm_system_config_interface_init (plugin, NULL);
|
2008-04-22 14:48:02 +00:00
|
|
|
|
|
|
|
|
g_object_get (G_OBJECT (plugin),
|
|
|
|
|
NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
|
2008-10-01 22:31:53 +00:00
|
|
|
NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo,
|
2008-04-22 14:48:02 +00:00
|
|
|
NULL);
|
|
|
|
|
|
2010-04-23 12:13:04 +02:00
|
|
|
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);
|
2008-04-22 14:48:02 +00:00
|
|
|
g_free (pname);
|
|
|
|
|
g_free (pinfo);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static GObject *
|
|
|
|
|
find_plugin (GSList *list, const char *pname)
|
|
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
GObject *obj = NULL;
|
|
|
|
|
|
2011-03-14 01:05:51 -05:00
|
|
|
g_return_val_if_fail (pname != NULL, NULL);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
|
|
|
|
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
|
2011-09-22 10:16:07 -05:00
|
|
|
load_plugins (NMSettings *self, const char **plugins, GError **error)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2011-11-15 13:30:16 +01:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *list = NULL;
|
2011-09-22 10:16:07 -05:00
|
|
|
const char **iter;
|
2009-06-11 00:39:12 -04:00
|
|
|
gboolean success = TRUE;
|
|
|
|
|
|
2011-09-22 10:16:07 -05:00
|
|
|
for (iter = plugins; *iter; iter++) {
|
2009-06-11 00:39:12 -04:00
|
|
|
GModule *plugin;
|
|
|
|
|
char *full_name, *path;
|
2011-09-22 10:16:07 -05:00
|
|
|
const char *pname = *iter;
|
2009-06-11 00:39:12 -04:00
|
|
|
GObject *obj;
|
2011-11-15 13:30:16 +01:00
|
|
|
GObject * (*factory_func) (const char *);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2011-09-22 10:16:07 -05:00
|
|
|
/* strip leading spaces */
|
|
|
|
|
while (isblank (*pname))
|
|
|
|
|
pname++;
|
|
|
|
|
|
2011-01-12 18:12:23 -06:00
|
|
|
/* keyfile plugin built in now */
|
|
|
|
|
if (!strcmp (pname, "keyfile"))
|
|
|
|
|
continue;
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-15 13:30:16 +01:00
|
|
|
obj = (*factory_func) (priv->config_file);
|
2009-06-11 00:39:12 -04:00
|
|
|
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_slist_foreach (list, (GFunc) g_object_unref, NULL);
|
|
|
|
|
g_slist_free (list);
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-29 14:34:33 -05:00
|
|
|
#define REMOVED_ID_TAG "removed-id-tag"
|
|
|
|
|
#define UPDATED_ID_TAG "updated-id-tag"
|
|
|
|
|
#define VISIBLE_ID_TAG "visible-id-tag"
|
2011-02-11 21:29:41 -06:00
|
|
|
#define UNREG_ID_TAG "unreg-id-tag"
|
2010-10-29 14:34:33 -05:00
|
|
|
|
2010-07-29 00:11:21 -04:00
|
|
|
static void
|
2011-01-26 11:38:12 -06:00
|
|
|
connection_removed (NMSettingsConnection *obj, gpointer user_data)
|
2010-07-29 00:11:21 -04:00
|
|
|
{
|
2010-10-29 14:34:33 -05:00
|
|
|
GObject *connection = G_OBJECT (obj);
|
|
|
|
|
guint id;
|
2011-09-20 21:49:35 -05:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
g_object_ref (connection);
|
|
|
|
|
|
2010-10-29 14:34:33 -05:00
|
|
|
/* 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);
|
|
|
|
|
|
2011-09-20 21:49:35 -05:00
|
|
|
/* Forget about the connection internally */
|
2010-10-29 14:34:33 -05:00
|
|
|
g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections,
|
|
|
|
|
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)));
|
2010-10-29 22:05:23 -05:00
|
|
|
|
|
|
|
|
/* Re-emit for listeners like NMPolicy */
|
2011-02-11 21:29:41 -06:00
|
|
|
g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection);
|
2010-10-29 14:34:33 -05:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-11 21:29:41 -06:00
|
|
|
static void
|
|
|
|
|
connection_unregister (NMSettingsConnection *obj, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data);
|
|
|
|
|
GObject *connection = G_OBJECT (obj);
|
|
|
|
|
guint id;
|
|
|
|
|
|
|
|
|
|
/* Make sure it's unregistered from the bus now that's removed */
|
|
|
|
|
dbus_g_connection_unregister_g_object (priv->bus, connection);
|
|
|
|
|
|
|
|
|
|
id = GPOINTER_TO_UINT (g_object_get_data (connection, UNREG_ID_TAG));
|
|
|
|
|
if (id)
|
|
|
|
|
g_signal_handler_disconnect (connection, id);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
static void
|
2011-01-26 11:38:12 -06:00
|
|
|
connection_updated (NMSettingsConnection *connection, gpointer user_data)
|
2010-10-27 15:47:10 -05:00
|
|
|
{
|
2010-10-29 22:05:23 -05:00
|
|
|
/* Re-emit for listeners like NMPolicy */
|
2010-10-27 20:05:23 -05:00
|
|
|
g_signal_emit (NM_SETTINGS (user_data),
|
2010-10-27 15:47:10 -05:00
|
|
|
signals[CONNECTION_UPDATED],
|
|
|
|
|
0,
|
|
|
|
|
connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2011-01-26 11:38:12 -06:00
|
|
|
connection_visibility_changed (NMSettingsConnection *connection,
|
2010-10-27 16:50:09 -05:00
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
2010-10-27 15:47:10 -05:00
|
|
|
{
|
2010-10-29 22:05:23 -05:00
|
|
|
/* Re-emit for listeners like NMPolicy */
|
2010-10-27 20:05:23 -05:00
|
|
|
g_signal_emit (NM_SETTINGS (user_data),
|
2010-10-27 15:47:10 -05:00
|
|
|
signals[CONNECTION_VISIBILITY_CHANGED],
|
|
|
|
|
0,
|
|
|
|
|
connection);
|
2010-07-29 00:11:21 -04:00
|
|
|
}
|
|
|
|
|
|
2011-06-28 15:48:12 +02:00
|
|
|
static void
|
|
|
|
|
secret_agent_registered (NMAgentManager *agent_mgr,
|
|
|
|
|
NMSecretAgent *agent,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
/* Re-emit for listeners like NMPolicy */
|
|
|
|
|
g_signal_emit (NM_SETTINGS (user_data),
|
|
|
|
|
signals[AGENT_REGISTERED],
|
|
|
|
|
0,
|
|
|
|
|
agent);
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-18 22:43:37 -05:00
|
|
|
#define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_GATEWAY "gateway"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_COOKIE "cookie"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_GWCERT "gwcert"
|
2011-05-19 23:41:28 +01:00
|
|
|
#define NM_OPENCONNECT_KEY_XMLCONFIG "xmlconfig"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_LASTHOST "lasthost"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_AUTOCONNECT "autoconnect"
|
|
|
|
|
#define NM_OPENCONNECT_KEY_CERTSIGS "certsigs"
|
2011-05-18 22:43:37 -05:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
openconnect_migrate_hack (NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMSettingVPN *s_vpn;
|
|
|
|
|
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NOT_SAVED;
|
|
|
|
|
|
|
|
|
|
/* Huge hack. There were some openconnect changes that needed to happen
|
|
|
|
|
* pretty late, too late to get into distros. Migration has already
|
|
|
|
|
* happened for many people, and their secret flags are wrong. But we
|
|
|
|
|
* don't want to requrie re-migration, so we have to fix it up here. Ugh.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
s_vpn = nm_connection_get_setting_vpn (connection);
|
|
|
|
|
if (s_vpn == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0 (nm_setting_vpn_get_service_type (s_vpn), NM_DBUS_SERVICE_OPENCONNECT) == 0) {
|
2011-05-19 23:41:28 +01:00
|
|
|
/* These are different for every login session, and should not be stored */
|
2011-05-18 22:43:37 -05:00
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GATEWAY, flags, NULL);
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_COOKIE, flags, NULL);
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GWCERT, flags, NULL);
|
2011-05-19 23:41:28 +01:00
|
|
|
|
|
|
|
|
/* These are purely internal data for the auth-dialog, and should be stored */
|
|
|
|
|
flags = 0;
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_XMLCONFIG, flags, NULL);
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_LASTHOST, flags, NULL);
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_AUTOCONNECT, flags, NULL);
|
|
|
|
|
nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_CERTSIGS, flags, NULL);
|
2011-05-18 22:43:37 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
claim_connection (NMSettings *self,
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *connection,
|
2009-07-23 09:20:52 -04:00
|
|
|
gboolean do_export)
|
2008-04-22 14:48:02 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-10-27 15:47:10 -05:00
|
|
|
static guint32 ec_counter = 0;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer data;
|
|
|
|
|
char *path;
|
2010-10-29 14:34:33 -05:00
|
|
|
guint id;
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
|
2010-11-17 17:33:00 -06:00
|
|
|
g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
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",
|
2010-10-27 15:47:10 -05:00
|
|
|
g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
|
|
|
|
|
error->message, error->code);
|
|
|
|
|
g_error_free (error);
|
2007-11-27 19:25:46 +00:00
|
|
|
return;
|
2010-10-27 15:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
2011-03-02 15:08:17 +01:00
|
|
|
/* Read timestamp from look-aside file and put it into the connection's data */
|
|
|
|
|
nm_settings_connection_read_and_fill_timestamp (connection);
|
|
|
|
|
|
2011-05-27 17:32:40 +02:00
|
|
|
/* Read seen-bssids from look-aside file and put it into the connection's data */
|
|
|
|
|
nm_settings_connection_read_and_fill_seen_bssids (connection);
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
/* Ensure it's initial visibility is up-to-date */
|
2011-01-26 11:38:12 -06:00
|
|
|
nm_settings_connection_recheck_visibility (connection);
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2011-05-18 22:43:37 -05:00
|
|
|
/* Evil openconnect migration hack */
|
|
|
|
|
openconnect_migrate_hack (NM_CONNECTION (connection));
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED,
|
2010-10-29 14:34:33 -05:00
|
|
|
G_CALLBACK (connection_removed),
|
|
|
|
|
self);
|
|
|
|
|
g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id));
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2011-02-11 21:29:41 -06:00
|
|
|
id = g_signal_connect (connection, "unregister",
|
|
|
|
|
G_CALLBACK (connection_unregister),
|
|
|
|
|
self);
|
|
|
|
|
g_object_set_data (G_OBJECT (connection), UNREG_ID_TAG, GUINT_TO_POINTER (id));
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED,
|
2010-10-29 14:34:33 -05:00
|
|
|
G_CALLBACK (connection_updated),
|
|
|
|
|
self);
|
|
|
|
|
g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id));
|
2010-10-27 15:47:10 -05:00
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
id = g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
|
2010-10-29 14:34:33 -05:00
|
|
|
G_CALLBACK (connection_visibility_changed),
|
|
|
|
|
self);
|
|
|
|
|
g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id));
|
2010-10-26 16:33:47 -05:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
/* 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.
|
|
|
|
|
*/
|
2010-10-27 16:20:41 -05:00
|
|
|
if (priv->connections_loaded) {
|
|
|
|
|
/* Internal added signal */
|
2010-10-27 15:47:10 -05:00
|
|
|
g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
|
2010-10-27 16:20:41 -05:00
|
|
|
|
|
|
|
|
/* Exported D-Bus signal */
|
|
|
|
|
g_signal_emit (self, signals[NEW_CONNECTION], 0, connection);
|
|
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
remove_default_wired_connection (NMSettings *self,
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *connection,
|
2010-10-26 16:33:47 -05:00
|
|
|
gboolean do_signal)
|
2008-04-08 01:36:39 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-10-27 15:47:10 -05:00
|
|
|
const char *path = nm_connection_get_path (NM_CONNECTION (connection));
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
if (g_hash_table_lookup (priv->connections, path)) {
|
2011-09-20 21:49:35 -05:00
|
|
|
if (do_signal)
|
|
|
|
|
g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_CONNECTION_REMOVED);
|
2010-10-27 15:47:10 -05:00
|
|
|
g_hash_table_remove (priv->connections, path);
|
2008-04-08 01:36:39 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
static NMSettingsConnection *
|
2010-10-27 20:05:23 -05:00
|
|
|
add_new_connection (NMSettings *self,
|
2009-07-23 09:20:52 -04:00
|
|
|
NMConnection *connection,
|
|
|
|
|
GError **error)
|
2008-04-22 14:48:02 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2008-07-16 07:37:10 +00:00
|
|
|
GSList *iter;
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *added = NULL;
|
2011-02-09 18:41:48 -06:00
|
|
|
GHashTableIter citer;
|
|
|
|
|
NMConnection *candidate = NULL;
|
|
|
|
|
|
|
|
|
|
/* Make sure a connection with this UUID doesn't already exist */
|
|
|
|
|
g_hash_table_iter_init (&citer, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) {
|
|
|
|
|
if (g_strcmp0 (nm_connection_get_uuid (connection),
|
|
|
|
|
nm_connection_get_uuid (candidate)) == 0) {
|
|
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_UUID_EXISTS,
|
|
|
|
|
"A connection with this UUID already exists.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-10-29 14:34:33 -05:00
|
|
|
|
|
|
|
|
/* 1) plugin writes the NMConnection to disk
|
2011-01-26 11:38:12 -06:00
|
|
|
* 2) plugin creates a new NMSettingsConnection subclass with the settings
|
2010-10-29 14:34:33 -05:00
|
|
|
* from the NMConnection and returns it to the settings service
|
2011-01-26 11:38:12 -06:00
|
|
|
* 3) settings service exports the new NMSettingsConnection subclass
|
2010-10-29 14:34:33 -05:00
|
|
|
* 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
|
|
|
|
|
*/
|
2010-10-29 22:10:32 -05:00
|
|
|
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
|
2010-10-29 23:13:57 -05:00
|
|
|
GError *add_error = NULL;
|
2009-03-02 12:58:45 -05:00
|
|
|
|
2010-10-29 22:10:32 -05:00
|
|
|
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;
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
2009-03-02 12:58:45 -05:00
|
|
|
|
2011-11-15 13:43:29 +01:00
|
|
|
static gboolean
|
|
|
|
|
secrets_filter_cb (NMSetting *setting,
|
|
|
|
|
const char *secret,
|
|
|
|
|
NMSettingSecretFlags flags,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data);
|
|
|
|
|
|
|
|
|
|
/* Returns TRUE to remove the secret */
|
|
|
|
|
|
|
|
|
|
/* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */
|
|
|
|
|
if ( (flags == NM_SETTING_SECRET_FLAG_NONE)
|
|
|
|
|
&& (filter_flags == NM_SETTING_SECRET_FLAG_NONE))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* Otherwise if the secret has at least one of the desired flags keep it */
|
|
|
|
|
return (flags & filter_flags) ? FALSE : TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
send_agent_owned_secrets (NMSettings *self,
|
|
|
|
|
NMSettingsConnection *connection,
|
|
|
|
|
gulong caller_uid)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *for_agent;
|
|
|
|
|
|
|
|
|
|
/* Dupe the connection so we can clear out non-agent-owned secrets,
|
|
|
|
|
* as agent-owned secrets are the only ones we send back to be saved.
|
|
|
|
|
* Only send secrets to agents of the same UID that called update too.
|
|
|
|
|
*/
|
|
|
|
|
for_agent = nm_connection_duplicate (NM_CONNECTION (connection));
|
|
|
|
|
nm_connection_clear_secrets_with_flags (for_agent,
|
|
|
|
|
secrets_filter_cb,
|
|
|
|
|
GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
|
|
|
|
|
nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, caller_uid);
|
|
|
|
|
g_object_unref (for_agent);
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2010-11-17 17:53:37 -06:00
|
|
|
pk_add_cb (NMAuthChain *chain,
|
|
|
|
|
GError *chain_error,
|
|
|
|
|
DBusGMethodInvocation *context,
|
|
|
|
|
gpointer user_data)
|
2009-07-23 09:20:52 -04:00
|
|
|
{
|
2010-11-17 17:53:37 -06:00
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
NMAuthCallResult result;
|
2009-07-23 09:20:52 -04:00
|
|
|
GError *error = NULL, *add_error = NULL;
|
2010-11-17 17:53:37 -06:00
|
|
|
NMConnection *connection;
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *added = NULL;
|
2011-01-10 23:39:12 -06:00
|
|
|
NMSettingsAddCallback callback;
|
|
|
|
|
gpointer callback_data;
|
2011-11-15 13:43:29 +01:00
|
|
|
gulong caller_uid;
|
2011-02-11 17:06:57 -06:00
|
|
|
const char *perm;
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
priv->auths = g_slist_remove (priv->auths, chain);
|
2009-10-21 14:19:01 -07:00
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
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;
|
2009-03-02 12:58:45 -05:00
|
|
|
}
|
|
|
|
|
|
2011-02-11 17:06:57 -06:00
|
|
|
perm = nm_auth_chain_get_data (chain, "perm");
|
|
|
|
|
g_assert (perm);
|
|
|
|
|
result = nm_auth_chain_get_result (chain, perm);
|
2010-11-17 17:53:37 -06:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
/* Caller didn't successfully authenticate */
|
2010-11-17 17:53:37 -06:00
|
|
|
if (result != NM_AUTH_CALL_RESULT_YES) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Insufficient privileges.");
|
2010-11-17 17:53:37 -06:00
|
|
|
goto done;
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
connection = nm_auth_chain_get_data (chain, "connection");
|
2011-02-11 17:06:57 -06:00
|
|
|
g_assert (connection);
|
2010-11-17 17:53:37 -06:00
|
|
|
added = add_new_connection (self, connection, &add_error);
|
2011-01-10 23:39:12 -06:00
|
|
|
if (!added) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_ADD_FAILED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"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);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
done:
|
2011-01-10 23:39:12 -06:00
|
|
|
callback = nm_auth_chain_get_data (chain, "callback");
|
|
|
|
|
callback_data = nm_auth_chain_get_data (chain, "callback-data");
|
2011-11-15 13:43:29 +01:00
|
|
|
caller_uid = nm_auth_chain_get_data_ulong (chain, "caller-uid");
|
2011-01-10 23:39:12 -06:00
|
|
|
|
|
|
|
|
callback (self, added, error, context, callback_data);
|
2010-11-17 17:53:37 -06:00
|
|
|
|
2011-11-15 13:43:29 +01:00
|
|
|
/* Send agent-owned secrets to the agents */
|
|
|
|
|
if (!error && added)
|
|
|
|
|
send_agent_owned_secrets (self, added, caller_uid);
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_clear_error (&error);
|
2010-11-17 17:53:37 -06:00
|
|
|
nm_auth_chain_unref (chain);
|
2009-03-02 12:58:45 -05:00
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2011-01-10 23:39:12 -06:00
|
|
|
add_cb (NMSettings *self,
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *connection,
|
2011-01-10 23:39:12 -06:00
|
|
|
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)
|
2009-03-02 12:58:45 -05:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2011-02-11 17:06:57 -06:00
|
|
|
NMSettingConnection *s_con;
|
2010-11-17 17:53:37 -06:00
|
|
|
NMAuthChain *chain;
|
2011-02-09 18:41:48 -06:00
|
|
|
GError *error = NULL, *tmp_error = NULL;
|
2011-02-11 17:06:57 -06:00
|
|
|
gulong caller_uid = G_MAXULONG;
|
|
|
|
|
char *error_desc = NULL;
|
|
|
|
|
const char *perm;
|
2011-02-09 18:41:48 -06:00
|
|
|
|
|
|
|
|
/* Connection must be valid, of course */
|
|
|
|
|
if (!nm_connection_verify (connection, &tmp_error)) {
|
|
|
|
|
error = g_error_new (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"The connection was invalid: %s",
|
|
|
|
|
tmp_error ? tmp_error->message : "(unknown)");
|
|
|
|
|
g_error_free (tmp_error);
|
|
|
|
|
callback (self, NULL, error, context, user_data);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2008-09-18 14:46:57 +00:00
|
|
|
/* Do any of the plugins support adding? */
|
2009-07-23 09:20:52 -04:00
|
|
|
if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"None of the registered plugins support add.");
|
2011-01-10 23:39:12 -06:00
|
|
|
callback (self, NULL, error, context, user_data);
|
2009-07-23 09:20:52 -04:00
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
2008-05-09 06:33:30 +00:00
|
|
|
}
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2011-02-11 17:06:57 -06:00
|
|
|
/* Get the caller's UID */
|
|
|
|
|
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);
|
|
|
|
|
callback (self, NULL, error, context, user_data);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
callback (self, NULL, error, context, user_data);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Caller is allowed to add this connection */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the caller is the only user in the connection's permissions, then
|
|
|
|
|
* we use the 'modify.own' permission instead of 'modify.system'. If the
|
|
|
|
|
* request affects more than just the caller, require 'modify.system'.
|
|
|
|
|
*/
|
2011-12-05 12:27:47 +01:00
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
2011-02-11 17:06:57 -06:00
|
|
|
g_assert (s_con);
|
|
|
|
|
if (nm_setting_connection_get_num_permissions (s_con) == 1)
|
|
|
|
|
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
|
|
|
|
|
else
|
|
|
|
|
perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
|
|
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
/* Otherwise validate the user request */
|
2011-05-18 22:20:24 -05:00
|
|
|
chain = nm_auth_chain_new (context, NULL, pk_add_cb, self);
|
2010-11-17 17:53:37 -06:00
|
|
|
g_assert (chain);
|
|
|
|
|
priv->auths = g_slist_append (priv->auths, chain);
|
2011-02-11 17:06:57 -06:00
|
|
|
nm_auth_chain_add_call (chain, perm, TRUE);
|
|
|
|
|
nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL);
|
2011-01-10 23:39:12 -06:00
|
|
|
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);
|
2011-11-15 13:43:29 +01:00
|
|
|
nm_auth_chain_set_data_ulong (chain, "caller-uid", caller_uid);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2010-07-29 00:11:21 -04:00
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2010-11-17 17:44:33 -06:00
|
|
|
pk_hostname_cb (NMAuthChain *chain,
|
|
|
|
|
GError *chain_error,
|
|
|
|
|
DBusGMethodInvocation *context,
|
|
|
|
|
gpointer user_data)
|
2008-09-18 14:46:57 +00:00
|
|
|
{
|
2010-11-17 17:44:33 -06:00
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
gboolean success = FALSE;
|
2009-07-23 09:20:52 -04:00
|
|
|
GError *error = NULL;
|
2008-09-18 14:46:57 +00:00
|
|
|
GSList *iter;
|
2010-11-17 17:44:33 -06:00
|
|
|
const char *hostname;
|
|
|
|
|
|
|
|
|
|
priv->auths = g_slist_remove (priv->auths, chain);
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
/* If our NMSettingsConnection is already gone, do nothing */
|
2010-11-17 17:44:33 -06:00
|
|
|
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;
|
2009-10-21 14:19:01 -07:00
|
|
|
}
|
|
|
|
|
|
2011-02-11 11:32:57 -06:00
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
/* Caller didn't successfully authenticate */
|
2010-11-17 17:54:04 -06:00
|
|
|
if (result != NM_AUTH_CALL_RESULT_YES) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_NOT_PRIVILEGED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Insufficient privileges.");
|
2010-11-17 17:44:33 -06:00
|
|
|
goto done;
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
2008-09-18 14:46:57 +00:00
|
|
|
|
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 */
|
2010-11-17 17:44:33 -06:00
|
|
|
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) {
|
2008-09-18 14:46:57 +00:00
|
|
|
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) {
|
2010-11-17 17:44:33 -06:00
|
|
|
g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL);
|
2008-09-18 14:46:57 +00:00
|
|
|
success = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
if (!success) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Saving the hostname failed.");
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
done:
|
|
|
|
|
if (error)
|
|
|
|
|
dbus_g_method_return_error (context, error);
|
|
|
|
|
else
|
|
|
|
|
dbus_g_method_return (context);
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_clear_error (&error);
|
2010-11-17 17:44:33 -06:00
|
|
|
nm_auth_chain_unref (chain);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
impl_settings_save_hostname (NMSettings *self,
|
2009-07-23 09:20:52 -04:00
|
|
|
const char *hostname,
|
|
|
|
|
DBusGMethodInvocation *context)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-11-17 17:44:33 -06:00
|
|
|
NMAuthChain *chain;
|
2009-07-23 09:20:52 -04:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
/* Do any of the plugins support setting the hostname? */
|
|
|
|
|
if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"None of the registered plugins support setting the hostname.");
|
|
|
|
|
dbus_g_method_return_error (context, error);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
/* Otherwise validate the user request */
|
2011-05-18 22:20:24 -05:00
|
|
|
chain = nm_auth_chain_new (context, NULL, pk_hostname_cb, self);
|
2010-11-17 17:44:33 -06:00
|
|
|
g_assert (chain);
|
|
|
|
|
priv->auths = g_slist_append (priv->auths, chain);
|
2011-02-11 11:32:57 -06:00
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE);
|
2010-11-17 17:44:33 -06:00
|
|
|
nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free);
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
static gboolean
|
2011-10-18 13:48:45 +02:00
|
|
|
have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-07-23 09:20:52 -04:00
|
|
|
GHashTableIter iter;
|
2010-10-27 15:47:10 -05:00
|
|
|
gpointer data;
|
2009-07-09 11:06:31 -04:00
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingWired *s_wired;
|
2011-10-14 10:13:49 -04:00
|
|
|
NMSettingInfiniband *s_infiniband;
|
2009-07-09 11:06:31 -04:00
|
|
|
const GByteArray *setting_mac;
|
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
2009-07-09 11:06:31 -04:00
|
|
|
g_return_val_if_fail (mac != NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
/* Find a wired connection locked to the given MAC address, if any */
|
2010-10-26 16:33:47 -05:00
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
2010-10-27 15:47:10 -05:00
|
|
|
while (g_hash_table_iter_next (&iter, NULL, &data)) {
|
|
|
|
|
NMConnection *connection = NM_CONNECTION (data);
|
2011-12-07 13:15:18 +01:00
|
|
|
const char *ctype, *iface;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-04-19 00:26:07 -05:00
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
ctype = nm_setting_connection_get_connection_type (s_con);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-12-07 13:15:18 +01:00
|
|
|
iface = nm_connection_get_virtual_iface_name (connection);
|
|
|
|
|
if (iface) {
|
|
|
|
|
if (!strcmp (iface, nm_device_get_iface (device))) {
|
2011-10-18 13:48:45 +02:00
|
|
|
ret = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
} else
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-19 00:26:07 -05:00
|
|
|
if ( strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)
|
2011-10-14 10:13:49 -04:00
|
|
|
&& strcmp (ctype, NM_SETTING_INFINIBAND_SETTING_NAME)
|
2011-04-19 00:26:07 -05:00
|
|
|
&& strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME))
|
2009-07-09 11:06:31 -04:00
|
|
|
continue;
|
|
|
|
|
|
2011-04-19 00:26:07 -05:00
|
|
|
s_wired = nm_connection_get_setting_wired (connection);
|
2011-10-14 10:13:49 -04:00
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
/* No wired setting; therefore the PPPoE connection applies to any device */
|
2011-04-19 00:26:07 -05:00
|
|
|
if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) {
|
2009-07-09 11:06:31 -04:00
|
|
|
ret = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
g_assert (s_wired != NULL || s_infiniband != NULL);
|
|
|
|
|
|
|
|
|
|
setting_mac = s_wired ?
|
|
|
|
|
nm_setting_wired_get_mac_address (s_wired) :
|
|
|
|
|
nm_setting_infiniband_get_mac_address (s_infiniband);
|
2009-07-09 11:06:31 -04:00
|
|
|
if (setting_mac) {
|
|
|
|
|
/* A connection mac-locked to this device */
|
2011-10-14 10:13:49 -04:00
|
|
|
if (mac->len == setting_mac->len &&
|
|
|
|
|
!memcmp (setting_mac->data, mac->data, mac->len)) {
|
2009-07-09 11:06:31 -04:00
|
|
|
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
|
2011-10-14 10:13:49 -04:00
|
|
|
is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac, int hwaddr_type)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-07-09 11:06:31 -04:00
|
|
|
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.");
|
2009-07-09 11:06:31 -04:00
|
|
|
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++) {
|
2011-10-14 10:13:49 -04:00
|
|
|
guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX];
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
if (strcmp (g_strstrip (*iter), "*") == 0) {
|
2010-09-27 11:08:03 +02:00
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer);
|
|
|
|
|
if (candidate && !memcmp (mac->data, candidate, mac->len)) {
|
2009-07-09 11:06:31 -04:00
|
|
|
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,
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-07-09 11:06:31 -04:00
|
|
|
NMSettingConnection *s_con;
|
2011-10-14 10:13:49 -04:00
|
|
|
int hwaddr_type;
|
2009-07-09 11:06:31 -04:00
|
|
|
char *tmp;
|
|
|
|
|
GKeyFile *config;
|
|
|
|
|
char **list, **iter, **updated;
|
|
|
|
|
gboolean found = FALSE;
|
2009-11-14 11:26:38 -08:00
|
|
|
gsize len = 0, i;
|
2009-07-09 11:06:31 -04:00
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
s_con = nm_connection_get_setting_connection (NM_CONNECTION (wired));
|
2009-07-09 11:06:31 -04:00
|
|
|
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;
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
if (nm_connection_get_setting_wired (NM_CONNECTION (wired)))
|
|
|
|
|
hwaddr_type = ARPHRD_ETHER;
|
|
|
|
|
else if (nm_connection_get_setting_infiniband (NM_CONNECTION (wired)))
|
|
|
|
|
hwaddr_type = ARPHRD_INFINIBAND;
|
|
|
|
|
else
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
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++) {
|
2011-10-14 10:13:49 -04:00
|
|
|
guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX];
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
if (strcmp (g_strstrip (*iter), "*") == 0) {
|
2010-09-27 11:08:03 +02:00
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer);
|
|
|
|
|
if (candidate && !memcmp (mac->data, candidate, mac->len)) {
|
2009-07-09 11:06:31 -04:00
|
|
|
found = TRUE;
|
2010-09-27 11:08:03 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add this device's MAC to the list */
|
|
|
|
|
if (!found) {
|
2011-10-14 10:13:49 -04:00
|
|
|
tmp = nm_utils_hwaddr_ntoa (mac->data, hwaddr_type);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2009-11-14 11:26:38 -08:00
|
|
|
/* New list; size + 1 for the new element, + 1 again for ending NULL */
|
2009-07-09 11:06:31 -04:00
|
|
|
updated = g_malloc0 (sizeof (char*) * (len + 2));
|
2009-11-14 11:26:38 -08:00
|
|
|
|
|
|
|
|
/* Copy original list and add new MAC */
|
|
|
|
|
for (i = 0; list && list[i]; i++)
|
|
|
|
|
updated[i] = list[i];
|
|
|
|
|
updated[i++] = tmp;
|
|
|
|
|
updated[i] = NULL;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
g_key_file_set_string_list (config,
|
|
|
|
|
"main", CONFIG_KEY_NO_AUTO_DEFAULT,
|
|
|
|
|
(const char **) updated,
|
2009-11-14 11:26:38 -08:00
|
|
|
len + 2);
|
2009-07-09 11:06:31 -04:00
|
|
|
/* 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);
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-05 17:46:16 -07:00
|
|
|
static void
|
2011-01-26 11:38:12 -06:00
|
|
|
delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data)
|
2009-10-05 17:46:16 -07:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-20 21:49:35 -05:00
|
|
|
static void
|
2009-07-09 11:06:31 -04:00
|
|
|
default_wired_try_update (NMDefaultWiredConnection *wired,
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
const char *id;
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *added;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
/* Try to move this default wired conneciton to a plugin so that it has
|
|
|
|
|
* persistent storage.
|
|
|
|
|
*/
|
|
|
|
|
|
2011-09-20 21:49:35 -05:00
|
|
|
/* Keep it alive over removal so we can re-add it if we need to */
|
|
|
|
|
g_object_ref (wired);
|
|
|
|
|
|
2011-03-08 13:41:28 +01:00
|
|
|
id = nm_connection_get_id (NM_CONNECTION (wired));
|
2009-07-09 11:06:31 -04:00
|
|
|
g_assert (id);
|
|
|
|
|
|
2011-01-26 11:38:12 -06:00
|
|
|
remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE);
|
2010-10-29 14:34:33 -05:00
|
|
|
added = add_new_connection (self, NM_CONNECTION (wired), &error);
|
|
|
|
|
if (added) {
|
2011-01-26 11:38:12 -06:00
|
|
|
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (wired), delete_cb, NULL);
|
2009-10-05 17:46:16 -07:00
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
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);
|
2011-09-20 21:49:35 -05:00
|
|
|
} else {
|
|
|
|
|
nm_log_warn (LOGD_SETTINGS, "couldn't save default wired connection '%s': %d / %s",
|
|
|
|
|
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);
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2011-09-20 21:49:35 -05:00
|
|
|
g_object_unref (wired);
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_device_added (NMSettings *self, NMDevice *device)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2011-03-30 12:02:50 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-07-09 11:06:31 -04:00
|
|
|
GByteArray *mac = NULL;
|
2012-02-21 15:03:46 -06:00
|
|
|
const guint8 *hwaddr;
|
2011-10-14 10:13:49 -04:00
|
|
|
int hwaddr_type;
|
2009-07-23 09:20:52 -04:00
|
|
|
NMDefaultWiredConnection *wired;
|
2009-07-09 11:06:31 -04:00
|
|
|
gboolean read_only = TRUE;
|
|
|
|
|
const char *id;
|
2011-03-27 16:57:14 -05:00
|
|
|
char *defname;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
if (!NM_IS_DEVICE_WIRED (device))
|
2009-07-09 11:06:31 -04:00
|
|
|
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;
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device));
|
|
|
|
|
hwaddr_type = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (device));
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
mac = g_byte_array_new ();
|
|
|
|
|
g_byte_array_append (mac, hwaddr, nm_utils_hwaddr_len (hwaddr_type));
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-18 13:48:45 +02:00
|
|
|
if ( have_connection_for_device (self, mac, device)
|
2011-10-14 10:13:49 -04:00
|
|
|
|| is_mac_auto_wired_blacklisted (self, mac, hwaddr_type))
|
2009-07-09 11:06:31 -04:00
|
|
|
goto ignore;
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
|
2009-07-09 11:06:31 -04:00
|
|
|
read_only = FALSE;
|
|
|
|
|
|
2011-03-30 12:02:50 -05:00
|
|
|
defname = nm_settings_utils_get_default_wired_name (priv->connections);
|
2011-03-27 16:57:14 -05:00
|
|
|
wired = nm_default_wired_connection_new (mac, device, defname, read_only);
|
|
|
|
|
g_free (defname);
|
2009-07-23 09:20:52 -04:00
|
|
|
if (!wired)
|
2009-07-09 11:06:31 -04:00
|
|
|
goto ignore;
|
|
|
|
|
|
2011-03-08 13:41:28 +01:00
|
|
|
id = nm_connection_get_id (NM_CONNECTION (wired));
|
2009-07-09 11:06:31 -04:00
|
|
|
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));
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self);
|
|
|
|
|
g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self);
|
2011-01-26 11:38:12 -06:00
|
|
|
claim_connection (self, NM_SETTINGS_CONNECTION (wired), TRUE);
|
2009-07-23 09:20:52 -04:00
|
|
|
g_object_unref (wired);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
ignore:
|
|
|
|
|
g_byte_array_free (mac, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_device_removed (NMSettings *self, NMDevice *device)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2009-07-23 09:20:52 -04:00
|
|
|
NMDefaultWiredConnection *connection;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
if (!NM_IS_DEVICE_WIRED (device))
|
2009-07-09 11:06:31 -04:00
|
|
|
return;
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
|
|
|
|
|
if (connection)
|
2011-01-26 11:38:12 -06:00
|
|
|
remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (connection), TRUE);
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
/***************************************************************/
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *
|
|
|
|
|
nm_settings_new (const char *config_file,
|
2011-09-22 10:16:07 -05:00
|
|
|
const char **plugins,
|
2011-01-12 18:12:23 -06:00
|
|
|
GError **error)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self;
|
|
|
|
|
NMSettingsPrivate *priv;
|
2011-01-12 18:12:23 -06:00
|
|
|
GObject *keyfile_plugin;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
self = g_object_new (NM_TYPE_SETTINGS, NULL);
|
2009-06-11 00:39:12 -04:00
|
|
|
if (!self)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
priv->config_file = g_strdup (config_file);
|
2010-10-27 16:17:44 -05:00
|
|
|
priv->dbus_mgr = nm_dbus_manager_get ();
|
|
|
|
|
priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
if (plugins) {
|
|
|
|
|
/* Load the plugins; fail if a plugin is not found. */
|
|
|
|
|
if (!load_plugins (self, plugins, error)) {
|
|
|
|
|
g_object_unref (self);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-12 18:12:23 -06:00
|
|
|
/* Add the keyfile plugin last */
|
2011-11-15 13:30:16 +01:00
|
|
|
keyfile_plugin = nm_settings_keyfile_plugin_new (config_file);
|
2011-01-12 18:12:23 -06:00
|
|
|
g_assert (keyfile_plugin);
|
|
|
|
|
add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin));
|
|
|
|
|
|
2011-02-02 20:32:15 -06:00
|
|
|
unmanaged_specs_changed (NULL, self);
|
|
|
|
|
|
2010-10-27 16:17:44 -05:00
|
|
|
dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self));
|
2009-06-11 00:39:12 -04:00
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-18 14:05:33 -06:00
|
|
|
static void
|
|
|
|
|
nm_settings_init (NMSettings *self)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
|
|
|
|
|
|
|
|
|
priv->session_monitor = nm_session_monitor_get ();
|
2011-01-27 10:41:02 -06:00
|
|
|
|
|
|
|
|
/* 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 ();
|
2011-06-28 15:48:12 +02:00
|
|
|
|
|
|
|
|
g_signal_connect (priv->agent_mgr, "agent-registered", G_CALLBACK (secret_agent_registered), self);
|
2010-11-18 14:05:33 -06:00
|
|
|
}
|
|
|
|
|
|
2009-10-21 14:19:01 -07:00
|
|
|
static void
|
|
|
|
|
dispose (GObject *object)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self = NM_SETTINGS (object);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-10-21 14:19:01 -07:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
for (iter = priv->auths; iter; iter = g_slist_next (iter))
|
|
|
|
|
nm_auth_chain_unref ((NMAuthChain *) iter->data);
|
|
|
|
|
g_slist_free (priv->auths);
|
|
|
|
|
|
2010-10-27 16:17:44 -05:00
|
|
|
g_object_unref (priv->dbus_mgr);
|
|
|
|
|
|
2010-11-18 14:05:33 -06:00
|
|
|
g_object_unref (priv->session_monitor);
|
2011-01-27 10:41:02 -06:00
|
|
|
g_object_unref (priv->agent_mgr);
|
2010-11-18 14:05:33 -06:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
|
2009-10-21 14:19:01 -07:00
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
|
|
|
|
finalize (GObject *object)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self = NM_SETTINGS (object);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2010-10-26 16:33:47 -05:00
|
|
|
g_hash_table_destroy (priv->connections);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
|
|
|
|
clear_unmanaged_specs (self);
|
|
|
|
|
|
|
|
|
|
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
|
|
|
|
|
g_slist_free (priv->plugins);
|
|
|
|
|
|
|
|
|
|
g_free (priv->config_file);
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object, guint prop_id,
|
|
|
|
|
GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *self = NM_SETTINGS (object);
|
2009-07-23 09:20:52 -04:00
|
|
|
const GSList *specs, *iter;
|
|
|
|
|
GSList *copy = NULL;
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_UNMANAGED_SPECS:
|
2010-10-27 20:05:23 -05:00
|
|
|
specs = nm_settings_get_unmanaged_specs (self);
|
2009-07-23 09:20:52 -04:00
|
|
|
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;
|
2010-08-03 13:23:30 -04:00
|
|
|
case PROP_HOSTNAME:
|
2010-10-27 20:05:23 -05:00
|
|
|
g_value_take_string (value, nm_settings_get_hostname (self));
|
2009-07-23 09:20:52 -04:00
|
|
|
|
|
|
|
|
/* Don't ever pass NULL through D-Bus */
|
|
|
|
|
if (!g_value_get_string (value))
|
|
|
|
|
g_value_set_static_string (value, "");
|
|
|
|
|
break;
|
2010-08-03 13:23:30 -04:00
|
|
|
case PROP_CAN_MODIFY:
|
2009-07-23 09:20:52 -04:00
|
|
|
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
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_class_init (NMSettingsClass *class)
|
2009-07-23 09:20:52 -04:00
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_type_class_add_private (class, sizeof (NMSettingsPrivate));
|
2009-07-23 09:20:52 -04:00
|
|
|
|
|
|
|
|
/* virtual methods */
|
|
|
|
|
object_class->notify = notify;
|
|
|
|
|
object_class->get_property = get_property;
|
2009-10-21 14:19:01 -07:00
|
|
|
object_class->dispose = dispose;
|
2009-07-23 09:20:52 -04:00
|
|
|
object_class->finalize = finalize;
|
|
|
|
|
|
|
|
|
|
/* properties */
|
2010-07-29 00:11:21 -04:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_UNMANAGED_SPECS,
|
2010-10-27 20:05:23 -05:00
|
|
|
g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Unamanged device specs",
|
|
|
|
|
"Unmanaged device specs",
|
|
|
|
|
DBUS_TYPE_G_LIST_OF_STRING,
|
|
|
|
|
G_PARAM_READABLE));
|
|
|
|
|
|
2010-08-03 13:23:30 -04:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_HOSTNAME,
|
2010-10-27 20:05:23 -05:00
|
|
|
g_param_spec_string (NM_SETTINGS_HOSTNAME,
|
2010-08-03 13:23:30 -04:00
|
|
|
"Hostname",
|
|
|
|
|
"Persistent hostname",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE));
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2010-08-03 13:23:30 -04:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CAN_MODIFY,
|
2010-10-27 20:05:23 -05:00
|
|
|
g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY,
|
2010-08-03 13:23:30 -04:00
|
|
|
"CanModify",
|
|
|
|
|
"Can modify anything (hostname, connections, etc)",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE));
|
2009-07-23 09:20:52 -04:00
|
|
|
|
|
|
|
|
/* signals */
|
|
|
|
|
signals[PROPERTIES_CHANGED] =
|
|
|
|
|
g_signal_new ("properties-changed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, properties_changed),
|
2009-07-23 09:20:52 -04:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__BOXED,
|
|
|
|
|
G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
|
2010-10-27 15:47:10 -05:00
|
|
|
signals[CONNECTION_ADDED] =
|
2011-01-26 11:38:12 -06:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
2010-10-27 15:47:10 -05:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, connection_added),
|
2010-10-27 15:47:10 -05:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
signals[CONNECTION_UPDATED] =
|
2011-01-26 11:38:12 -06:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
2010-10-27 15:47:10 -05:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, connection_updated),
|
2010-10-27 15:47:10 -05:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
signals[CONNECTION_REMOVED] =
|
2011-01-26 11:38:12 -06:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
|
2010-10-27 15:47:10 -05:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, connection_removed),
|
2010-10-27 15:47:10 -05:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
signals[CONNECTION_VISIBILITY_CHANGED] =
|
2011-01-26 11:38:12 -06:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
|
2010-08-03 13:23:30 -04:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed),
|
2010-08-03 13:23:30 -04:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
signals[CONNECTIONS_LOADED] =
|
2011-01-26 11:38:12 -06:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED,
|
2010-10-27 15:47:10 -05:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2010-10-27 20:05:23 -05:00
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, connections_loaded),
|
2010-10-27 15:47:10 -05:00
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
|
2011-06-28 15:48:12 +02:00
|
|
|
signals[AGENT_REGISTERED] =
|
|
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
G_STRUCT_OFFSET (NMSettingsClass, agent_registered),
|
|
|
|
|
NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
|
2010-10-27 16:20:41 -05:00
|
|
|
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,
|
2011-02-11 22:03:10 -06:00
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
2010-10-27 16:20:41 -05:00
|
|
|
|
2010-10-27 20:38:26 -05:00
|
|
|
dbus_g_error_domain_register (NM_SETTINGS_ERROR,
|
2010-07-29 21:58:16 -04:00
|
|
|
NM_DBUS_IFACE_SETTINGS,
|
2010-10-27 20:38:26 -05:00
|
|
|
NM_TYPE_SETTINGS_ERROR);
|
2010-02-15 17:26:55 -08:00
|
|
|
|
|
|
|
|
/* And register all the settings errors with D-Bus */
|
2010-04-22 12:27:31 -07:00
|
|
|
dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR);
|
2010-02-15 17:26:55 -08:00
|
|
|
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);
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info);
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|