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
|
|
|
*/
|
|
|
|
|
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-default.h"
|
2011-03-14 01:00:56 -05:00
|
|
|
|
2016-05-16 18:08:08 +02:00
|
|
|
#include "nm-settings.h"
|
|
|
|
|
|
2008-10-01 22:59:21 +00:00
|
|
|
#include <unistd.h>
|
2014-10-21 10:31:30 +02:00
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <errno.h>
|
2008-10-01 22:59:21 +00:00
|
|
|
#include <string.h>
|
2009-06-11 00:39:12 -04:00
|
|
|
#include <gmodule.h>
|
2010-11-18 12:53:24 -06:00
|
|
|
#include <pwd.h>
|
2010-02-15 17:26:55 -08:00
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
#if HAVE_SELINUX
|
|
|
|
|
#include <selinux/selinux.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-06-01 12:31:36 +02:00
|
|
|
#include "nm-common-macros.h"
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-dbus-interface.h"
|
|
|
|
|
#include "nm-connection.h"
|
|
|
|
|
#include "nm-setting-8021x.h"
|
|
|
|
|
#include "nm-setting-bluetooth.h"
|
|
|
|
|
#include "nm-setting-cdma.h"
|
|
|
|
|
#include "nm-setting-connection.h"
|
|
|
|
|
#include "nm-setting-gsm.h"
|
|
|
|
|
#include "nm-setting-ip4-config.h"
|
|
|
|
|
#include "nm-setting-ip6-config.h"
|
|
|
|
|
#include "nm-setting-olpc-mesh.h"
|
|
|
|
|
#include "nm-setting-ppp.h"
|
|
|
|
|
#include "nm-setting-pppoe.h"
|
|
|
|
|
#include "nm-setting-serial.h"
|
|
|
|
|
#include "nm-setting-vpn.h"
|
|
|
|
|
#include "nm-setting-wired.h"
|
|
|
|
|
#include "nm-setting-adsl.h"
|
|
|
|
|
#include "nm-setting-wireless.h"
|
|
|
|
|
#include "nm-setting-wireless-security.h"
|
2016-08-16 05:55:58 +05:30
|
|
|
#include "nm-setting-proxy.h"
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-setting-bond.h"
|
|
|
|
|
#include "nm-utils.h"
|
2014-07-27 23:55:55 +02:00
|
|
|
#include "nm-core-internal.h"
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2016-11-21 00:43:52 +01:00
|
|
|
#include "devices/nm-device-ethernet.h"
|
2011-01-26 11:38:12 -06:00
|
|
|
#include "nm-settings-connection.h"
|
2015-04-16 08:52:20 -04:00
|
|
|
#include "nm-settings-plugin.h"
|
2015-04-16 14:20:51 -04:00
|
|
|
#include "nm-bus-manager.h"
|
2014-08-16 01:33:46 +02:00
|
|
|
#include "nm-auth-utils.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-auth-subject.h"
|
2010-10-26 11:15:19 -05:00
|
|
|
#include "nm-session-monitor.h"
|
2016-10-05 17:44:58 +02:00
|
|
|
#include "plugins/keyfile/nms-keyfile-plugin.h"
|
2011-01-27 10:41:02 -06:00
|
|
|
#include "nm-agent-manager.h"
|
2013-03-12 11:11:54 -04:00
|
|
|
#include "nm-config.h"
|
2015-07-15 14:44:45 +02:00
|
|
|
#include "nm-audit-manager.h"
|
2013-09-26 17:34:23 -04:00
|
|
|
#include "NetworkManagerUtils.h"
|
2015-07-15 14:09:00 +02:00
|
|
|
#include "nm-dispatcher.h"
|
2016-09-29 13:49:01 +02:00
|
|
|
#include "nm-inotify-helper.h"
|
2007-11-21 06:24:15 +00:00
|
|
|
|
2016-11-23 13:14:08 +01:00
|
|
|
#include "introspection/org.freedesktop.NetworkManager.Settings.h"
|
2015-04-15 14:53:30 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
/*****************************************************************************/
|
2014-10-21 10:10:35 +02:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
#define EXPORT(sym) void * __export_##sym = &sym;
|
|
|
|
|
|
|
|
|
|
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)
|
2016-09-29 13:49:01 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
#define HOSTNAMED_SERVICE_NAME "org.freedesktop.hostname1"
|
|
|
|
|
#define HOSTNAMED_SERVICE_PATH "/org/freedesktop/hostname1"
|
|
|
|
|
#define HOSTNAMED_SERVICE_INTERFACE "org.freedesktop.hostname1"
|
|
|
|
|
|
2016-03-24 14:09:44 -05:00
|
|
|
#define HOSTNAME_FILE_DEFAULT "/etc/hostname"
|
|
|
|
|
#define HOSTNAME_FILE_UCASE_HOSTNAME "/etc/HOSTNAME"
|
|
|
|
|
#define HOSTNAME_FILE_GENTOO "/etc/conf.d/hostname"
|
|
|
|
|
#define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
|
|
|
|
|
#define CONF_DHCP IFCFG_DIR "/dhcp"
|
2015-03-23 09:15:47 +01:00
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
static NM_CACHED_QUARK_FCN ("plugin-module-path", plugin_module_path_quark)
|
2015-06-17 17:43:32 +02:00
|
|
|
|
2016-04-25 15:03:31 +02:00
|
|
|
#if (defined(HOSTNAME_PERSIST_SUSE) + defined(HOSTNAME_PERSIST_SLACKWARE) + defined(HOSTNAME_PERSIST_GENTOO)) > 1
|
|
|
|
|
#error "Can only define one of HOSTNAME_PERSIST_*"
|
|
|
|
|
#endif
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
#if defined(HOSTNAME_PERSIST_SUSE)
|
2016-03-24 14:09:44 -05:00
|
|
|
#define HOSTNAME_FILE HOSTNAME_FILE_UCASE_HOSTNAME
|
|
|
|
|
#elif defined(HOSTNAME_PERSIST_SLACKWARE)
|
|
|
|
|
#define HOSTNAME_FILE HOSTNAME_FILE_UCASE_HOSTNAME
|
2015-03-23 09:15:47 +01:00
|
|
|
#elif defined(HOSTNAME_PERSIST_GENTOO)
|
|
|
|
|
#define HOSTNAME_FILE HOSTNAME_FILE_GENTOO
|
|
|
|
|
#else
|
|
|
|
|
#define HOSTNAME_FILE HOSTNAME_FILE_DEFAULT
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
static NM_CACHED_QUARK_FCN ("default-wired-connection", _default_wired_connection_quark)
|
|
|
|
|
static NM_CACHED_QUARK_FCN ("default-wired-device", _default_wired_device_quark)
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
/*****************************************************************************/
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE (NMSettings,
|
|
|
|
|
PROP_UNMANAGED_SPECS,
|
|
|
|
|
PROP_HOSTNAME,
|
|
|
|
|
PROP_CAN_MODIFY,
|
|
|
|
|
PROP_CONNECTIONS,
|
|
|
|
|
PROP_STARTUP_COMPLETE,
|
|
|
|
|
);
|
2008-05-07 09:48:12 +00:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
enum {
|
|
|
|
|
CONNECTION_ADDED,
|
|
|
|
|
CONNECTION_UPDATED,
|
|
|
|
|
CONNECTION_REMOVED,
|
|
|
|
|
CONNECTION_VISIBILITY_CHANGED,
|
|
|
|
|
AGENT_REGISTERED,
|
|
|
|
|
NEW_CONNECTION, /* exported, not used internally */
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
2016-04-26 15:43:57 +02:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
2012-05-02 10:25:58 -05:00
|
|
|
|
2008-04-08 01:36:39 +00:00
|
|
|
typedef struct {
|
2011-01-27 10:41:02 -06:00
|
|
|
NMAgentManager *agent_mgr;
|
|
|
|
|
|
2013-03-12 11:11:54 -04:00
|
|
|
NMConfig *config;
|
2008-04-22 14:48:02 +00:00
|
|
|
|
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;
|
2016-05-17 11:03:53 +02:00
|
|
|
NMSettingsConnection **connections_cached_list;
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *unmanaged_specs;
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
GSList *unrecognized_specs;
|
2014-12-18 16:04:07 -05:00
|
|
|
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
gboolean started;
|
2014-12-18 16:04:07 -05:00
|
|
|
gboolean startup_complete;
|
2015-03-23 09:15:47 +01:00
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
char *value;
|
|
|
|
|
GFileMonitor *monitor;
|
|
|
|
|
GFileMonitor *dhcp_monitor;
|
2016-01-04 10:29:06 +01:00
|
|
|
gulong monitor_id;
|
|
|
|
|
gulong dhcp_monitor_id;
|
2015-03-23 17:36:34 +01:00
|
|
|
GDBusProxy *hostnamed_proxy;
|
2015-03-23 09:15:47 +01:00
|
|
|
} hostname;
|
2010-10-27 20:05:23 -05:00
|
|
|
} NMSettingsPrivate;
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
struct _NMSettings {
|
|
|
|
|
NMExportedObject parent;
|
|
|
|
|
NMSettingsPrivate _priv;
|
|
|
|
|
};
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
struct _NMSettingsClass {
|
|
|
|
|
NMExportedObjectClass parent;
|
2008-04-08 01:36:39 +00:00
|
|
|
};
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT);
|
|
|
|
|
|
|
|
|
|
#define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettings, NM_IS_SETTINGS)
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define _NMLOG_DOMAIN LOGD_SETTINGS
|
2016-10-14 15:32:56 +02:00
|
|
|
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "settings", __VA_ARGS__)
|
2016-09-29 13:49:01 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void claim_connection (NMSettings *self,
|
|
|
|
|
NMSettingsConnection *connection);
|
|
|
|
|
|
|
|
|
|
static void unmanaged_specs_changed (NMSettingsPlugin *config, gpointer user_data);
|
|
|
|
|
static void unrecognized_specs_changed (NMSettingsPlugin *config, gpointer user_data);
|
|
|
|
|
|
|
|
|
|
static void connection_ready_changed (NMSettingsConnection *conn,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2008-04-08 01:36:39 +00:00
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
static void
|
|
|
|
|
check_startup_complete (NMSettings *self)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
NMSettingsConnection *conn;
|
|
|
|
|
|
|
|
|
|
if (priv->startup_complete)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) {
|
|
|
|
|
if (!nm_settings_connection_get_ready (conn))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-26 15:43:57 +02:00
|
|
|
/* the connection_ready_changed signal handler is no longer needed. */
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn))
|
|
|
|
|
g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self);
|
|
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
priv->startup_complete = TRUE;
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_STARTUP_COMPLETE);
|
2014-12-18 16:04:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
connection_ready_changed (NMSettingsConnection *conn,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
|
|
|
|
|
if (nm_settings_connection_get_ready (conn))
|
|
|
|
|
check_startup_complete (self);
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-13 14:13:50 -03:00
|
|
|
static void
|
2015-04-16 08:52:20 -04:00
|
|
|
plugin_connection_added (NMSettingsPlugin *config,
|
2013-06-13 14:13:50 -03:00
|
|
|
NMSettingsConnection *connection,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-04-23 09:43:20 -05:00
|
|
|
claim_connection (NM_SETTINGS (user_data), connection);
|
2013-06-13 14:13:50 -03:00
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
|
2008-05-11 20:20:52 +00:00
|
|
|
GSList *plugin_connections;
|
|
|
|
|
GSList *elt;
|
|
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
plugin_connections = nm_settings_plugin_get_connections (plugin);
|
2008-05-11 20:20:52 +00:00
|
|
|
|
|
|
|
|
// 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))
|
2015-04-23 09:43:20 -05:00
|
|
|
claim_connection (self, NM_SETTINGS_CONNECTION (elt->data));
|
2008-05-11 20:20:52 +00:00
|
|
|
|
|
|
|
|
g_slist_free (plugin_connections);
|
2013-06-13 14:13:50 -03:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
g_signal_connect (plugin, NM_SETTINGS_PLUGIN_CONNECTION_ADDED,
|
2013-06-13 14:13:50 -03:00
|
|
|
G_CALLBACK (plugin_connection_added), self);
|
2015-04-16 08:52:20 -04:00
|
|
|
g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED,
|
2013-06-13 14:13:50 -03:00
|
|
|
G_CALLBACK (unmanaged_specs_changed), self);
|
2015-04-16 08:52:20 -04:00
|
|
|
g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED,
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
G_CALLBACK (unrecognized_specs_changed), self);
|
2008-05-11 20:20:52 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-18 14:46:57 +00:00
|
|
|
priv->connections_loaded = TRUE;
|
2016-04-22 15:04:15 +02:00
|
|
|
_notify (self, PROP_CONNECTIONS);
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
unmanaged_specs_changed (NULL, self);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
unrecognized_specs_changed (NULL, self);
|
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-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);
|
2016-04-26 15:43:57 +02:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
2010-08-03 13:23:30 -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
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
impl_settings_list_connections (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context)
|
2010-07-29 00:11:21 -04:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2015-04-15 14:53:30 -04:00
|
|
|
GPtrArray *connections;
|
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
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
|
2010-10-26 16:33:47 -05:00
|
|
|
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))
|
2015-04-15 14:53:30 -04:00
|
|
|
g_ptr_array_add (connections, key);
|
|
|
|
|
g_ptr_array_add (connections, NULL);
|
|
|
|
|
|
|
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(^ao)", connections->pdata));
|
|
|
|
|
g_ptr_array_unref (connections);
|
2010-07-29 00:11:21 -04:00
|
|
|
}
|
|
|
|
|
|
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 (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
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
|
2015-09-07 13:38:43 +02:00
|
|
|
if (g_strcmp0 (uuid, nm_settings_connection_get_uuid (candidate)) == 0)
|
2012-01-13 17:20:06 -06:00
|
|
|
return candidate;
|
2011-04-22 11:55:52 -05:00
|
|
|
}
|
|
|
|
|
|
2012-01-13 17:20:06 -06:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-09 11:44:44 -06:00
|
|
|
static void
|
2012-01-13 17:20:06 -06:00
|
|
|
impl_settings_get_connection_by_uuid (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *uuid)
|
2012-01-13 17:20:06 -06:00
|
|
|
{
|
|
|
|
|
NMSettingsConnection *connection = NULL;
|
2014-06-26 17:34:54 +02:00
|
|
|
NMAuthSubject *subject = NULL;
|
2014-01-09 11:44:44 -06:00
|
|
|
GError *error = NULL;
|
|
|
|
|
char *error_desc = NULL;
|
2012-01-13 17:20:06 -06:00
|
|
|
|
|
|
|
|
connection = nm_settings_get_connection_by_uuid (self, uuid);
|
2014-01-09 11:44:44 -06:00
|
|
|
if (!connection) {
|
|
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"No connection with the UUID was found.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 13:34:57 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2014-01-09 11:44:44 -06:00
|
|
|
if (!subject) {
|
|
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to determine UID of request.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 13:34:57 +02:00
|
|
|
if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
|
|
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2014-01-09 11:44:44 -06:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
goto error;
|
2011-04-22 11:55:52 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-09 11:44:44 -06:00
|
|
|
g_clear_object (&subject);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (
|
|
|
|
|
context,
|
|
|
|
|
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
|
2014-01-09 11:44:44 -06:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_assert (error);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2014-01-09 11:44:44 -06:00
|
|
|
g_clear_object (&subject);
|
2011-04-22 11:55:52 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-17 11:03:53 +02:00
|
|
|
/**
|
|
|
|
|
* nm_settings_get_connections:
|
|
|
|
|
* @self: the #NMSettings
|
|
|
|
|
* @out_len: (out): (allow-none): returns the number of returned
|
|
|
|
|
* connections.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer-none): a list of NMSettingsConnections. The list is
|
|
|
|
|
* unsorted and NULL terminated. The result is never %NULL, in case of no
|
|
|
|
|
* connections, it returns an empty list.
|
|
|
|
|
* The returned list is cached internally, only valid until the next
|
|
|
|
|
* NMSettings operation.
|
|
|
|
|
*/
|
|
|
|
|
NMSettingsConnection *const*
|
|
|
|
|
nm_settings_get_connections (NMSettings *self, guint *out_len)
|
|
|
|
|
{
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
NMSettingsPrivate *priv;
|
|
|
|
|
guint l, i;
|
|
|
|
|
NMSettingsConnection **v;
|
|
|
|
|
NMSettingsConnection *con;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
|
|
|
|
|
|
|
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
2017-02-03 12:27:15 +01:00
|
|
|
if (G_LIKELY (priv->connections_cached_list)) {
|
2016-05-17 11:03:53 +02:00
|
|
|
NM_SET_OUT (out_len, g_hash_table_size (priv->connections));
|
|
|
|
|
return priv->connections_cached_list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
l = g_hash_table_size (priv->connections);
|
|
|
|
|
|
2017-02-03 12:27:15 +01:00
|
|
|
v = g_new (NMSettingsConnection *, (gsize) l + 1);
|
2016-05-17 11:03:53 +02:00
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
2017-02-03 12:27:15 +01:00
|
|
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con)) {
|
|
|
|
|
nm_assert (i < l);
|
2016-05-17 11:03:53 +02:00
|
|
|
v[i++] = con;
|
2017-02-03 12:27:15 +01:00
|
|
|
}
|
2016-05-17 11:03:53 +02:00
|
|
|
nm_assert (i == l);
|
2017-02-03 12:27:15 +01:00
|
|
|
v[i] = NULL;
|
2016-05-17 11:03:53 +02:00
|
|
|
|
|
|
|
|
NM_SET_OUT (out_len, l);
|
|
|
|
|
priv->connections_cached_list = v;
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-03 12:27:15 +01:00
|
|
|
/**
|
|
|
|
|
* nm_settings_get_connections_clone:
|
|
|
|
|
* @self: the #NMSetting
|
|
|
|
|
* @out_len: (allow-none): optional output argument
|
|
|
|
|
* @func: caller-supplied function for filtering connections
|
|
|
|
|
* @func_data: caller-supplied data passed to @func
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer container) (element-type NMSettingsConnection):
|
|
|
|
|
* an NULL terminated array of #NMSettingsConnection objects that were
|
|
|
|
|
* filtered by @func (or all connections if no filter was specified).
|
|
|
|
|
* The order is arbitrary.
|
|
|
|
|
* Caller is responsible for freeing the returned array with free(),
|
|
|
|
|
* the contained values do not need to be unrefed.
|
|
|
|
|
*/
|
|
|
|
|
NMSettingsConnection **
|
|
|
|
|
nm_settings_get_connections_clone (NMSettings *self,
|
|
|
|
|
guint *out_len,
|
|
|
|
|
NMSettingsConnectionFilterFunc func,
|
|
|
|
|
gpointer func_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsConnection *const*list_cached;
|
|
|
|
|
NMSettingsConnection **list;
|
|
|
|
|
guint len, i, j;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
|
|
|
|
|
|
|
|
|
|
list_cached = nm_settings_get_connections (self, &len);
|
|
|
|
|
|
|
|
|
|
#if NM_MORE_ASSERTS
|
|
|
|
|
nm_assert (list_cached);
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
|
nm_assert (NM_IS_SETTINGS_CONNECTION (list_cached[i]));
|
|
|
|
|
nm_assert (!list_cached[i]);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
list = g_new (NMSettingsConnection *, ((gsize) len + 1));
|
|
|
|
|
if (func) {
|
|
|
|
|
for (i = 0, j = 0; i < len; i++) {
|
|
|
|
|
if (func (self, list_cached[i], func_data))
|
|
|
|
|
list[j++] = list_cached[i];
|
|
|
|
|
}
|
|
|
|
|
list[j] = NULL;
|
|
|
|
|
len = j;
|
|
|
|
|
} else
|
|
|
|
|
memcpy (list, list_cached, sizeof (list[0]) * ((gsize) len + 1));
|
|
|
|
|
|
|
|
|
|
NM_SET_OUT (out_len, len);
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-29 14:59:48 +01:00
|
|
|
/* Returns a list of NMSettingsConnections.
|
|
|
|
|
* The list is sorted in the order suitable for auto-connecting, i.e.
|
|
|
|
|
* first go connections with autoconnect=yes and most recent timestamp.
|
2017-02-03 14:15:16 +01:00
|
|
|
* Caller must free the list with g_free(), but not the list items.
|
2010-10-27 15:47:10 -05:00
|
|
|
*/
|
2017-02-03 14:15:16 +01:00
|
|
|
NMSettingsConnection **
|
|
|
|
|
nm_settings_get_connections_sorted (NMSettings *self, guint *out_len)
|
2010-10-27 15:47:10 -05:00
|
|
|
{
|
2017-02-03 14:15:16 +01:00
|
|
|
NMSettingsConnection **connections;
|
|
|
|
|
guint len;
|
2010-10-27 15:47:10 -05:00
|
|
|
|
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
|
|
|
|
2017-02-03 14:15:16 +01:00
|
|
|
connections = nm_settings_get_connections_clone (self, &len, NULL, NULL);
|
|
|
|
|
if (len > 1)
|
2017-02-05 16:24:27 +01:00
|
|
|
g_qsort_with_data (connections, len, sizeof (NMSettingsConnection *), nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL);
|
2017-02-03 14:15:16 +01:00
|
|
|
|
|
|
|
|
NM_SET_OUT (out_len, len);
|
|
|
|
|
return connections;
|
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-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
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2015-04-22 15:05:53 +02:00
|
|
|
gboolean
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection)
|
2015-04-22 15:05:53 +02:00
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer data;
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, NULL, &data))
|
|
|
|
|
if (data == connection)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
return priv->unmanaged_specs;
|
2008-04-08 01:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
static NMSettingsPlugin *
|
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);
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
/* Do any of the plugins support the given capability? */
|
2008-11-14 18:24:38 +00:00
|
|
|
for (iter = priv->plugins; iter; iter = iter->next) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPluginCapabilities caps = NM_SETTINGS_PLUGIN_CAP_NONE;
|
2008-11-14 18:24:38 +00:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
g_object_get (G_OBJECT (iter->data), NM_SETTINGS_PLUGIN_CAPABILITIES, &caps, NULL);
|
2015-07-07 16:54:05 +02:00
|
|
|
if (NM_FLAGS_ALL (caps, capability))
|
2015-04-16 08:52:20 -04:00
|
|
|
return NM_SETTINGS_PLUGIN (iter->data);
|
2008-11-14 18:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
#if defined(HOSTNAME_PERSIST_GENTOO)
|
|
|
|
|
static gchar *
|
|
|
|
|
read_hostname_gentoo (const char *path)
|
|
|
|
|
{
|
2016-04-25 15:13:18 +02:00
|
|
|
gs_free char *contents = NULL;
|
|
|
|
|
gs_strfreev char **all_lines = NULL;
|
|
|
|
|
const char *tmp;
|
|
|
|
|
guint i;
|
2015-03-23 09:15:47 +01:00
|
|
|
|
|
|
|
|
if (!g_file_get_contents (path, &contents, NULL, NULL))
|
|
|
|
|
return NULL;
|
2016-04-25 15:13:18 +02:00
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
all_lines = g_strsplit (contents, "\n", 0);
|
2016-04-25 15:13:18 +02:00
|
|
|
for (i = 0; all_lines[i]; i++) {
|
2015-03-23 09:15:47 +01:00
|
|
|
g_strstrip (all_lines[i]);
|
|
|
|
|
if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
|
|
|
|
|
continue;
|
|
|
|
|
if (g_str_has_prefix (all_lines[i], "hostname=")) {
|
2016-02-12 12:34:43 +01:00
|
|
|
tmp = &all_lines[i][NM_STRLEN ("hostname=")];
|
2016-04-25 15:13:18 +02:00
|
|
|
return g_shell_unquote (tmp, NULL);
|
2015-03-23 09:15:47 +01:00
|
|
|
}
|
|
|
|
|
}
|
2016-04-25 15:13:18 +02:00
|
|
|
return NULL;
|
2015-03-23 09:15:47 +01:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-04-22 20:30:56 -05:00
|
|
|
#if defined(HOSTNAME_PERSIST_SLACKWARE)
|
|
|
|
|
static gchar *
|
|
|
|
|
read_hostname_slackware (const char *path)
|
|
|
|
|
{
|
2016-04-25 15:13:18 +02:00
|
|
|
gs_free char *contents = NULL;
|
|
|
|
|
gs_strfreev char **all_lines = NULL;
|
|
|
|
|
char *tmp;
|
|
|
|
|
guint i, j = 0;
|
2016-04-22 20:30:56 -05:00
|
|
|
|
|
|
|
|
if (!g_file_get_contents (path, &contents, NULL, NULL))
|
|
|
|
|
return NULL;
|
2016-04-25 15:13:18 +02:00
|
|
|
|
2016-04-22 20:30:56 -05:00
|
|
|
all_lines = g_strsplit (contents, "\n", 0);
|
2016-04-25 15:13:18 +02:00
|
|
|
for (i = 0; all_lines[i]; i++) {
|
2016-04-22 20:30:56 -05:00
|
|
|
g_strstrip (all_lines[i]);
|
|
|
|
|
if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
|
|
|
|
|
continue;
|
|
|
|
|
tmp = &all_lines[i][0];
|
|
|
|
|
/* We only want up to the first '.' -- the rest of the */
|
|
|
|
|
/* fqdn is defined in /etc/hosts */
|
|
|
|
|
while (tmp[j] != '\0') {
|
|
|
|
|
if (tmp[j] == '.') {
|
|
|
|
|
tmp[j] = '\0';
|
2016-04-25 15:03:31 +02:00
|
|
|
break;
|
2016-04-22 20:30:56 -05:00
|
|
|
}
|
|
|
|
|
j++;
|
|
|
|
|
}
|
2016-04-25 15:13:18 +02:00
|
|
|
return g_shell_unquote (tmp, NULL);
|
2016-04-22 20:30:56 -05:00
|
|
|
}
|
2016-04-25 15:13:18 +02:00
|
|
|
return NULL;
|
2016-04-22 20:30:56 -05:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
#if defined(HOSTNAME_PERSIST_SUSE)
|
|
|
|
|
static gboolean
|
|
|
|
|
hostname_is_dynamic (void)
|
|
|
|
|
{
|
|
|
|
|
GIOChannel *channel;
|
|
|
|
|
char *str = NULL;
|
|
|
|
|
gboolean dynamic = FALSE;
|
|
|
|
|
|
|
|
|
|
channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
|
|
|
|
|
if (!channel)
|
|
|
|
|
return dynamic;
|
|
|
|
|
|
|
|
|
|
while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
|
|
|
|
|
if (str) {
|
|
|
|
|
g_strstrip (str);
|
|
|
|
|
if (g_str_has_prefix (str, "DHCLIENT_SET_HOSTNAME="))
|
2016-02-12 12:34:43 +01:00
|
|
|
dynamic = strcmp (&str[NM_STRLEN ("DHCLIENT_SET_HOSTNAME=")], "\"yes\"") == 0;
|
2015-03-23 09:15:47 +01:00
|
|
|
g_free (str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_io_channel_shutdown (channel, FALSE, NULL);
|
|
|
|
|
g_io_channel_unref (channel);
|
|
|
|
|
|
|
|
|
|
return dynamic;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
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
|
|
|
char *hostname = NULL;
|
|
|
|
|
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
if (!priv->started)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
if (priv->hostname.hostnamed_proxy) {
|
|
|
|
|
hostname = g_strdup (priv->hostname.value);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
#if defined(HOSTNAME_PERSIST_SUSE)
|
|
|
|
|
if (priv->hostname.dhcp_monitor_id && hostname_is_dynamic ())
|
|
|
|
|
return NULL;
|
|
|
|
|
#endif
|
2016-04-25 15:03:31 +02:00
|
|
|
|
|
|
|
|
#if defined(HOSTNAME_PERSIST_GENTOO)
|
2016-04-27 14:14:00 +02:00
|
|
|
hostname = read_hostname_gentoo (HOSTNAME_FILE);
|
2016-04-25 15:03:31 +02:00
|
|
|
#elif defined(HOSTNAME_PERSIST_SLACKWARE)
|
2016-04-27 14:14:00 +02:00
|
|
|
hostname = read_hostname_slackware (HOSTNAME_FILE);
|
2016-04-25 15:03:31 +02:00
|
|
|
#else
|
2016-04-27 14:14:00 +02:00
|
|
|
if (g_file_get_contents (HOSTNAME_FILE, &hostname, NULL, NULL))
|
2015-03-23 09:15:47 +01:00
|
|
|
g_strchomp (hostname);
|
2016-04-25 15:03:31 +02:00
|
|
|
#endif
|
2015-03-23 09:15:47 +01:00
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
out:
|
2015-03-23 09:15:47 +01:00
|
|
|
if (hostname && !hostname[0]) {
|
|
|
|
|
g_free (hostname);
|
|
|
|
|
hostname = NULL;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
return hostname;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
find_spec (GSList *spec_list, const char *spec)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
for (iter = spec_list; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
if (!strcmp ((const char *) iter->data, spec))
|
2009-06-11 00:39:12 -04:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-27 19:25:46 +00:00
|
|
|
static void
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
update_specs (NMSettings *self, GSList **specs_ptr,
|
2015-04-16 08:52:20 -04:00
|
|
|
GSList * (*get_specs_func) (NMSettingsPlugin *))
|
2007-11-27 19:25:46 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2007-11-27 19:25:46 +00:00
|
|
|
GSList *iter;
|
|
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
g_slist_free_full (*specs_ptr, g_free);
|
|
|
|
|
*specs_ptr = NULL;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
specs = get_specs_func (NM_SETTINGS_PLUGIN (iter->data));
|
2009-06-11 00:39:12 -04:00
|
|
|
for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) {
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
if (!find_spec (*specs_ptr, (const char *) specs_iter->data)) {
|
|
|
|
|
*specs_ptr = g_slist_prepend (*specs_ptr, 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
|
|
|
}
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
static void
|
2015-04-16 08:52:20 -04:00
|
|
|
unmanaged_specs_changed (NMSettingsPlugin *config,
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
update_specs (self, &priv->unmanaged_specs,
|
2015-04-16 08:52:20 -04:00
|
|
|
nm_settings_plugin_get_unmanaged_specs);
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_UNMANAGED_SPECS);
|
2007-11-21 06:24:15 +00:00
|
|
|
}
|
2007-11-27 19:25:46 +00:00
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
static void
|
2015-04-16 08:52:20 -04:00
|
|
|
unrecognized_specs_changed (NMSettingsPlugin *config,
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
update_specs (self, &priv->unrecognized_specs,
|
2015-04-16 08:52:20 -04:00
|
|
|
nm_settings_plugin_get_unrecognized_specs);
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
}
|
|
|
|
|
|
2015-08-11 12:32:27 +02:00
|
|
|
static gboolean
|
2015-04-16 08:52:20 -04:00
|
|
|
add_plugin (NMSettings *self, NMSettingsPlugin *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;
|
2015-06-17 17:43:32 +02:00
|
|
|
const char *path;
|
2007-11-27 19:25:46 +00:00
|
|
|
|
2015-08-11 12:32:27 +02:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
2015-04-16 08:52:20 -04:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (plugin), FALSE);
|
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
|
|
|
|
2015-08-11 12:32:27 +02:00
|
|
|
if (g_slist_find (priv->plugins, plugin)) {
|
|
|
|
|
/* don't add duplicates. */
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-22 14:48:02 +00:00
|
|
|
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
|
2015-04-16 09:42:32 -04:00
|
|
|
nm_settings_plugin_init (plugin);
|
2008-04-22 14:48:02 +00:00
|
|
|
|
|
|
|
|
g_object_get (G_OBJECT (plugin),
|
2015-04-16 08:52:20 -04:00
|
|
|
NM_SETTINGS_PLUGIN_NAME, &pname,
|
|
|
|
|
NM_SETTINGS_PLUGIN_INFO, &pinfo,
|
2008-04-22 14:48:02 +00:00
|
|
|
NULL);
|
|
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
path = g_object_get_qdata (G_OBJECT (plugin), plugin_module_path_quark ());
|
2015-06-17 17:43:32 +02:00
|
|
|
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("loaded plugin %s: %s%s%s%s", pname, pinfo,
|
|
|
|
|
NM_PRINT_FMT_QUOTED (path, " (", path, ")", ""));
|
2008-04-22 14:48:02 +00:00
|
|
|
g_free (pname);
|
|
|
|
|
g_free (pinfo);
|
2015-08-11 12:32:27 +02:00
|
|
|
|
|
|
|
|
return TRUE;
|
2008-04-22 14:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
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)) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
|
2009-06-11 00:39:12 -04:00
|
|
|
char *list_pname = NULL;
|
|
|
|
|
|
|
|
|
|
g_object_get (G_OBJECT (plugin),
|
2015-04-16 08:52:20 -04:00
|
|
|
NM_SETTINGS_PLUGIN_NAME,
|
2009-06-11 00:39:12 -04:00
|
|
|
&list_pname,
|
|
|
|
|
NULL);
|
|
|
|
|
if (list_pname && !strcmp (pname, list_pname))
|
|
|
|
|
obj = G_OBJECT (plugin);
|
|
|
|
|
|
|
|
|
|
g_free (list_pname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-10 16:04:14 +02:00
|
|
|
static void
|
|
|
|
|
add_keyfile_plugin (NMSettings *self)
|
|
|
|
|
{
|
2016-10-05 18:35:23 +02:00
|
|
|
gs_unref_object NMSKeyfilePlugin *keyfile_plugin = NULL;
|
2012-07-10 16:04:14 +02:00
|
|
|
|
2016-10-05 18:12:23 +02:00
|
|
|
keyfile_plugin = nms_keyfile_plugin_new ();
|
2015-04-16 08:52:20 -04:00
|
|
|
if (!add_plugin (self, NM_SETTINGS_PLUGIN (keyfile_plugin)))
|
2015-08-11 12:32:27 +02:00
|
|
|
g_return_if_reached ();
|
2012-07-10 16:04:14 +02:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
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
|
|
|
{
|
|
|
|
|
GSList *list = NULL;
|
2011-09-22 10:16:07 -05:00
|
|
|
const char **iter;
|
2012-07-10 16:04:14 +02:00
|
|
|
gboolean keyfile_added = FALSE;
|
2009-06-11 00:39:12 -04:00
|
|
|
gboolean success = TRUE;
|
2015-06-09 19:27:55 +02:00
|
|
|
gboolean add_ibft = FALSE;
|
|
|
|
|
gboolean has_no_ibft;
|
|
|
|
|
gssize idx_no_ibft, idx_ibft;
|
|
|
|
|
|
2017-02-04 17:53:17 +01:00
|
|
|
idx_ibft = nm_utils_strv_find_first ((char **) plugins, -1, "ibft");
|
|
|
|
|
idx_no_ibft = nm_utils_strv_find_first ((char **) plugins, -1, "no-ibft");
|
2015-06-09 19:27:55 +02:00
|
|
|
has_no_ibft = idx_no_ibft >= 0 && idx_no_ibft > idx_ibft;
|
|
|
|
|
#if WITH_SETTINGS_PLUGIN_IBFT
|
|
|
|
|
add_ibft = idx_no_ibft < 0 && idx_ibft < 0;
|
|
|
|
|
#endif
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2013-02-11 15:45:48 -06:00
|
|
|
for (iter = plugins; iter && *iter; iter++) {
|
2015-06-09 19:27:55 +02:00
|
|
|
const char *pname = *iter;
|
2009-06-11 00:39:12 -04:00
|
|
|
GObject *obj;
|
2011-09-22 10:16:07 -05:00
|
|
|
|
2014-10-21 10:10:35 +02:00
|
|
|
if (!*pname || strchr (pname, '/')) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("ignore invalid plugin \"%s\"", pname);
|
2014-10-21 10:10:35 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-05-25 13:49:11 +02:00
|
|
|
if (!strcmp (pname, "ifcfg-suse")) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("skipping deprecated plugin ifcfg-suse");
|
2015-05-25 13:49:11 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-09 19:27:55 +02:00
|
|
|
if (!strcmp (pname, "no-ibft"))
|
|
|
|
|
continue;
|
|
|
|
|
if (has_no_ibft && !strcmp (pname, "ibft"))
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-07-10 16:04:14 +02:00
|
|
|
/* keyfile plugin is built-in now */
|
|
|
|
|
if (strcmp (pname, "keyfile") == 0) {
|
|
|
|
|
if (!keyfile_added) {
|
|
|
|
|
add_keyfile_plugin (self);
|
|
|
|
|
keyfile_added = TRUE;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-04 17:53:17 +01:00
|
|
|
if (nm_utils_strv_find_first ((char **) plugins,
|
|
|
|
|
iter - plugins,
|
|
|
|
|
pname) >= 0) {
|
2015-08-11 10:50:17 +02:00
|
|
|
/* the plugin is already mentioned in the list previously.
|
|
|
|
|
* Don't load a duplicate. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (find_plugin (list, pname))
|
|
|
|
|
continue;
|
|
|
|
|
|
2015-06-09 19:27:55 +02:00
|
|
|
load_plugin:
|
|
|
|
|
{
|
|
|
|
|
GModule *plugin;
|
|
|
|
|
gs_free char *full_name = NULL;
|
|
|
|
|
gs_free char *path = NULL;
|
|
|
|
|
GObject * (*factory_func) (void);
|
|
|
|
|
struct stat st;
|
|
|
|
|
int errsv;
|
|
|
|
|
|
|
|
|
|
full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
|
|
|
|
|
path = g_module_build_path (NMPLUGINDIR, full_name);
|
|
|
|
|
|
|
|
|
|
if (stat (path, &st) != 0) {
|
|
|
|
|
errsv = errno;
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not load plugin '%s' from file '%s': %s", pname, path, strerror (errsv));
|
2015-06-09 19:27:55 +02:00
|
|
|
goto next;
|
|
|
|
|
}
|
|
|
|
|
if (!S_ISREG (st.st_mode)) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not load plugin '%s' from file '%s': not a file", pname, path);
|
2015-06-09 19:27:55 +02:00
|
|
|
goto next;
|
|
|
|
|
}
|
|
|
|
|
if (st.st_uid != 0) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not load plugin '%s' from file '%s': file must be owned by root", pname, path);
|
2015-06-09 19:27:55 +02:00
|
|
|
goto next;
|
|
|
|
|
}
|
|
|
|
|
if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not load plugin '%s' from file '%s': invalid file permissions", pname, path);
|
2015-06-09 19:27:55 +02:00
|
|
|
goto next;
|
|
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-06-09 19:27:55 +02:00
|
|
|
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
|
|
|
|
|
if (!plugin) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not load plugin '%s' from file '%s': %s",
|
2015-06-09 19:27:55 +02:00
|
|
|
pname, path, g_module_error ());
|
|
|
|
|
goto next;
|
|
|
|
|
}
|
2014-10-21 10:31:30 +02:00
|
|
|
|
2015-06-09 19:27:55 +02:00
|
|
|
/* errors after this point are fatal, because we loaded the shared library already. */
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
if (!g_module_symbol (plugin, "nm_settings_plugin_factory", (gpointer) (&factory_func))) {
|
2015-06-09 19:27:55 +02:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
|
|
|
|
"Could not find plugin '%s' factory function.",
|
|
|
|
|
pname);
|
|
|
|
|
success = FALSE;
|
|
|
|
|
g_module_close (plugin);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-10-21 10:10:35 +02:00
|
|
|
|
2016-04-29 15:00:09 +02:00
|
|
|
/* after accessing the plugin we cannot unload it anymore, because the glib
|
|
|
|
|
* types cannot be properly unregistered. */
|
|
|
|
|
g_module_make_resident (plugin);
|
|
|
|
|
|
2015-06-09 19:27:55 +02:00
|
|
|
obj = (*factory_func) ();
|
2015-04-16 08:52:20 -04:00
|
|
|
if (!obj || !NM_IS_SETTINGS_PLUGIN (obj)) {
|
2015-06-09 19:27:55 +02:00
|
|
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
|
|
|
|
"Plugin '%s' returned invalid system config object.",
|
|
|
|
|
pname);
|
|
|
|
|
success = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
g_object_set_qdata_full (obj, plugin_module_path_quark (), path, g_free);
|
2015-06-09 19:27:55 +02:00
|
|
|
path = NULL;
|
2015-04-16 08:52:20 -04:00
|
|
|
if (add_plugin (self, NM_SETTINGS_PLUGIN (obj)))
|
2015-08-11 12:32:27 +02:00
|
|
|
list = g_slist_append (list, obj);
|
|
|
|
|
else
|
|
|
|
|
g_object_unref (obj);
|
2015-06-09 19:27:55 +02:00
|
|
|
}
|
|
|
|
|
next:
|
|
|
|
|
if (add_ibft && !strcmp (pname, "ifcfg-rh")) {
|
|
|
|
|
/* The plugin ibft is not explicitly mentioned but we just enabled "ifcfg-rh".
|
|
|
|
|
* Enable "ibft" by default after "ifcfg-rh". */
|
|
|
|
|
pname = "ibft";
|
|
|
|
|
add_ibft = FALSE;
|
|
|
|
|
goto load_plugin;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-10 16:04:14 +02:00
|
|
|
/* If keyfile plugin was not among configured plugins, add it as the last one */
|
|
|
|
|
if (!keyfile_added)
|
|
|
|
|
add_keyfile_plugin (self);
|
|
|
|
|
|
2013-10-18 16:07:26 +02:00
|
|
|
g_slist_free_full (list, g_object_unref);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
static void
|
2016-04-13 15:47:25 +02:00
|
|
|
connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer user_data)
|
2010-10-27 15:47:10 -05:00
|
|
|
{
|
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,
|
2016-04-13 16:03:06 +02:00
|
|
|
connection,
|
|
|
|
|
by_user);
|
2010-10-27 15:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2013-11-14 10:55:46 -06:00
|
|
|
static void
|
|
|
|
|
connection_removed (NMSettingsConnection *connection, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettings *self = NM_SETTINGS (user_data);
|
2015-04-23 09:40:42 -05:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
const char *cpath = nm_connection_get_path (NM_CONNECTION (connection));
|
|
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup (priv->connections, cpath))
|
|
|
|
|
g_return_if_reached ();
|
2013-11-14 10:55:46 -06:00
|
|
|
g_object_ref (connection);
|
|
|
|
|
|
|
|
|
|
/* Disconnect signal handlers, as plugins might still keep references
|
|
|
|
|
* to the connection (and thus the signal handlers would still be live)
|
|
|
|
|
* even after NMSettings has dropped all its references.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed), self);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self);
|
2016-04-26 15:43:57 +02:00
|
|
|
if (!priv->startup_complete)
|
|
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self);
|
nm-settings: take a reference to ourselves as long we have signals that use us hooked on
Program received signal SIGSEGV, Segmentation fault.
g_type_check_instance_cast (type_instance=type_instance@entry=0x89f180, iface_type=9004512) at gtype.c:4060
4060 node = lookup_type_node_I (type_instance->g_class->g_type);
(gdb) bt
#0 0x00007ffff4b44e80 in g_type_check_instance_cast (type_instance=type_instance@entry=0x89f180, iface_type=9004512) at gtype.c:4060
#1 0x000000000056a460 in connection_visibility_changed (connection=0x89f680 [NMKeyfileConnection], pspec=<optimized out>, user_data=0x89f180) at settings/nm-settings.c:870
#5 0x00007ffff4b3b54f in <emit signal notify:visible on instance 0x89f680 [NMKeyfileConnection]> (instance=instance@entry=0x89f680, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3393
#2 0x00007ffff4b200b5 in g_closure_invoke (closure=0x9131a0, return_value=return_value@entry=0x0, n_param_values=2, param_values=param_values@entry=0x7fffffffd540, invocation_hint=invocation_hint@entry=0x7fffffffd4c0) at gclosure.c:801
#3 0x00007ffff4b32499 in signal_emit_unlocked_R (node=node@entry=0x8696b0, detail=detail@entry=641, instance=instance@entry=0x89f680, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffd540) at gsignal.c:3581
#4 0x00007ffff4b3b1a0 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd710) at gsignal.c:3337
#6 0x00007ffff4b24665 in g_object_dispatch_properties_changed (object=0x89f680 [NMKeyfileConnection], n_pspecs=<optimized out>, pspecs=<optimized out>) at gobject.c:1056
#7 0x00007ffff4b26d11 in g_object_notify (pspec=0x8ce660 [GParamBoolean], object=0x89f680 [NMKeyfileConnection]) at gobject.c:1149
#8 0x00007ffff4b26d11 in g_object_notify (object=0x89f680 [NMKeyfileConnection], property_name=property_name@entry=0x5d2eb9 "visible") at gobject.c:1197
#9 0x0000000000497f85 in set_visible (self=self@entry=0x89f680 [NMKeyfileConnection], new_visible=new_visible@entry=0) at settings/nm-settings-connection.c:296
#10 0x0000000000498165 in dispose (object=0x89f680 [NMKeyfileConnection]) at settings/nm-settings-connection.c:2390
#11 0x00007ffff4b24fec in g_object_unref (_object=0x89f680) at gobject.c:3137
#12 0x00000000004a4a4f in dispose (object=0xa24260 [NMVpnConnection]) at nm-active-connection.c:904
#13 0x00007ffff4b24fec in g_object_unref (_object=0xa24260) at gobject.c:3137
#14 0x0000000000577636 in nm_vpn_service_stop_connections (service=0x8ff610 [NMVpnService], quitting=1, reason=NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED) at vpn-manager/nm-vpn-service.c:150
#15 0x0000000000576ea2 in dispose (object=0x921060 [NMVpnManager]) at vpn-manager/nm-vpn-manager.c:284
#16 0x00007ffff4b24fec in g_object_unref (_object=0x921060) at gobject.c:3137
#17 0x00000000004d0f05 in dispose (object=0x88a2b0 [NMManager]) at nm-manager.c:5061
#18 0x00007ffff4b24fec in g_object_unref (_object=0x88a2b0) at gobject.c:3137
#19 0x0000000000444e08 in _nm_singleton_instance_destroy () at NetworkManagerUtils.c:138
#20 0x00007ffff7de97b7 in _dl_fini () at dl-fini.c:252
#21 0x00007ffff4444778 in __run_exit_handlers (status=status@entry=0, listp=0x7ffff47d0618 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#22 0x00007ffff44447c5 in __GI_exit (status=status@entry=0) at exit.c:104
#23 0x0000000000445b80 in main (argc=1, argv=0x7fffffffdf08) at main.c:458
(gdb)
2015-08-19 10:45:01 +02:00
|
|
|
g_object_unref (self);
|
2013-11-14 10:55:46 -06:00
|
|
|
|
|
|
|
|
/* Forget about the connection internally */
|
2015-04-23 09:40:42 -05:00
|
|
|
g_hash_table_remove (priv->connections, (gpointer) cpath);
|
2016-05-17 11:03:53 +02:00
|
|
|
g_clear_pointer (&priv->connections_cached_list, g_free);
|
2013-11-14 10:55:46 -06:00
|
|
|
|
2013-11-26 09:45:21 -06:00
|
|
|
/* Notify D-Bus */
|
2013-11-14 10:55:46 -06:00
|
|
|
g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection);
|
2013-11-26 09:45:21 -06:00
|
|
|
|
|
|
|
|
/* Re-emit for listeners like NMPolicy */
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_CONNECTIONS);
|
2015-07-23 10:03:21 -05:00
|
|
|
if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection)))
|
|
|
|
|
nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection));
|
2013-11-14 10:55:46 -06:00
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
check_startup_complete (self);
|
|
|
|
|
|
2013-11-14 10:55:46 -06:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMSettingVpn *s_vpn;
|
2011-05-18 22:43:37 -05:00
|
|
|
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
|
2015-04-23 09:43:20 -05:00
|
|
|
claim_connection (NMSettings *self, NMSettingsConnection *connection)
|
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
|
|
|
GError *error = NULL;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer data;
|
2015-04-03 10:08:52 -04:00
|
|
|
const char *path;
|
2014-12-08 19:02:19 +01:00
|
|
|
NMSettingsConnection *existing;
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-01 23:43:14 +01:00
|
|
|
if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("plugin provided invalid connection: %s", error->message);
|
2010-10-27 15:47:10 -05:00
|
|
|
g_error_free (error);
|
2007-11-27 19:25:46 +00:00
|
|
|
return;
|
2010-10-27 15:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
2015-09-07 13:38:43 +02:00
|
|
|
existing = nm_settings_get_connection_by_uuid (self, nm_settings_connection_get_uuid (connection));
|
2014-12-08 19:02:19 +01:00
|
|
|
if (existing) {
|
|
|
|
|
/* Cannot add duplicate connections per UUID. Just return without action and
|
|
|
|
|
* log a warning.
|
|
|
|
|
*
|
|
|
|
|
* This means, that plugins must not provide duplicate connections (UUID).
|
|
|
|
|
* In fact, none of the plugins currently would do that.
|
|
|
|
|
*
|
|
|
|
|
* But globaly, over different setting plugins, there could be duplicates
|
|
|
|
|
* without the individual plugins being aware. Don't handle that at all, just
|
|
|
|
|
* error out. That should not happen unless the admin misconfigured the system
|
|
|
|
|
* to create conflicting connections. */
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("plugin provided duplicate connection with UUID %s",
|
|
|
|
|
nm_settings_connection_get_uuid (connection));
|
2014-12-08 19:02:19 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
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));
|
|
|
|
|
|
nm-settings: take a reference to ourselves as long we have signals that use us hooked on
Program received signal SIGSEGV, Segmentation fault.
g_type_check_instance_cast (type_instance=type_instance@entry=0x89f180, iface_type=9004512) at gtype.c:4060
4060 node = lookup_type_node_I (type_instance->g_class->g_type);
(gdb) bt
#0 0x00007ffff4b44e80 in g_type_check_instance_cast (type_instance=type_instance@entry=0x89f180, iface_type=9004512) at gtype.c:4060
#1 0x000000000056a460 in connection_visibility_changed (connection=0x89f680 [NMKeyfileConnection], pspec=<optimized out>, user_data=0x89f180) at settings/nm-settings.c:870
#5 0x00007ffff4b3b54f in <emit signal notify:visible on instance 0x89f680 [NMKeyfileConnection]> (instance=instance@entry=0x89f680, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3393
#2 0x00007ffff4b200b5 in g_closure_invoke (closure=0x9131a0, return_value=return_value@entry=0x0, n_param_values=2, param_values=param_values@entry=0x7fffffffd540, invocation_hint=invocation_hint@entry=0x7fffffffd4c0) at gclosure.c:801
#3 0x00007ffff4b32499 in signal_emit_unlocked_R (node=node@entry=0x8696b0, detail=detail@entry=641, instance=instance@entry=0x89f680, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffd540) at gsignal.c:3581
#4 0x00007ffff4b3b1a0 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd710) at gsignal.c:3337
#6 0x00007ffff4b24665 in g_object_dispatch_properties_changed (object=0x89f680 [NMKeyfileConnection], n_pspecs=<optimized out>, pspecs=<optimized out>) at gobject.c:1056
#7 0x00007ffff4b26d11 in g_object_notify (pspec=0x8ce660 [GParamBoolean], object=0x89f680 [NMKeyfileConnection]) at gobject.c:1149
#8 0x00007ffff4b26d11 in g_object_notify (object=0x89f680 [NMKeyfileConnection], property_name=property_name@entry=0x5d2eb9 "visible") at gobject.c:1197
#9 0x0000000000497f85 in set_visible (self=self@entry=0x89f680 [NMKeyfileConnection], new_visible=new_visible@entry=0) at settings/nm-settings-connection.c:296
#10 0x0000000000498165 in dispose (object=0x89f680 [NMKeyfileConnection]) at settings/nm-settings-connection.c:2390
#11 0x00007ffff4b24fec in g_object_unref (_object=0x89f680) at gobject.c:3137
#12 0x00000000004a4a4f in dispose (object=0xa24260 [NMVpnConnection]) at nm-active-connection.c:904
#13 0x00007ffff4b24fec in g_object_unref (_object=0xa24260) at gobject.c:3137
#14 0x0000000000577636 in nm_vpn_service_stop_connections (service=0x8ff610 [NMVpnService], quitting=1, reason=NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED) at vpn-manager/nm-vpn-service.c:150
#15 0x0000000000576ea2 in dispose (object=0x921060 [NMVpnManager]) at vpn-manager/nm-vpn-manager.c:284
#16 0x00007ffff4b24fec in g_object_unref (_object=0x921060) at gobject.c:3137
#17 0x00000000004d0f05 in dispose (object=0x88a2b0 [NMManager]) at nm-manager.c:5061
#18 0x00007ffff4b24fec in g_object_unref (_object=0x88a2b0) at gobject.c:3137
#19 0x0000000000444e08 in _nm_singleton_instance_destroy () at NetworkManagerUtils.c:138
#20 0x00007ffff7de97b7 in _dl_fini () at dl-fini.c:252
#21 0x00007ffff4444778 in __run_exit_handlers (status=status@entry=0, listp=0x7ffff47d0618 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#22 0x00007ffff44447c5 in __GI_exit (status=status@entry=0) at exit.c:104
#23 0x0000000000445b80 in main (argc=1, argv=0x7fffffffdf08) at main.c:458
(gdb)
2015-08-19 10:45:01 +02:00
|
|
|
g_object_ref (self);
|
2017-01-24 13:57:05 +01:00
|
|
|
/* This one unexports the connection, it needs to run late to give the active
|
|
|
|
|
* connection a chance to deal with its reference to this settings connection. */
|
|
|
|
|
g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED,
|
|
|
|
|
G_CALLBACK (connection_removed), self);
|
2016-04-13 15:47:25 +02:00
|
|
|
g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL,
|
2013-11-14 10:55:46 -06:00
|
|
|
G_CALLBACK (connection_updated), self);
|
|
|
|
|
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
|
|
|
|
|
G_CALLBACK (connection_visibility_changed),
|
|
|
|
|
self);
|
2014-12-18 16:04:07 -05:00
|
|
|
if (!priv->startup_complete) {
|
|
|
|
|
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY,
|
|
|
|
|
G_CALLBACK (connection_ready_changed),
|
|
|
|
|
self);
|
|
|
|
|
}
|
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);
|
2015-04-03 10:08:52 -04:00
|
|
|
path = nm_exported_object_export (NM_EXPORTED_OBJECT (connection));
|
2010-10-27 15:47:10 -05:00
|
|
|
nm_connection_set_path (NM_CONNECTION (connection), path);
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (priv->connections,
|
|
|
|
|
(gpointer) nm_connection_get_path (NM_CONNECTION (connection)),
|
|
|
|
|
g_object_ref (connection));
|
2016-05-17 11:03:53 +02:00
|
|
|
g_clear_pointer (&priv->connections_cached_list, g_free);
|
2010-10-27 15:47:10 -05:00
|
|
|
|
2014-02-26 20:54:49 +01:00
|
|
|
nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ");
|
|
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
/* Only emit the individual connection-added signal after connections
|
2013-12-05 08:50:10 -05:00
|
|
|
* have been initially loaded.
|
2010-10-27 15:47:10 -05:00
|
|
|
*/
|
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);
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_CONNECTIONS);
|
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
|
|
|
}
|
|
|
|
|
|
2013-10-17 13:04:37 -05:00
|
|
|
/**
|
|
|
|
|
* nm_settings_add_connection:
|
|
|
|
|
* @self: the #NMSettings object
|
|
|
|
|
* @connection: the source connection to create a new #NMSettingsConnection from
|
|
|
|
|
* @save_to_disk: %TRUE to save the connection to disk immediately, %FALSE to
|
|
|
|
|
* not save to disk
|
|
|
|
|
* @error: on return, a location to store any errors that may occur
|
|
|
|
|
*
|
2016-04-13 13:33:04 +02:00
|
|
|
* Creates a new #NMSettingsConnection for the given source @connection.
|
2013-10-17 13:04:37 -05:00
|
|
|
* The returned object is owned by @self and the caller must reference
|
|
|
|
|
* the object to continue using it.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the new #NMSettingsConnection or %NULL
|
|
|
|
|
*/
|
2013-06-20 19:39:25 +02:00
|
|
|
NMSettingsConnection *
|
2013-08-27 14:51:16 +02:00
|
|
|
nm_settings_add_connection (NMSettings *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean save_to_disk,
|
|
|
|
|
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)) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
|
2010-10-29 23:13:57 -05:00
|
|
|
GError *add_error = NULL;
|
2009-03-02 12:58:45 -05:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
added = nm_settings_plugin_add_connection (plugin, connection, save_to_disk, &add_error);
|
2010-10-29 22:10:32 -05:00
|
|
|
if (added) {
|
2015-04-23 09:43:20 -05:00
|
|
|
claim_connection (self, added);
|
2010-10-29 22:10:32 -05:00
|
|
|
return added;
|
|
|
|
|
}
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGD ("Failed to add %s/'%s': %s",
|
|
|
|
|
nm_connection_get_uuid (connection),
|
|
|
|
|
nm_connection_get_id (connection),
|
|
|
|
|
add_error->message);
|
2013-04-12 16:09:29 -05:00
|
|
|
g_clear_error (&add_error);
|
2010-10-29 22:10:32 -05:00
|
|
|
}
|
2013-04-12 16:09:29 -05:00
|
|
|
|
2014-10-15 15:27:25 -04:00
|
|
|
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
2013-04-12 16:09:29 -05:00
|
|
|
"No plugin supported adding this connection");
|
2010-10-29 22:10:32 -05:00
|
|
|
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,
|
2013-11-05 14:36:38 -05:00
|
|
|
NMAuthSubject *subject)
|
2011-11-15 13:43:29 +01:00
|
|
|
{
|
|
|
|
|
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.
|
|
|
|
|
*/
|
2014-08-13 14:34:29 -04:00
|
|
|
for_agent = nm_simple_connection_new_clone (NM_CONNECTION (connection));
|
2011-11-15 13:43:29 +01:00
|
|
|
nm_connection_clear_secrets_with_flags (for_agent,
|
|
|
|
|
secrets_filter_cb,
|
|
|
|
|
GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
|
2015-09-07 16:12:04 +02:00
|
|
|
nm_agent_manager_save_secrets (priv->agent_mgr,
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_connection_get_path (NM_CONNECTION (connection)),
|
2015-09-07 16:12:04 +02:00
|
|
|
for_agent,
|
|
|
|
|
subject);
|
2011-11-15 13:43:29 +01:00
|
|
|
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,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-11-17 17:53:37 -06:00
|
|
|
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;
|
2013-04-12 16:09:29 -05:00
|
|
|
GError *error = NULL;
|
2015-04-22 15:08:21 +02:00
|
|
|
NMConnection *connection = NULL;
|
2011-01-26 11:38:12 -06:00
|
|
|
NMSettingsConnection *added = NULL;
|
2011-01-10 23:39:12 -06:00
|
|
|
NMSettingsAddCallback callback;
|
|
|
|
|
gpointer callback_data;
|
2013-11-05 14:36:38 -05:00
|
|
|
NMAuthSubject *subject;
|
2011-02-11 17:06:57 -06:00
|
|
|
const char *perm;
|
2013-04-12 16:09:29 -05:00
|
|
|
gboolean save_to_disk;
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2013-07-29 11:37:18 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2010-11-17 17:53:37 -06:00
|
|
|
priv->auths = g_slist_remove (priv->auths, chain);
|
2009-10-21 14:19:01 -07:00
|
|
|
|
2012-10-08 12:52:15 -05: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
|
|
|
if (chain_error) {
|
|
|
|
|
error = g_error_new (NM_SETTINGS_ERROR,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_SETTINGS_ERROR_FAILED,
|
2010-11-17 17:53:37 -06:00
|
|
|
"Error checking authorization: %s",
|
2016-02-28 16:25:36 +01:00
|
|
|
chain_error->message);
|
2012-10-08 12:52:15 -05:00
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
2013-02-22 18:20:34 -06:00
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Insufficient privileges.");
|
2012-10-08 12:52:15 -05:00
|
|
|
} else {
|
|
|
|
|
/* Authorized */
|
|
|
|
|
connection = nm_auth_chain_get_data (chain, "connection");
|
|
|
|
|
g_assert (connection);
|
2013-04-12 16:09:29 -05:00
|
|
|
save_to_disk = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "save-to-disk"));
|
2013-08-27 14:51:16 +02:00
|
|
|
added = nm_settings_add_connection (self, connection, save_to_disk, &error);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
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");
|
2013-11-05 14:36:38 -05:00
|
|
|
subject = nm_auth_chain_get_data (chain, "subject");
|
2011-01-10 23:39:12 -06:00
|
|
|
|
2015-07-15 14:44:45 +02:00
|
|
|
callback (self, added, error, context, subject, 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 */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!error && added && nm_settings_has_connection (self, added))
|
2013-11-05 14:36:38 -05:00
|
|
|
send_agent_owned_secrets (self, added, subject);
|
2011-11-15 13:43:29 +01:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2012-03-16 17:56:32 -05:00
|
|
|
/* FIXME: remove if/when kernel supports adhoc wpa */
|
|
|
|
|
static gboolean
|
|
|
|
|
is_adhoc_wpa (NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWireless *s_wifi;
|
|
|
|
|
NMSettingWirelessSecurity *s_wsec;
|
|
|
|
|
const char *mode, *key_mgmt;
|
|
|
|
|
|
|
|
|
|
/* The kernel doesn't support Ad-Hoc WPA connections well at this time,
|
|
|
|
|
* and turns them into open networks. It's been this way since at least
|
|
|
|
|
* 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
s_wifi = nm_connection_get_setting_wireless (connection);
|
2012-03-23 09:59:20 -05:00
|
|
|
if (!s_wifi)
|
|
|
|
|
return FALSE;
|
2012-03-16 17:56:32 -05:00
|
|
|
|
|
|
|
|
mode = nm_setting_wireless_get_mode (s_wifi);
|
|
|
|
|
if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) != 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
|
|
|
|
if (!s_wsec)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
|
|
|
|
|
if (g_strcmp0 (key_mgmt, "wpa-none") != 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
void
|
2013-08-27 14:51:16 +02:00
|
|
|
nm_settings_add_connection_dbus (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean save_to_disk,
|
|
|
|
|
GDBusMethodInvocation *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;
|
2013-07-29 11:37:18 -05:00
|
|
|
NMAuthSubject *subject = NULL;
|
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
|
|
|
char *error_desc = NULL;
|
|
|
|
|
const char *perm;
|
2011-02-09 18:41:48 -06:00
|
|
|
|
2013-07-29 11:37:18 -05:00
|
|
|
g_return_if_fail (connection != NULL);
|
|
|
|
|
g_return_if_fail (context != NULL);
|
|
|
|
|
|
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",
|
2016-02-28 16:25:36 +01:00
|
|
|
tmp_error->message);
|
2011-02-09 18:41:48 -06:00
|
|
|
g_error_free (tmp_error);
|
2013-07-29 11:37:18 -05:00
|
|
|
goto done;
|
2011-02-09 18:41:48 -06:00
|
|
|
}
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2012-03-16 17:56:32 -05:00
|
|
|
/* The kernel doesn't support Ad-Hoc WPA connections well at this time,
|
|
|
|
|
* and turns them into open networks. It's been this way since at least
|
|
|
|
|
* 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks.
|
|
|
|
|
*/
|
|
|
|
|
if (is_adhoc_wpa (connection)) {
|
|
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
|
|
|
|
"WPA Ad-Hoc disabled due to kernel bugs");
|
2013-07-29 11:37:18 -05:00
|
|
|
goto done;
|
2012-03-16 17:56:32 -05:00
|
|
|
}
|
|
|
|
|
|
2008-09-18 14:46:57 +00:00
|
|
|
/* Do any of the plugins support adding? */
|
2015-04-16 08:52:20 -04:00
|
|
|
if (!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS)) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_SETTINGS_ERROR_NOT_SUPPORTED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"None of the registered plugins support add.");
|
2013-07-29 11:37:18 -05:00
|
|
|
goto done;
|
2008-05-09 06:33:30 +00:00
|
|
|
}
|
2008-04-22 14:48:02 +00:00
|
|
|
|
2014-08-14 13:34:57 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2013-07-29 11:37:18 -05:00
|
|
|
if (!subject) {
|
2012-12-15 10:48:11 -06:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:37:18 -05:00
|
|
|
"Unable to determine UID of request.");
|
|
|
|
|
goto done;
|
2011-02-11 17:06:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ensure the caller's username exists in the connection's permissions,
|
|
|
|
|
* or that the permissions is empty (ie, visible by everyone).
|
|
|
|
|
*/
|
2014-08-14 13:34:57 +02:00
|
|
|
if (!nm_auth_is_subject_in_acl (connection,
|
|
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2012-12-16 11:38:04 -06:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
2013-07-29 11:37:18 -05:00
|
|
|
goto done;
|
2011-02-11 17:06:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
2012-12-16 12:30:41 -06:00
|
|
|
/* Validate the user request */
|
2013-07-29 11:37:18 -05:00
|
|
|
chain = nm_auth_chain_new_subject (subject, context, pk_add_cb, self);
|
|
|
|
|
if (!chain) {
|
2012-12-16 12:30:41 -06:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:37:18 -05:00
|
|
|
"Unable to authenticate the request.");
|
|
|
|
|
goto done;
|
2012-12-16 12:30:41 -06:00
|
|
|
}
|
2013-07-29 11:37:18 -05:00
|
|
|
|
|
|
|
|
priv->auths = g_slist_append (priv->auths, chain);
|
|
|
|
|
nm_auth_chain_add_call (chain, perm, TRUE);
|
|
|
|
|
nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL);
|
|
|
|
|
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);
|
2013-11-05 14:36:38 -05:00
|
|
|
nm_auth_chain_set_data (chain, "subject", g_object_ref (subject), g_object_unref);
|
2013-07-29 11:37:18 -05:00
|
|
|
nm_auth_chain_set_data (chain, "save-to-disk", GUINT_TO_POINTER (save_to_disk), NULL);
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (error)
|
2015-07-15 14:44:45 +02:00
|
|
|
callback (self, NULL, error, context, subject, user_data);
|
2013-07-29 11:37:18 -05:00
|
|
|
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
g_clear_object (&subject);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2013-04-12 16:09:29 -05:00
|
|
|
impl_settings_add_connection_add_cb (NMSettings *self,
|
|
|
|
|
NMSettingsConnection *connection,
|
|
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2015-07-15 14:44:45 +02:00
|
|
|
NMAuthSubject *subject,
|
2013-04-12 16:09:29 -05:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-07-15 14:44:45 +02:00
|
|
|
if (error) {
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_gerror (context, error);
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message);
|
2015-07-15 14:44:45 +02:00
|
|
|
} else {
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (
|
2015-07-14 16:53:24 +02:00
|
|
|
context,
|
|
|
|
|
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL,
|
2015-07-15 14:44:45 +02:00
|
|
|
subject, NULL);
|
|
|
|
|
}
|
2013-04-12 16:09:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_settings_add_connection_helper (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
GVariant *settings,
|
|
|
|
|
gboolean save_to_disk)
|
2011-01-10 23:39:12 -06:00
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
2016-03-17 10:34:44 +01:00
|
|
|
connection = _nm_simple_connection_new_from_dbus (settings,
|
2016-03-23 15:58:53 +01:00
|
|
|
NM_SETTING_PARSE_FLAGS_STRICT
|
|
|
|
|
| NM_SETTING_PARSE_FLAGS_NORMALIZE,
|
2016-03-17 10:34:44 +01:00
|
|
|
&error);
|
2015-11-10 14:46:57 +01:00
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
if (connection) {
|
2015-11-10 14:46:57 +01:00
|
|
|
if (!nm_connection_verify_secrets (connection, &error))
|
|
|
|
|
goto failure;
|
|
|
|
|
|
2013-08-27 14:51:16 +02:00
|
|
|
nm_settings_add_connection_dbus (self,
|
2014-08-13 14:34:29 -04:00
|
|
|
connection,
|
|
|
|
|
save_to_disk,
|
|
|
|
|
context,
|
|
|
|
|
impl_settings_add_connection_add_cb,
|
|
|
|
|
NULL);
|
2011-01-10 23:39:12 -06:00
|
|
|
g_object_unref (connection);
|
2015-11-10 14:46:57 +01:00
|
|
|
return;
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
2015-11-10 14:46:57 +01:00
|
|
|
|
|
|
|
|
failure:
|
|
|
|
|
g_assert (error);
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2010-07-29 00:11:21 -04:00
|
|
|
}
|
|
|
|
|
|
2013-04-12 16:09:29 -05:00
|
|
|
static void
|
|
|
|
|
impl_settings_add_connection (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
GVariant *settings)
|
2013-04-12 16:09:29 -05:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
impl_settings_add_connection_helper (self, context, settings, TRUE);
|
2013-04-12 16:09:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_settings_add_connection_unsaved (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
GVariant *settings)
|
2013-04-12 16:09:29 -05:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
impl_settings_add_connection_helper (self, context, settings, FALSE);
|
2013-04-12 16:09:29 -05:00
|
|
|
}
|
|
|
|
|
|
2013-10-31 15:17:33 -04:00
|
|
|
static void
|
|
|
|
|
impl_settings_load_connections (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
char **filenames)
|
2013-10-31 15:17:33 -04:00
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
GPtrArray *failures;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
int i;
|
|
|
|
|
|
2016-08-23 09:38:40 +02:00
|
|
|
/* The permission is already enforced by the D-Bus daemon, but we ensure
|
|
|
|
|
* that the caller is still alive so that clients are forced to wait and
|
|
|
|
|
* we'll be able to switch to polkit without breaking behavior.
|
|
|
|
|
*/
|
|
|
|
|
if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (),
|
|
|
|
|
context,
|
|
|
|
|
G_MAXULONG,
|
|
|
|
|
NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED))
|
|
|
|
|
return;
|
|
|
|
|
|
2013-10-31 15:17:33 -04:00
|
|
|
failures = g_ptr_array_new ();
|
|
|
|
|
|
|
|
|
|
for (i = 0; filenames[i]; i++) {
|
|
|
|
|
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
|
2013-10-31 15:17:33 -04:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
if (nm_settings_plugin_load_connection (plugin, filenames[i]))
|
2013-10-31 15:17:33 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!iter) {
|
|
|
|
|
if (!g_path_is_absolute (filenames[i]))
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("connection filename '%s' is not an absolute path", filenames[i]);
|
2013-10-31 15:17:33 -04:00
|
|
|
g_ptr_array_add (failures, (char *) filenames[i]);
|
|
|
|
|
}
|
2013-05-23 19:05:40 -03:00
|
|
|
}
|
|
|
|
|
|
2013-10-31 15:17:33 -04:00
|
|
|
g_ptr_array_add (failures, NULL);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (
|
|
|
|
|
context,
|
|
|
|
|
g_variant_new ("(b^as)",
|
|
|
|
|
failures->len == 1,
|
|
|
|
|
failures->pdata));
|
2013-10-31 15:17:33 -04:00
|
|
|
g_ptr_array_unref (failures);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_settings_reload_connections (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context)
|
2013-10-31 15:17:33 -04:00
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
2016-08-23 09:38:40 +02:00
|
|
|
/* The permission is already enforced by the D-Bus daemon, but we ensure
|
|
|
|
|
* that the caller is still alive so that clients are forced to wait and
|
|
|
|
|
* we'll be able to switch to polkit without breaking behavior.
|
|
|
|
|
*/
|
|
|
|
|
if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (),
|
|
|
|
|
context,
|
|
|
|
|
G_MAXULONG,
|
|
|
|
|
NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED))
|
|
|
|
|
return;
|
|
|
|
|
|
2013-12-05 08:50:10 -05:00
|
|
|
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
2015-04-16 08:52:20 -04:00
|
|
|
NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
|
2013-05-23 19:05:40 -03:00
|
|
|
|
2015-04-16 08:52:20 -04:00
|
|
|
nm_settings_plugin_reload_connections (plugin);
|
2013-05-23 19:05:40 -03:00
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE));
|
2013-05-23 19:05:40 -03:00
|
|
|
}
|
|
|
|
|
|
2016-02-18 18:19:30 +01:00
|
|
|
typedef struct {
|
|
|
|
|
char *hostname;
|
|
|
|
|
NMSettingsSetHostnameCb cb;
|
|
|
|
|
gpointer user_data;
|
|
|
|
|
} SetHostnameInfo;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_transient_hostname_done (GObject *object,
|
|
|
|
|
GAsyncResult *res,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GDBusProxy *proxy = G_DBUS_PROXY (object);
|
|
|
|
|
gs_free SetHostnameInfo *info = user_data;
|
|
|
|
|
gs_unref_variant GVariant *result = NULL;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
result = g_dbus_proxy_call_finish (proxy, res, &error);
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
_LOGW ("couldn't set the system hostname to '%s' using hostnamed: %s",
|
|
|
|
|
info->hostname, error->message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info->cb (info->hostname, !error, info->user_data);
|
|
|
|
|
g_free (info->hostname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_settings_set_transient_hostname (NMSettings *self,
|
|
|
|
|
const char *hostname,
|
|
|
|
|
NMSettingsSetHostnameCb cb,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv;
|
|
|
|
|
SetHostnameInfo *info;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_SETTINGS (self));
|
|
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (!priv->hostname.hostnamed_proxy) {
|
|
|
|
|
cb (hostname, FALSE, user_data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info = g_new0 (SetHostnameInfo, 1);
|
|
|
|
|
info->hostname = g_strdup (hostname);
|
|
|
|
|
info->cb = cb;
|
|
|
|
|
info->user_data = user_data;
|
|
|
|
|
|
|
|
|
|
g_dbus_proxy_call (priv->hostname.hostnamed_proxy,
|
|
|
|
|
"SetHostname",
|
|
|
|
|
g_variant_new ("(sb)", hostname, FALSE),
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
-1,
|
|
|
|
|
NULL,
|
|
|
|
|
set_transient_hostname_done,
|
|
|
|
|
info);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
static gboolean
|
|
|
|
|
write_hostname (NMSettingsPrivate *priv, const char *hostname)
|
|
|
|
|
{
|
|
|
|
|
char *hostname_eol;
|
|
|
|
|
gboolean ret;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
2016-04-27 14:14:00 +02:00
|
|
|
const char *file = HOSTNAME_FILE;
|
2016-01-29 15:48:23 +01:00
|
|
|
gs_free char *link_path = NULL;
|
2015-03-23 17:36:34 +01:00
|
|
|
gs_unref_variant GVariant *var = NULL;
|
2016-01-29 15:48:23 +01:00
|
|
|
struct stat file_stat;
|
2015-03-23 09:15:47 +01:00
|
|
|
#if HAVE_SELINUX
|
|
|
|
|
security_context_t se_ctx_prev = NULL, se_ctx = NULL;
|
|
|
|
|
mode_t st_mode = 0;
|
2015-03-23 17:36:34 +01:00
|
|
|
#endif
|
2015-03-23 09:15:47 +01:00
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
if (priv->hostname.hostnamed_proxy) {
|
|
|
|
|
var = g_dbus_proxy_call_sync (priv->hostname.hostnamed_proxy,
|
|
|
|
|
"SetStaticHostname",
|
|
|
|
|
g_variant_new ("(sb)", hostname, FALSE),
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
-1,
|
|
|
|
|
NULL,
|
|
|
|
|
&error);
|
|
|
|
|
if (error)
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not set hostname: %s", error->message);
|
2015-03-23 17:36:34 +01:00
|
|
|
|
|
|
|
|
return !error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-26 22:48:41 +00:00
|
|
|
/* If the hostname file is a symbolic link, follow it to find where the
|
|
|
|
|
* real file is located, otherwise g_file_set_contents will attempt to
|
|
|
|
|
* replace the link with a plain file.
|
|
|
|
|
*/
|
2016-01-29 15:48:23 +01:00
|
|
|
if ( lstat (file, &file_stat) == 0
|
|
|
|
|
&& S_ISLNK (file_stat.st_mode)
|
2016-04-27 15:03:50 +02:00
|
|
|
&& (link_path = nm_utils_read_link_absolute (file, NULL)))
|
2016-01-26 22:48:41 +00:00
|
|
|
file = link_path;
|
|
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
#if HAVE_SELINUX
|
2015-03-23 09:15:47 +01:00
|
|
|
/* Get default context for hostname file and set it for fscreate */
|
|
|
|
|
if (stat (file, &file_stat) == 0)
|
|
|
|
|
st_mode = file_stat.st_mode;
|
|
|
|
|
matchpathcon (file, st_mode, &se_ctx);
|
|
|
|
|
matchpathcon_fini ();
|
|
|
|
|
getfscreatecon (&se_ctx_prev);
|
|
|
|
|
setfscreatecon (se_ctx);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined (HOSTNAME_PERSIST_GENTOO)
|
|
|
|
|
hostname_eol = g_strdup_printf ("#Generated by NetworkManager\n"
|
|
|
|
|
"hostname=\"%s\"\n", hostname);
|
|
|
|
|
#else
|
|
|
|
|
hostname_eol = g_strdup_printf ("%s\n", hostname);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ret = g_file_set_contents (file, hostname_eol, -1, &error);
|
|
|
|
|
|
|
|
|
|
#if HAVE_SELINUX
|
|
|
|
|
/* Restore previous context and cleanup */
|
|
|
|
|
setfscreatecon (se_ctx_prev);
|
|
|
|
|
freecon (se_ctx);
|
|
|
|
|
freecon (se_ctx_prev);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
g_free (hostname_eol);
|
|
|
|
|
|
|
|
|
|
if (!ret) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGW ("could not save hostname to %s: %s", file, error->message);
|
2015-03-23 09:15:47 +01:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
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,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-11-17 17:44:33 -06:00
|
|
|
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;
|
2009-07-23 09:20:52 -04:00
|
|
|
GError *error = NULL;
|
2010-11-17 17:44:33 -06:00
|
|
|
const char *hostname;
|
|
|
|
|
|
2013-07-29 11:37:18 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
priv->auths = g_slist_remove (priv->auths, chain);
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
|
|
|
|
|
|
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,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_SETTINGS_ERROR_FAILED,
|
2010-11-17 17:44:33 -06:00
|
|
|
"Error checking authorization: %s",
|
2016-02-28 16:25:36 +01:00
|
|
|
chain_error->message);
|
2012-10-08 12:52:15 -05:00
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
2010-10-27 20:38:26 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
2013-02-22 18:20:34 -06:00
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
2009-07-23 09:20:52 -04:00
|
|
|
"Insufficient privileges.");
|
2012-10-08 12:52:15 -05:00
|
|
|
} else {
|
|
|
|
|
hostname = nm_auth_chain_get_data (chain, "hostname");
|
2008-09-18 14:46:57 +00:00
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
if (!write_hostname (priv, hostname)) {
|
2012-10-08 12:52:15 -05:00
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_SETTINGS_ERROR_FAILED,
|
2012-10-08 12:52:15 -05:00
|
|
|
"Saving the hostname failed.");
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:44:33 -06:00
|
|
|
if (error)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2010-11-17 17:44:33 -06:00
|
|
|
else
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
2010-11-17 17:44:33 -06:00
|
|
|
|
|
|
|
|
nm_auth_chain_unref (chain);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
2013-10-23 21:41:33 -05:00
|
|
|
static gboolean
|
|
|
|
|
validate_hostname (const char *hostname)
|
|
|
|
|
{
|
|
|
|
|
const char *p;
|
|
|
|
|
gboolean dot = TRUE;
|
|
|
|
|
|
|
|
|
|
if (!hostname || !hostname[0])
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
for (p = hostname; *p; p++) {
|
|
|
|
|
if (*p == '.') {
|
|
|
|
|
if (dot)
|
|
|
|
|
return FALSE;
|
|
|
|
|
dot = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
if (!g_ascii_isalnum (*p) && (*p != '-') && (*p != '_'))
|
|
|
|
|
return FALSE;
|
|
|
|
|
dot = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dot)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return (p - hostname <= HOST_NAME_MAX);
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
impl_settings_save_hostname (NMSettings *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *hostname)
|
2009-07-23 09:20:52 -04:00
|
|
|
{
|
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;
|
|
|
|
|
|
2013-10-23 21:41:33 -05:00
|
|
|
/* Minimal validation of the hostname */
|
|
|
|
|
if (!validate_hostname (hostname)) {
|
|
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_SETTINGS_ERROR_INVALID_HOSTNAME,
|
2013-10-23 21:41:33 -05:00
|
|
|
"The hostname was too long or contained invalid characters.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-29 11:37:18 -05:00
|
|
|
chain = nm_auth_chain_new_context (context, pk_hostname_cb, self);
|
|
|
|
|
if (!chain) {
|
|
|
|
|
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
|
|
|
|
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to authenticate the request.");
|
|
|
|
|
goto done;
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
2013-07-29 11:37:18 -05:00
|
|
|
|
|
|
|
|
priv->auths = g_slist_append (priv->auths, chain);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE);
|
|
|
|
|
nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free);
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (error)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2008-09-18 14:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
static void
|
|
|
|
|
hostname_maybe_changed (NMSettings *settings)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (settings);
|
|
|
|
|
char *new_hostname;
|
|
|
|
|
|
|
|
|
|
new_hostname = nm_settings_get_hostname (settings);
|
|
|
|
|
|
|
|
|
|
if ( (new_hostname && !priv->hostname.value)
|
|
|
|
|
|| (!new_hostname && priv->hostname.value)
|
|
|
|
|
|| (priv->hostname.value && new_hostname && strcmp (priv->hostname.value, new_hostname))) {
|
|
|
|
|
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("hostname changed from %s%s%s to %s%s%s",
|
|
|
|
|
NM_PRINT_FMT_QUOTED (priv->hostname.value, "\"", priv->hostname.value, "\"", "(none)"),
|
|
|
|
|
NM_PRINT_FMT_QUOTED (new_hostname, "\"", new_hostname, "\"", "(none)"));
|
2015-03-23 09:15:47 +01:00
|
|
|
g_free (priv->hostname.value);
|
|
|
|
|
priv->hostname.value = new_hostname;
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (settings, PROP_HOSTNAME);
|
2015-03-23 09:15:47 +01:00
|
|
|
} else
|
|
|
|
|
g_free (new_hostname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
hostname_file_changed_cb (GFileMonitor *monitor,
|
|
|
|
|
GFile *file,
|
|
|
|
|
GFile *other_file,
|
|
|
|
|
GFileMonitorEvent event_type,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
hostname_maybe_changed (user_data);
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
static gboolean
|
2013-03-12 13:14:54 -04:00
|
|
|
have_connection_for_device (NMSettings *self, 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;
|
2014-07-30 10:57:45 -04:00
|
|
|
const char *setting_hwaddr;
|
2016-06-15 13:15:07 +02:00
|
|
|
const char *perm_hw_addr;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
2013-03-12 13:14:54 -04:00
|
|
|
|
2016-10-13 18:52:12 +02:00
|
|
|
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
2014-09-24 14:42:51 -05:00
|
|
|
if (!nm_device_check_connection_compatible (device, connection))
|
|
|
|
|
continue;
|
|
|
|
|
|
2011-04-19 00:26:07 -05:00
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2013-04-11 10:41:49 -04:00
|
|
|
iface = nm_setting_connection_get_interface_name (s_con);
|
|
|
|
|
if (iface && strcmp (iface, nm_device_get_iface (device)) != 0)
|
|
|
|
|
continue;
|
2011-10-18 13:48:45 +02:00
|
|
|
|
2013-04-11 10:41:49 -04:00
|
|
|
ctype = nm_setting_connection_get_connection_type (s_con);
|
2011-04-19 00:26:07 -05:00
|
|
|
if ( strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)
|
|
|
|
|
&& 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);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2011-04-19 00:26:07 -05:00
|
|
|
if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) {
|
2013-04-11 10:41:49 -04:00
|
|
|
/* No wired setting; therefore the PPPoE connection applies to any device */
|
|
|
|
|
return TRUE;
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2013-03-21 15:55:46 -04:00
|
|
|
g_assert (s_wired != NULL);
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
setting_hwaddr = nm_setting_wired_get_mac_address (s_wired);
|
|
|
|
|
if (setting_hwaddr) {
|
2009-07-09 11:06:31 -04:00
|
|
|
/* A connection mac-locked to this device */
|
2016-06-15 13:15:07 +02:00
|
|
|
if ( perm_hw_addr
|
|
|
|
|
&& nm_utils_hwaddr_matches (setting_hwaddr, -1, perm_hw_addr, -1))
|
2013-04-11 10:41:49 -04:00
|
|
|
return TRUE;
|
2009-07-09 11:06:31 -04:00
|
|
|
} else {
|
|
|
|
|
/* A connection that applies to any wired device */
|
2013-04-11 10:41:49 -04:00
|
|
|
return TRUE;
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
/* See if there's a known non-NetworkManager configuration for the device */
|
|
|
|
|
if (nm_device_spec_match_list (device, priv->unrecognized_specs))
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
2013-04-11 10:41:49 -04:00
|
|
|
return FALSE;
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2013-11-12 14:26:20 -06:00
|
|
|
static void default_wired_clear_tag (NMSettings *self,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
NMSettingsConnection *connection,
|
|
|
|
|
gboolean add_to_no_auto_default);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
|
|
|
|
static void
|
2013-11-12 14:26:20 -06:00
|
|
|
default_wired_connection_removed_cb (NMSettingsConnection *connection, NMSettings *self)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2013-03-21 15:55:46 -04:00
|
|
|
NMDevice *device;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2013-11-12 14:26:20 -06:00
|
|
|
/* 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
|
2013-03-12 13:14:54 -04:00
|
|
|
* connection for that device again.
|
|
|
|
|
*/
|
2017-02-02 18:53:49 +01:00
|
|
|
device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ());
|
2013-11-12 14:26:20 -06:00
|
|
|
if (device)
|
|
|
|
|
default_wired_clear_tag (self, device, connection, TRUE);
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2009-10-05 17:46:16 -07:00
|
|
|
static void
|
2016-04-13 15:47:25 +02:00
|
|
|
default_wired_connection_updated_by_user_cb (NMSettingsConnection *connection, gboolean by_user, NMSettings *self)
|
2009-10-05 17:46:16 -07:00
|
|
|
{
|
2013-11-12 14:26:20 -06:00
|
|
|
NMDevice *device;
|
|
|
|
|
|
2016-04-13 15:47:25 +02:00
|
|
|
if (!by_user)
|
|
|
|
|
return;
|
|
|
|
|
|
2013-11-12 14:26:20 -06:00
|
|
|
/* The connection has been changed by the user, it should no longer be
|
|
|
|
|
* considered a default wired connection, and should no longer affect
|
|
|
|
|
* the no-auto-default configuration option.
|
|
|
|
|
*/
|
2017-02-02 18:53:49 +01:00
|
|
|
device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ());
|
2013-11-12 14:26:20 -06:00
|
|
|
if (device)
|
|
|
|
|
default_wired_clear_tag (self, device, connection, FALSE);
|
2009-10-05 17:46:16 -07:00
|
|
|
}
|
|
|
|
|
|
2011-09-20 21:49:35 -05:00
|
|
|
static void
|
2013-11-12 14:26:20 -06:00
|
|
|
default_wired_clear_tag (NMSettings *self,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
NMSettingsConnection *connection,
|
|
|
|
|
gboolean add_to_no_auto_default)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2013-11-12 14:26:20 -06:00
|
|
|
g_return_if_fail (NM_IS_SETTINGS (self));
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (device));
|
|
|
|
|
g_return_if_fail (NM_IS_CONNECTION (connection));
|
2017-02-02 18:53:49 +01:00
|
|
|
g_return_if_fail (device == g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()));
|
|
|
|
|
g_return_if_fail (connection == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ()));
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL);
|
|
|
|
|
g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL);
|
2009-10-05 17:46:16 -07:00
|
|
|
|
2013-11-12 14:26:20 -06:00
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_removed_cb), self);
|
2013-12-11 21:30:36 +01:00
|
|
|
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self);
|
2011-09-20 21:49:35 -05:00
|
|
|
|
2013-11-12 14:26:20 -06:00
|
|
|
if (add_to_no_auto_default)
|
2015-01-07 17:09:52 +01:00
|
|
|
nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device);
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
static void
|
|
|
|
|
device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2013-11-12 14:26:20 -06:00
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingsConnection *added;
|
|
|
|
|
GError *error = NULL;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
if (!nm_device_is_real (device))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (device,
|
|
|
|
|
G_CALLBACK (device_realized),
|
|
|
|
|
self);
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
/* If the device isn't managed or it already has a default wired connection,
|
|
|
|
|
* ignore it.
|
|
|
|
|
*/
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
if ( !nm_device_get_managed (device, FALSE)
|
2017-02-02 18:53:49 +01:00
|
|
|
|| g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())
|
2014-09-08 16:11:51 -05:00
|
|
|
|| have_connection_for_device (self, device))
|
2009-07-09 11:06:31 -04:00
|
|
|
return;
|
|
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
connection = nm_device_new_default_connection (device);
|
|
|
|
|
if (!connection)
|
2013-11-12 14:26:20 -06:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Add the connection */
|
|
|
|
|
added = nm_settings_add_connection (self, connection, FALSE, &error);
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
|
|
|
|
|
if (!added) {
|
2016-04-25 21:27:10 +02:00
|
|
|
if (!g_error_matches (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS)) {
|
|
|
|
|
_LOGW ("(%s) couldn't create default wired connection: %s",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
error->message);
|
|
|
|
|
}
|
2013-11-12 14:26:20 -06:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
g_object_set_qdata (G_OBJECT (added), _default_wired_device_quark (), device);
|
|
|
|
|
g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), added);
|
2013-11-12 14:26:20 -06:00
|
|
|
|
2016-04-13 15:47:25 +02:00
|
|
|
g_signal_connect (added, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL,
|
2013-12-11 21:30:36 +01:00
|
|
|
G_CALLBACK (default_wired_connection_updated_by_user_cb), self);
|
2013-11-12 14:26:20 -06:00
|
|
|
g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED,
|
|
|
|
|
G_CALLBACK (default_wired_connection_removed_cb), self);
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("(%s): created default wired connection '%s'",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
nm_settings_connection_get_id (added));
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
void
|
|
|
|
|
nm_settings_device_added (NMSettings *self, NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
if (nm_device_is_real (device))
|
|
|
|
|
device_realized (device, NULL, self);
|
|
|
|
|
else {
|
|
|
|
|
g_signal_connect_after (device, "notify::" NM_DEVICE_REAL,
|
|
|
|
|
G_CALLBACK (device_realized),
|
|
|
|
|
self);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-09 11:06:31 -04:00
|
|
|
void
|
2013-11-14 11:33:12 -06:00
|
|
|
nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quitting)
|
2009-07-09 11:06:31 -04:00
|
|
|
{
|
2013-11-12 14:26:20 -06:00
|
|
|
NMSettingsConnection *connection;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
g_signal_handlers_disconnect_by_func (device,
|
|
|
|
|
G_CALLBACK (device_realized),
|
|
|
|
|
self);
|
|
|
|
|
|
2017-02-02 18:53:49 +01:00
|
|
|
connection = g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ());
|
2013-11-12 14:26:20 -06:00
|
|
|
if (connection) {
|
|
|
|
|
default_wired_clear_tag (self, device, connection, FALSE);
|
2013-11-14 11:33:12 -06:00
|
|
|
|
|
|
|
|
/* Don't delete the default wired connection on shutdown, so that it
|
|
|
|
|
* remains up and can be assumed if NM starts again.
|
|
|
|
|
*/
|
|
|
|
|
if (quitting == FALSE)
|
|
|
|
|
nm_settings_connection_delete (connection, NULL, NULL);
|
2013-11-12 14:26:20 -06:00
|
|
|
}
|
2009-07-09 11:06:31 -04:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2010-10-27 15:47:10 -05:00
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
gboolean
|
|
|
|
|
nm_settings_get_startup_complete (NMSettings *self)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
return priv->startup_complete;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-12-18 16:04:07 -05:00
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
static void
|
|
|
|
|
hostnamed_properties_changed (GDBusProxy *proxy,
|
|
|
|
|
GVariant *changed_properties,
|
|
|
|
|
char **invalidated_properties,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2016-04-13 13:33:04 +02:00
|
|
|
NMSettings *self = user_data;
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2015-03-23 17:36:34 +01:00
|
|
|
GVariant *v_hostname;
|
|
|
|
|
const char *hostname;
|
|
|
|
|
|
|
|
|
|
v_hostname = g_dbus_proxy_get_cached_property (priv->hostname.hostnamed_proxy,
|
|
|
|
|
"StaticHostname");
|
|
|
|
|
if (!v_hostname)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
hostname = g_variant_get_string (v_hostname, NULL);
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0 (priv->hostname.value, hostname) != 0) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("hostname changed from %s%s%s to %s%s%s",
|
|
|
|
|
NM_PRINT_FMT_QUOTED (priv->hostname.value, "\"", priv->hostname.value, "\"", "(none)"),
|
|
|
|
|
NM_PRINT_FMT_QUOTED (hostname, "\"", hostname, "\"", "(none)"));
|
2015-03-23 17:36:34 +01:00
|
|
|
g_free (priv->hostname.value);
|
|
|
|
|
priv->hostname.value = g_strdup (hostname);
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_HOSTNAME);
|
2017-03-08 14:11:22 +01:00
|
|
|
nm_dispatcher_call_hostname (NULL, NULL, NULL);
|
2015-03-23 17:36:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_variant_unref (v_hostname);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 17:26:22 +01:00
|
|
|
static void
|
|
|
|
|
setup_hostname_file_monitors (NMSettings *self)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2015-03-23 17:26:22 +01:00
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
2015-03-23 09:15:47 +01:00
|
|
|
GFileMonitor *monitor;
|
2016-04-27 00:45:16 +01:00
|
|
|
const char *path = HOSTNAME_FILE;
|
|
|
|
|
char *link_path = NULL;
|
|
|
|
|
struct stat file_stat;
|
2015-03-23 17:26:22 +01:00
|
|
|
GFile *file;
|
2011-02-02 20:32:15 -06:00
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
priv->hostname.value = nm_settings_get_hostname (self);
|
|
|
|
|
|
2016-04-27 00:45:16 +01:00
|
|
|
/* resolve the path to the hostname file if it is a symbolic link */
|
|
|
|
|
if ( lstat(path, &file_stat) == 0
|
|
|
|
|
&& S_ISLNK (file_stat.st_mode)
|
|
|
|
|
&& (link_path = nm_utils_read_link_absolute (path, NULL))) {
|
|
|
|
|
path = link_path;
|
|
|
|
|
if ( lstat(link_path, &file_stat) == 0
|
|
|
|
|
&& S_ISLNK (file_stat.st_mode)) {
|
|
|
|
|
_LOGW ("only one level of symbolic link indirection is allowed when monitoring "
|
|
|
|
|
HOSTNAME_FILE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
/* monitor changes to hostname file */
|
2016-04-27 00:45:16 +01:00
|
|
|
file = g_file_new_for_path (path);
|
2015-03-23 09:15:47 +01:00
|
|
|
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
|
|
|
|
g_object_unref (file);
|
2016-04-27 00:45:16 +01:00
|
|
|
g_free(link_path);
|
2015-03-23 09:15:47 +01:00
|
|
|
if (monitor) {
|
|
|
|
|
priv->hostname.monitor_id = g_signal_connect (monitor, "changed",
|
|
|
|
|
G_CALLBACK (hostname_file_changed_cb),
|
|
|
|
|
self);
|
|
|
|
|
priv->hostname.monitor = monitor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined (HOSTNAME_PERSIST_SUSE)
|
|
|
|
|
/* monitor changes to dhcp file to know whether the hostname is valid */
|
|
|
|
|
file = g_file_new_for_path (CONF_DHCP);
|
|
|
|
|
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
|
|
|
|
g_object_unref (file);
|
|
|
|
|
if (monitor) {
|
|
|
|
|
priv->hostname.dhcp_monitor_id = g_signal_connect (monitor, "changed",
|
|
|
|
|
G_CALLBACK (hostname_file_changed_cb),
|
|
|
|
|
self);
|
|
|
|
|
priv->hostname.dhcp_monitor = monitor;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
hostname_maybe_changed (self);
|
2015-03-23 17:26:22 +01:00
|
|
|
}
|
|
|
|
|
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
gboolean
|
|
|
|
|
nm_settings_start (NMSettings *self, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingsPrivate *priv;
|
|
|
|
|
GDBusProxy *proxy;
|
|
|
|
|
GVariant *variant;
|
|
|
|
|
GError *local_error = NULL;
|
2016-11-25 13:54:42 +01:00
|
|
|
gs_strfreev char **plugins = NULL;
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
|
|
|
|
|
priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
|
2015-03-23 17:26:22 +01:00
|
|
|
/* Load the plugins; fail if a plugin is not found. */
|
2016-11-25 13:54:42 +01:00
|
|
|
plugins = nm_config_data_get_plugins (nm_config_get_data_orig (priv->config), TRUE);
|
2016-09-28 17:31:34 +02:00
|
|
|
|
2016-11-25 13:54:42 +01:00
|
|
|
if (!load_plugins (self, (const char **) plugins, error)) {
|
2015-03-23 17:26:22 +01:00
|
|
|
g_object_unref (self);
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
return FALSE;
|
2015-03-23 17:26:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
load_connections (self);
|
|
|
|
|
check_startup_complete (self);
|
2015-03-23 17:36:34 +01:00
|
|
|
|
|
|
|
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, NULL,
|
|
|
|
|
HOSTNAMED_SERVICE_NAME, HOSTNAMED_SERVICE_PATH,
|
|
|
|
|
HOSTNAMED_SERVICE_INTERFACE, NULL, &local_error);
|
|
|
|
|
if (proxy) {
|
|
|
|
|
variant = g_dbus_proxy_get_cached_property (proxy, "StaticHostname");
|
|
|
|
|
if (variant) {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("hostname: using hostnamed");
|
2015-03-23 17:36:34 +01:00
|
|
|
priv->hostname.hostnamed_proxy = proxy;
|
|
|
|
|
g_signal_connect (proxy, "g-properties-changed",
|
|
|
|
|
G_CALLBACK (hostnamed_properties_changed), self);
|
|
|
|
|
hostnamed_properties_changed (proxy, NULL, NULL, self);
|
|
|
|
|
g_variant_unref (variant);
|
|
|
|
|
} else {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("hostname: couldn't get property from hostnamed");
|
2015-03-23 17:36:34 +01:00
|
|
|
g_object_unref (proxy);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2016-03-03 09:20:10 +01:00
|
|
|
_LOGI ("hostname: hostnamed not used as proxy creation failed with: %s",
|
|
|
|
|
local_error->message);
|
2015-03-23 17:36:34 +01:00
|
|
|
g_clear_error (&local_error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!priv->hostname.hostnamed_proxy)
|
|
|
|
|
setup_hostname_file_monitors (self);
|
2015-03-23 17:26:22 +01:00
|
|
|
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
priv->started = TRUE;
|
2016-04-13 13:33:04 +02:00
|
|
|
_notify (self, PROP_HOSTNAME);
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
return TRUE;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object, guint prop_id,
|
|
|
|
|
GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
NMSettings *self = NM_SETTINGS (object);
|
|
|
|
|
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
|
|
|
|
|
const GSList *specs, *iter;
|
|
|
|
|
GHashTableIter citer;
|
|
|
|
|
GPtrArray *array;
|
|
|
|
|
const char *path;
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_UNMANAGED_SPECS:
|
|
|
|
|
array = g_ptr_array_new ();
|
|
|
|
|
specs = nm_settings_get_unmanaged_specs (self);
|
|
|
|
|
for (iter = specs; iter; iter = g_slist_next (iter))
|
|
|
|
|
g_ptr_array_add (array, g_strdup (iter->data));
|
|
|
|
|
g_ptr_array_add (array, NULL);
|
|
|
|
|
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_HOSTNAME:
|
|
|
|
|
g_value_take_string (value, nm_settings_get_hostname (self));
|
|
|
|
|
|
|
|
|
|
/* Don't ever pass NULL through D-Bus */
|
|
|
|
|
if (!g_value_get_string (value))
|
|
|
|
|
g_value_set_static_string (value, "");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CAN_MODIFY:
|
|
|
|
|
g_value_set_boolean (value, !!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CONNECTIONS:
|
|
|
|
|
array = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
|
|
|
|
|
g_hash_table_iter_init (&citer, priv->connections);
|
|
|
|
|
while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL))
|
|
|
|
|
g_ptr_array_add (array, g_strdup (path));
|
|
|
|
|
g_ptr_array_add (array, NULL);
|
|
|
|
|
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_STARTUP_COMPLETE:
|
|
|
|
|
g_value_set_boolean (value, nm_settings_get_startup_complete (self));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
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);
|
|
|
|
|
|
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.
|
|
|
|
|
*/
|
2015-01-06 12:11:21 +01:00
|
|
|
priv->agent_mgr = g_object_ref (nm_agent_manager_get ());
|
2011-06-28 15:48:12 +02:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
priv->config = g_object_ref (nm_config_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
|
|
|
}
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
NMSettings *
|
|
|
|
|
nm_settings_new (void)
|
|
|
|
|
{
|
|
|
|
|
return g_object_new (NM_TYPE_SETTINGS, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2013-10-18 16:07:26 +02:00
|
|
|
g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref);
|
|
|
|
|
priv->auths = NULL;
|
2010-11-17 17:44:33 -06:00
|
|
|
|
2011-01-27 10:41:02 -06:00
|
|
|
g_object_unref (priv->agent_mgr);
|
2010-11-18 14:05:33 -06:00
|
|
|
|
2015-03-23 17:36:34 +01:00
|
|
|
if (priv->hostname.hostnamed_proxy) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->hostname.hostnamed_proxy,
|
|
|
|
|
G_CALLBACK (hostnamed_properties_changed),
|
|
|
|
|
self);
|
|
|
|
|
g_clear_object (&priv->hostname.hostnamed_proxy);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 09:15:47 +01:00
|
|
|
if (priv->hostname.monitor) {
|
|
|
|
|
if (priv->hostname.monitor_id)
|
|
|
|
|
g_signal_handler_disconnect (priv->hostname.monitor, priv->hostname.monitor_id);
|
|
|
|
|
|
|
|
|
|
g_file_monitor_cancel (priv->hostname.monitor);
|
|
|
|
|
g_clear_object (&priv->hostname.monitor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->hostname.dhcp_monitor) {
|
|
|
|
|
if (priv->hostname.dhcp_monitor_id)
|
|
|
|
|
g_signal_handler_disconnect (priv->hostname.dhcp_monitor,
|
|
|
|
|
priv->hostname.dhcp_monitor_id);
|
|
|
|
|
|
|
|
|
|
g_file_monitor_cancel (priv->hostname.dhcp_monitor);
|
|
|
|
|
g_clear_object (&priv->hostname.dhcp_monitor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&priv->hostname.value, g_free);
|
|
|
|
|
|
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);
|
2016-05-17 11:03:53 +02:00
|
|
|
g_clear_pointer (&priv->connections_cached_list, g_free);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
settings: add unrecognized-specs, implement in ifcfg-rh
In Fedora, OVS ports are now identified in ifcfg files as
"TYPE=OVSPort", which NM doesn't recognize, and so it would ignore
those ifcfg files. Unfortunately, this meant that if auto-default
wasn't disabled, and there was no other configuration defined for the
device, then NM would create an NMDefaultWiredConnection for it and
screw things up.
So, add an "unrecognized-specs" settings plugin property, which allows
a plugin to indicate to NetworkManager that it knows of some
non-NetworkManager-supported connection defined for a device. This
will suppress default-wired connection creation for that device,
similar to the "no-auto-default" config file option, but determined by
the plugin instead of by manual configuration. Devices listed in
unrecognized-specs may still be managed by NetworkManager, unless they
are also listed in unmanaged-specs.
https://bugzilla.redhat.com/show_bug.cgi?id=1022256
2013-10-29 14:53:35 -04:00
|
|
|
g_slist_free_full (priv->unmanaged_specs, g_free);
|
|
|
|
|
g_slist_free_full (priv->unrecognized_specs, g_free);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2013-10-18 16:07:26 +02:00
|
|
|
g_slist_free_full (priv->plugins, g_object_unref);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
g_clear_object (&priv->config);
|
2009-07-23 09:20:52 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2015-04-03 10:08:52 -04:00
|
|
|
NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class);
|
2015-03-23 09:15:47 +01:00
|
|
|
|
2015-04-03 10:08:52 -04:00
|
|
|
exported_object_class->export_path = NM_DBUS_PATH_SETTINGS;
|
|
|
|
|
|
2009-07-23 09:20:52 -04:00
|
|
|
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;
|
|
|
|
|
|
2016-04-13 13:33:04 +02:00
|
|
|
obj_properties[PROP_UNMANAGED_SPECS] =
|
|
|
|
|
g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_HOSTNAME] =
|
|
|
|
|
g_param_spec_string (NM_SETTINGS_HOSTNAME, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_CAN_MODIFY] =
|
|
|
|
|
g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_CONNECTIONS] =
|
|
|
|
|
g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_STARTUP_COMPLETE] =
|
|
|
|
|
g_param_spec_boolean (NM_SETTINGS_STARTUP_COMPLETE, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
2016-04-13 16:57:40 +02:00
|
|
|
|
2016-04-13 13:33:04 +02:00
|
|
|
signals[CONNECTION_ADDED] =
|
|
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-13 14:24:07 +02:00
|
|
|
0, NULL, NULL,
|
2016-04-13 13:33:04 +02:00
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
|
|
|
|
|
|
|
|
|
|
signals[CONNECTION_UPDATED] =
|
|
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-13 14:24:07 +02:00
|
|
|
0, NULL, NULL,
|
2016-04-13 16:03:06 +02:00
|
|
|
NULL,
|
|
|
|
|
G_TYPE_NONE, 2, NM_TYPE_SETTINGS_CONNECTION, G_TYPE_BOOLEAN);
|
2016-04-13 13:33:04 +02:00
|
|
|
|
|
|
|
|
signals[CONNECTION_REMOVED] =
|
|
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-13 14:24:07 +02:00
|
|
|
0, NULL, NULL,
|
2016-04-13 13:33:04 +02:00
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
|
|
|
|
|
|
|
|
|
|
signals[CONNECTION_VISIBILITY_CHANGED] =
|
|
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-13 14:24:07 +02:00
|
|
|
0, NULL, NULL,
|
2016-04-13 13:33:04 +02:00
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
|
2010-08-03 13:23:30 -04:00
|
|
|
|
2011-06-28 15:48:12 +02:00
|
|
|
signals[AGENT_REGISTERED] =
|
2016-04-13 13:33:04 +02:00
|
|
|
g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-13 14:24:07 +02:00
|
|
|
0, NULL, NULL,
|
2016-04-13 13:33:04 +02:00
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_SECRET_AGENT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
signals[NEW_CONNECTION] =
|
|
|
|
|
g_signal_new ("new-connection",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
|
|
|
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
|
2010-10-27 16:20:41 -05:00
|
|
|
|
2015-04-13 13:31:42 -04:00
|
|
|
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
|
2015-04-15 14:53:30 -04:00
|
|
|
NMDBUS_TYPE_SETTINGS_SKELETON,
|
|
|
|
|
"ListConnections", impl_settings_list_connections,
|
|
|
|
|
"GetConnectionByUuid", impl_settings_get_connection_by_uuid,
|
|
|
|
|
"AddConnection", impl_settings_add_connection,
|
|
|
|
|
"AddConnectionUnsaved", impl_settings_add_connection_unsaved,
|
|
|
|
|
"LoadConnections", impl_settings_load_connections,
|
|
|
|
|
"ReloadConnections", impl_settings_reload_connections,
|
|
|
|
|
"SaveHostname", impl_settings_save_hostname,
|
|
|
|
|
NULL);
|
2009-07-23 09:20:52 -04:00
|
|
|
}
|
|
|
|
|
|