diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am
index 572e122fb6..f49d0127a5 100644
--- a/cli/src/Makefile.am
+++ b/cli/src/Makefile.am
@@ -4,7 +4,6 @@ bin_PROGRAMS = \
INCLUDES = \
-I${top_srcdir} \
-I${top_srcdir}/include \
- -I${top_builddir}/marshallers \
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib
@@ -31,7 +30,6 @@ nmcli_CPPFLAGS = \
nmcli_LDADD = \
$(DBUS_LIBS) \
$(GLIB_LIBS) \
- $(top_builddir)/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm-glib.la
diff --git a/configure.ac b/configure.ac
index 509de590e5..2441c3dc08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -697,6 +697,7 @@ initscript/Mandriva/networkmanager
initscript/linexa/Makefile
initscript/linexa/networkmanager
introspection/Makefile
+introspection/all.xml
man/Makefile
man/NetworkManager.8
man/NetworkManager.conf.5
diff --git a/docs/api/Makefile.am b/docs/api/Makefile.am
index 687d9cfb1c..276b4aefef 100644
--- a/docs/api/Makefile.am
+++ b/docs/api/Makefile.am
@@ -27,7 +27,7 @@ XSLTPROC = xsltproc --xinclude --nonet
XMLS = $(wildcard $(top_srcdir)/introspection/nm-*.xml)
OTHER_FILES= \
- $(top_srcdir)/introspection/all.xml \
+ $(top_builddir)/introspection/all.xml \
$(top_srcdir)/introspection/generic-types.xml \
$(top_srcdir)/introspection/errors.xml \
$(top_srcdir)/introspection/vpn-errors.xml \
@@ -37,7 +37,7 @@ OTHER_FILES= \
GENERATED_FILES = spec.html settings-spec.xml
spec.html: $(XMLS) $(OTHER_FILES) html-build.stamp
- $(XSLTPROC) $(top_srcdir)/tools/doc-generator.xsl $(top_srcdir)/introspection/all.xml > $@
+ $(XSLTPROC) $(top_srcdir)/tools/doc-generator.xsl $(top_builddir)/introspection/all.xml > $@
mkdir -p $(builddir)/html/
cp $@ $(builddir)/html/
diff --git a/examples/python/Makefile.am b/examples/python/Makefile.am
index 5650ed8333..7fa376ef75 100644
--- a/examples/python/Makefile.am
+++ b/examples/python/Makefile.am
@@ -5,6 +5,7 @@ EXTRA_DIST = \
vpn.py \
list-connections.py \
show-bssids.py \
- disconnect-device.py
+ disconnect-device.py \
+ get-active-connections.py
diff --git a/examples/python/get-active-connection-uuids.py b/examples/python/get-active-connection-uuids.py
new file mode 100755
index 0000000000..9eefac20b2
--- /dev/null
+++ b/examples/python/get-active-connection-uuids.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2010 Red Hat, Inc.
+#
+
+import dbus, sys
+
+# This example takes a device interface name as a parameter and tells
+# NetworkManager to disconnect that device, closing down any network
+# connection it may have
+
+bus = dbus.SystemBus()
+
+# Get a proxy for the base NetworkManager object
+m_proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
+manager = dbus.Interface(m_proxy, "org.freedesktop.NetworkManager")
+mgr_props = dbus.Interface(m_proxy, "org.freedesktop.DBus.Properties")
+
+s_proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings")
+settings = dbus.Interface(s_proxy, "org.freedesktop.NetworkManager.Settings")
+
+# Find the device the user wants to disconnect
+active = mgr_props.Get("org.freedesktop.NetworkManager", "ActiveConnections")
+for a in active:
+ a_proxy = bus.get_object("org.freedesktop.NetworkManager", a)
+
+ # Get the UUID directly; apps could use this to perform certain operations
+ # based on which network you're connected too
+ a_props = dbus.Interface(a_proxy, "org.freedesktop.DBus.Properties")
+ uuid = a_props.Get("org.freedesktop.NetworkManager.Connection.Active", "Uuid")
+
+ # Grab the connection object path so we can get all the connection's settings
+ connection_path = a_props.Get("org.freedesktop.NetworkManager.Connection.Active", "Connection")
+ c_proxy = bus.get_object("org.freedesktop.NetworkManager", connection_path)
+ connection = dbus.Interface(c_proxy, "org.freedesktop.NetworkManager.Settings.Connection")
+ settings = connection.GetSettings()
+ print "%s (%s)" % (settings['connection']['id'], uuid)
+
+if len(active) == 0:
+ print "No active connections"
+
diff --git a/examples/python/list-connections.py b/examples/python/list-connections.py
old mode 100644
new mode 100755
diff --git a/examples/python/show-bssids.py b/examples/python/show-bssids.py
old mode 100644
new mode 100755
diff --git a/examples/python/vpn.py b/examples/python/vpn.py
old mode 100644
new mode 100755
diff --git a/introspection/Makefile.am b/introspection/Makefile.am
index 320245eee1..7b549c1269 100644
--- a/introspection/Makefile.am
+++ b/introspection/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = \
- all.xml \
+ all.xml.in \
generic-types.xml \
errors.xml \
vpn-errors.xml \
diff --git a/introspection/all.xml b/introspection/all.xml.in
similarity index 98%
rename from introspection/all.xml
rename to introspection/all.xml.in
index 5d1baf01c9..4d2c272179 100644
--- a/introspection/all.xml
+++ b/introspection/all.xml.in
@@ -3,7 +3,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
NetworkManager D-Bus Interface Specification
-0.9
+@VERSION@
Copyright (C) 2008 - 2011 Red Hat, Inc.
diff --git a/introspection/nm-agent-manager.xml b/introspection/nm-agent-manager.xml
index 0b1e3e6e86..e26caacf42 100644
--- a/introspection/nm-agent-manager.xml
+++ b/introspection/nm-agent-manager.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index 1bb76d09fd..f5fd7abcf4 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -1,13 +1,6 @@
-
-
-
+
diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml
index 64163534a5..301cde76dd 100644
--- a/introspection/nm-settings.xml
+++ b/introspection/nm-settings.xml
@@ -1,6 +1,6 @@
-
+
The Settings interface allows clients to view and administrate the connections stored and used by NetworkManager.
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 6e9f92b59c..91fc3afac4 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -99,6 +99,7 @@ nm_connection_error_get_type (void)
ENUM_ENTRY (NM_CONNECTION_ERROR_UNKNOWN, "UnknownError"),
ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "ConnectionSettingNotFound"),
ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "ConnectionTypeInvalid"),
+ ENUM_ENTRY (NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "SettingNotFound"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMConnectionError", values);
@@ -790,60 +791,76 @@ nm_connection_verify (NMConnection *connection, GError **error)
* nm_connection_update_secrets:
* @connection: the #NMConnection
* @setting_name: the setting object name to which the secrets apply
- * @setting_secrets: (element-type utf8 GObject.Value): a #GHashTable mapping
+ * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping
* string:#GValue of setting property names and secrets of the given @setting_name
* @error: location to store error, or %NULL
*
* Update the specified setting's secrets, given a hash table of secrets
* intended for that setting (deserialized from D-Bus for example). Will also
* extract the given setting's secrets hash if given a hash of hashes, as would
- * be returned from nm_connection_to_hash().
+ * be returned from nm_connection_to_hash(). If @setting_name is %NULL, expects
+ * a fully serialized #NMConnection as returned by nm_connection_to_hash() and
+ * will update all secrets from all settings contained in @secrets.
*
- * Returns: %TRUE if the secrets were successfully updated and the connection
- * is valid, %FALSE on failure or if the setting was never added to the connection
+ * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update
+ * failed (tried to update secrets for a setting that doesn't exist, etc)
**/
gboolean
nm_connection_update_secrets (NMConnection *connection,
const char *setting_name,
- GHashTable *setting_secrets,
+ GHashTable *secrets,
GError **error)
{
NMSetting *setting;
gboolean success;
GHashTable *tmp;
- GType setting_type;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
- g_return_val_if_fail (setting_name != NULL, FALSE);
- g_return_val_if_fail (setting_secrets != NULL, FALSE);
+ g_return_val_if_fail (secrets != NULL, FALSE);
if (error)
g_return_val_if_fail (*error == NULL, FALSE);
- setting_type = nm_connection_lookup_setting_type (setting_name);
- if (!setting_type) {
- g_set_error_literal (error,
- NM_CONNECTION_ERROR,
- NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
- setting_name);
- return FALSE;
+ if (setting_name) {
+ /* Update just one setting */
+ setting = nm_connection_get_setting_by_name (connection, setting_name);
+ if (!setting) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
+ setting_name);
+ return FALSE;
+ }
+
+ /* Check if this is a hash of hashes, ie a full deserialized connection,
+ * not just a single hashed setting.
+ */
+ tmp = g_hash_table_lookup (secrets, setting_name);
+ success = nm_setting_update_secrets (setting, tmp ? tmp : secrets, error);
+ } else {
+ GHashTableIter iter;
+ const char *name;
+
+ success = TRUE; /* Just in case 'secrets' has no elements */
+
+ /* Try as a serialized connection (GHashTable of GHashTables) */
+ g_hash_table_iter_init (&iter, secrets);
+ while (g_hash_table_iter_next (&iter, (gpointer) &name, (gpointer) &tmp)) {
+ setting = nm_connection_get_setting_by_name (connection, name);
+ if (!setting) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
+ name);
+ return FALSE;
+ }
+
+ /* Update the secrets for this setting */
+ success = nm_setting_update_secrets (setting, tmp, error);
+ if (success == FALSE)
+ break;
+ }
}
-
- setting = nm_connection_get_setting (connection, setting_type);
- if (!setting) {
- g_set_error_literal (error,
- NM_CONNECTION_ERROR,
- NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
- setting_name);
- return FALSE;
- }
-
- /* Check if this is a hash of hashes, ie a full deserialized connection,
- * not just a single hashed setting.
- */
- tmp = g_hash_table_lookup (setting_secrets, setting_name);
-
- success = nm_setting_update_secrets (setting, tmp ? tmp : setting_secrets, error);
if (success)
g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name);
return success;
diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h
index 87b053c101..a7e0721cc1 100644
--- a/libnm-util/nm-connection.h
+++ b/libnm-util/nm-connection.h
@@ -66,6 +66,8 @@ G_BEGIN_DECLS
* 'connection' setting did not point to a valid connection base type; ie
* it was not a hardware-related setting like #NMSettingWired or
* #NMSettingWireless.
+ * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object
+ * did not contain the specified #NMSetting object
*
* Describes errors that may result from operations involving a #NMConnection.
*
@@ -74,7 +76,8 @@ typedef enum
{
NM_CONNECTION_ERROR_UNKNOWN = 0,
NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
- NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID
+ NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
+ NM_CONNECTION_ERROR_SETTING_NOT_FOUND
} NMConnectionError;
#define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ())
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index c04b974160..50091cb9a6 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -756,23 +756,27 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
/**
* NMSettinVPN:user-name:
*
- * User name of the currently logged in user for connections provided by the
- * user settings service. This name is provided to the VPN plugin to use in
- * lieu of a custom username provided by that VPN plugins specific
- * configuration. The VPN plugin itself decides which user name to use.
+ * If the VPN connection requires a user name for authentication, that name
+ * should be provided here. If the connection is available to more than
+ * one user, and the VPN requires each user to supply a different name, then
+ * leave this property empty. If this property is empty, NetworkManager
+ * will automatically supply the username of the user which requested the
+ * VPN connection.
**/
g_object_class_install_property
(object_class, PROP_USER_NAME,
g_param_spec_string (NM_SETTING_VPN_USER_NAME,
- "User name",
- "User name of the currently logged in user for "
- "connections provided by the user settings service. "
- "This name is provided to the VPN plugin to use in "
- "lieu of a custom username provided by that VPN "
- "plugins specific configuration. The VPN plugin "
- "itself decides which user name to use.",
- NULL,
- G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+ "User name",
+ "If the VPN connection requires a user name for "
+ "authentication, that name should be provided here. "
+ "If the connection is available to more than one "
+ "user, and the VPN requires each user to supply a "
+ "different name, then leave this property empty. If "
+ "this property is empty, NetworkManager will "
+ "automatically supply the username of the user which "
+ "requested the VPN connection.",
+ NULL,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
/**
* NMSettingVPN:data:
diff --git a/libnm-util/tests/test-secrets.c b/libnm-util/tests/test-secrets.c
index f1d105fcd2..1fe3c43823 100644
--- a/libnm-util/tests/test-secrets.c
+++ b/libnm-util/tests/test-secrets.c
@@ -591,7 +591,84 @@ test_update_secrets_wifi_bad_setting_name (void)
"asdfasdfasdfasf",
secrets,
&error);
- g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND);
+ g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
+ g_assert (success == FALSE);
+
+ g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection (void)
+{
+ NMConnection *connection;
+ NMSettingWirelessSecurity *s_wsec;
+ GHashTable *secrets, *wsec_hash;
+ GError *error = NULL;
+ gboolean success;
+ const char *wepkey = "11111111111111111111111111";
+
+ connection = wifi_connection_new ();
+
+ /* Build up the secrets hash */
+ secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+ wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ g_assert (wsec_hash);
+ g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
+
+ success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+ g_assert_no_error (error);
+ g_assert (success == TRUE);
+
+ s_wsec = nm_connection_get_setting_wireless_security (connection);
+ g_assert (s_wsec);
+ g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey);
+
+ g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection_empty_hash (void)
+{
+ NMConnection *connection;
+ GHashTable *secrets;
+ GError *error = NULL;
+ gboolean success;
+
+ connection = wifi_connection_new ();
+ secrets = g_hash_table_new (g_str_hash, g_str_equal);
+ success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+ g_assert_no_error (error);
+ g_assert (success == TRUE);
+ g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection_bad_setting (void)
+{
+ NMConnection *connection;
+ GHashTable *secrets, *wsec_hash;
+ GError *error = NULL;
+ gboolean success;
+ const char *wepkey = "11111111111111111111111111";
+
+ connection = wifi_connection_new ();
+
+ /* Build up the secrets hash */
+ secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+ wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ g_assert (wsec_hash);
+ g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
+
+ /* Steal the wsec setting hash so it's not deallocated, and stuff it back
+ * in with a different name so we ensure libnm-util is returning the right
+ * error when it finds an entry in the connection hash that doesn't match
+ * any setting in the connection.
+ */
+ g_hash_table_steal (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ g_hash_table_insert (secrets, "asdfasdfasdfasdf", wsec_hash);
+
+ success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+ g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
g_assert (success == FALSE);
g_object_unref (connection);
@@ -617,6 +694,10 @@ int main (int argc, char **argv)
test_update_secrets_wifi_full_hash ();
test_update_secrets_wifi_bad_setting_name ();
+ test_update_secrets_whole_connection ();
+ test_update_secrets_whole_connection_empty_hash ();
+ test_update_secrets_whole_connection_bad_setting ();
+
base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base);
g_free (base);
diff --git a/man/NetworkManager.8.in b/man/NetworkManager.8.in
index c5f44513d8..127c72bf37 100644
--- a/man/NetworkManager.8.in
+++ b/man/NetworkManager.8.in
@@ -1,14 +1,16 @@
.\" NetworkManager(8) manual page
.\"
-.\" Copyright (C) 2005 - 2010 Red Hat, Inc.
+.\" Copyright (C) 2005 - 2011 Red Hat, Inc.
.\" Copyright (C) 2005 - 2009 Novell, Inc.
.\" Copyright (C) 2005 Robert Love
.\"
-.TH NETWORKMANAGER "8" "January 29, 2010"
+.TH NETWORKMANAGER "8" "2 August 2011"
.SH NAME
NetworkManager \- network management daemon
.SH SYNOPSIS
-.B NetworkManager [\-\-version] [\-\-no\-daemon] [\-\-pid\-file=] [\-\-state\-file=] [\-\-config=] [\-\-plugins=,plugin2>,...] [\-\-log\-level=] [\-\-log\-domains=,,...]
+.B NetworkManager [\-\-version] | [\-\-help]
+.PP
+.B NetworkManager [\-\-no\-daemon] [\-\-pid\-file=] [\-\-state\-file=] [\-\-config=] [\-\-plugins=,plugin2>,...] [\-\-log\-level=] [\-\-log\-domains=,,...]
.SH DESCRIPTION
The \fINetworkManager\fP daemon attempts to make networking configuration and
operation as painless and automatic as possible by managing the primary network
@@ -21,10 +23,22 @@ settings and operation.
.P
NetworkManager will execute scripts in the /etc/NetworkManager/dispatcher.d
directory in alphabetical order in response to network events. Each script
-should be (a) a regular file, (b) owned by root, (c) not writable by group or
-other, (d) not set-uid, (e) and executable by the owner. Each script receives
-two arguments, the first being the interface name of the device just activated,
-and second an action.
+should be:
+.IP "(a)" 4
+a regular file
+.IP "(b)" 4
+owned by root
+.IP "(c)" 4
+not writable by group or other
+.IP "(d)" 4
+not set-uid
+.IP "(e)" 4
+and executable by the owner
+.PP
+Each script receives two arguments, the first being the interface name of the
+device just activated, and second an action.
+.PP
+Actions:
.TP
.I "up"
The interface has been activated. The environment contains more information
@@ -64,6 +78,9 @@ The following options are supported:
.I "\-\-version"
Print the NetworkManager software version and exit.
.TP
+.I "\-\-help"
+Print NetworkManager's available options and exit.
+.TP
.I "\-\-no\-daemon"
Do not daemonize. This is useful for debugging, and directs log output to the
controlling terminal in addition to syslog.
@@ -113,5 +130,7 @@ When set to anything, causes NetworkManager to turn on PPP debugging in pppd,
which logs all PPP and PPTP frames and client/server exchanges.
.SH SEE ALSO
.BR nm\-tool (1),
+.BR nm\-online (1),
+.BR nmcli (1),
.BR NetworkManager.conf (5).
diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in
index d047f39391..9fe722c4c9 100644
--- a/man/NetworkManager.conf.5.in
+++ b/man/NetworkManager.conf.5.in
@@ -1,8 +1,8 @@
.\" NetworkManager.conf(5) manual page
.\"
-.\" Copyright (C) 2010 Red Hat, Inc.
+.\" Copyright (C) 2010 - 2011 Red Hat, Inc.
.\"
-.TH "NetworkManager.conf" "5" "23 November 2010" ""
+.TH "NetworkManager.conf" "5" "2 August 2011" ""
.SH NAME
NetworkManager.conf \- NetworkManager configuration file
.SH SYNOPSIS
@@ -20,9 +20,6 @@ is a configuration file for NetworkManager. It is used to set up various
aspects of NetworkManager's behavior. The location of
the file may be changed through use of the "\-\-config=" argument for
\fBNetworkManager\fP (8).
-
-It is not necessary to restart NetworkManager when making changes, as the
-configuration file is watched for changes and reloaded automatically when necessary.
.SH "FILE FORMAT"
.P
The configuration file format is so-called key file (sort of ini-style format).
@@ -163,12 +160,61 @@ warning messages.
The following log domains are available: [NONE, HW, RFKILL, ETHER, WIFI, BT, MB,
DHCP4, DHCP6, PPP, WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT,
AGENTS, SETTINGS, SUSPEND, CORE, DEVICE, OLPC, WIMAX]. When "NONE" is given by
-itself, logging is disabled. MB = Mobile Broadband, AGENTS = secret agents
-operations and communication, SETTINGS = settings/config service operations,
-OLPC = OLPC Mesh device operations, CORE = core daemon operations, DEVICE =
-activation and general interface operations.
+itself, logging is disabled.
+.PP
+.RS
+HW = Hardware related operations
+.br
+RFKILL = RFKill subsystem operations
+.br
+ETHER = Ethernet device operations
+.br
+WIFI = Wi-Fi device operations
+.br
+BT = Bluetooth
+.br
+MB = Mobile Broadband
+.br
+DHCP4 = DHCP for IPv4
+.br
+DHCP6 = DHCP for IPv6
+.br
+PPP = Point-to-point protocol operations
+.br
+WIFI_SCAN = Wi-Fi scanning operations
+.br
+IP4 = Domain for IPv4 logging
+.br
+IP6 = Domain for IPv6 logging
+.br
+AUTOIP4 = AutoIP (avahi) operations
+.br
+DNS = Domain Name System related operations
+.br
+VPN = Virtual Private Network connections and operaions
+.br
+SHARING = Connection sharing
+.br
+SUPPLICANT = WPA supplicant related operations
+.br
+AGENTS = Secret agents operations and communication
+.br
+SETTINGS = Settings/config service operations
+.br
+SUSPEND = Suspend/resume
+.br
+CORE = Core daemon operations
+.br
+DEVICE = Activation and general interface operations
+.br
+OLPC = OLPC Mesh device operations
+.br
+WIMAX = Wimax device operations
+.br
.SH "SEE ALSO"
.BR http://live.gnome.org/NetworkManager/SystemSettings
.sp
.BR NetworkManager (8),
-.BR nm\-tool (1).
+.BR nmcli (1),
+.BR nm\-tool (1),
+.BR nm\-online (1).
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 00e46a130c..debfbdf7d7 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -86,6 +86,17 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
+static void
+update_mm_enabled (NMModem *self, gboolean new_enabled)
+{
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
+
+ if (priv->mm_enabled != new_enabled) {
+ priv->mm_enabled = new_enabled;
+ g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
+ }
+}
+
gboolean
nm_modem_get_mm_enabled (NMModem *self)
{
@@ -822,8 +833,7 @@ get_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d
}
if (G_VALUE_HOLDS_BOOLEAN (&value)) {
- NM_MODEM_GET_PRIVATE (self)->mm_enabled = g_value_get_boolean (&value);
- g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
+ update_mm_enabled (self, g_value_get_boolean (&value));
} else
nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type");
@@ -880,6 +890,9 @@ nm_modem_set_mm_enabled (NMModem *self, gboolean enabled)
self, NULL,
G_TYPE_BOOLEAN, enabled,
G_TYPE_INVALID);
+ /* If we are disabling the modem, stop saying that it's enabled. */
+ if (!enabled)
+ update_mm_enabled (self, enabled);
}
}
@@ -898,8 +911,7 @@ modem_properties_changed (DBusGProxy *proxy,
value = g_hash_table_lookup (props, "Enabled");
if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
- priv->mm_enabled = g_value_get_boolean (value);
- g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED);
+ update_mm_enabled (self, g_value_get_boolean (value));
}
value = g_hash_table_lookup (props, "IpMethod");
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 56c79f3d38..02292f7afd 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -902,6 +902,9 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds
if (state < NM_DEVICE_STATE_DISCONNECTED)
return;
+ if (!nm_device_interface_get_enabled (NM_DEVICE_INTERFACE (device)))
+ return;
+
if (!nm_device_autoconnect_allowed (device))
return;
@@ -1060,6 +1063,12 @@ nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data)
}
#endif
+static void
+modem_enabled_changed (NMDeviceModem *device, gpointer user_data)
+{
+ schedule_activate_check ((NMPolicy *) (user_data), NM_DEVICE (device), 0);
+}
+
typedef struct {
gulong id;
NMDevice *device;
@@ -1094,6 +1103,8 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
_connect_device_signal (policy, device, "nsp-added", nsps_changed);
_connect_device_signal (policy, device, "nsp-removed", nsps_changed);
#endif
+ } else if (NM_IS_DEVICE_MODEM (device)) {
+ _connect_device_signal (policy, device, NM_DEVICE_MODEM_ENABLE_CHANGED, modem_enabled_changed);
}
}
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index f0f9c1a6d7..4b3a56cd6d 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -382,25 +382,14 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL);
g_assert (new_settings);
if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) {
- GHashTableIter iter;
- NMSetting *setting;
- const char *setting_name;
- GHashTable *setting_hash;
-
/* Copy the connection to keep its secrets around even if NM
* calls nm_connection_clear_secrets().
*/
update_secrets_cache (self);
/* And add the transient secrets back */
- if (transient_secrets) {
- g_hash_table_iter_init (&iter, transient_secrets);
- while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
- setting = nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name);
- if (setting)
- nm_setting_update_secrets (setting, setting_hash, NULL);
- }
- }
+ if (transient_secrets)
+ nm_connection_update_secrets (NM_CONNECTION (self), NULL, transient_secrets, NULL);
nm_settings_connection_recheck_visibility (self);
success = TRUE;
@@ -1109,31 +1098,30 @@ con_update_cb (NMSettingsConnection *connection,
}
static void
-only_agent_secrets_cb (NMSetting *setting,
- const char *key,
- const GValue *value,
- GParamFlags flags,
- gpointer user_data)
+secrets_filter_cb (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
{
+ NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data);
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+ const char *secret_name = NULL;
+ GHashTableIter iter;
+
if (flags & NM_SETTING_PARAM_SECRET) {
- NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-
- /* Clear out system-owned or always-ask secrets */
if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
- GHashTableIter iter;
- const char *secret_name = NULL;
-
/* VPNs are special; need to handle each secret separately */
g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
- while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
+ while (g_hash_table_iter_next (&iter, (gpointer) &secret_name, NULL)) {
secret_flags = NM_SETTING_SECRET_FLAG_NONE;
nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
- if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ if (!(secret_flags & filter_flags))
nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
}
} else {
nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
- if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ if (!(secret_flags & filter_flags))
g_object_set (G_OBJECT (setting), key, NULL, NULL);
}
}
@@ -1148,23 +1136,52 @@ update_auth_cb (NMSettingsConnection *self,
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMConnection *new_settings = data;
- NMConnection *for_agent;
+ NMConnection *for_agent, *dup;
+ NMSettingSecretFlags filter_flags;
+ GHashTable *hash;
+ GError *local = NULL;
if (error)
dbus_g_method_return_error (context, error);
else {
+ /* Cache the new secrets since they may get overwritten by the replace
+ * when transient secrets are copied back.
+ */
+ dup = nm_connection_duplicate (new_settings);
+
/* Update and commit our settings. */
nm_settings_connection_replace_and_commit (self,
new_settings,
con_update_cb,
context);
+ /* Copy new agent secrets back to the connection */
+ filter_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED;
+ nm_connection_for_each_setting_value (dup,
+ secrets_filter_cb,
+ GUINT_TO_POINTER (filter_flags));
+ hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+ g_object_unref (dup);
+
+ if (hash) {
+ if (!nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, &local)) {
+ nm_log_warn (LOGD_SETTINGS, "Failed to update connection secrets: (%d) %s",
+ local ? local->code : -1,
+ local && local->message ? local->message : "(unknown)");
+ g_clear_error (&local);
+ }
+ g_hash_table_destroy (hash);
+ }
+
/* Dupe the connection and clear out non-agent-owned secrets so we can
* send the agent-owned ones to agents to be saved. Only send them to
* agents of the same UID as the Update() request sender.
*/
for_agent = nm_connection_duplicate (NM_CONNECTION (self));
- nm_connection_for_each_setting_value (for_agent, only_agent_secrets_cb, NULL);
+ filter_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED;
+ nm_connection_for_each_setting_value (for_agent,
+ secrets_filter_cb,
+ GUINT_TO_POINTER (filter_flags));
nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, sender_uid);
g_object_unref (for_agent);
}
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
index 534f44d9ff..04d3d3e453 100644
--- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2008 - 2010 Red Hat, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
*/
#include
@@ -181,7 +181,7 @@ nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
static void
commit_changes (NMSettingsConnection *connection,
NMSettingsConnectionCommitFunc callback,
- gpointer user_data)
+ gpointer user_data)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
GError *error = NULL;
@@ -208,9 +208,12 @@ commit_changes (NMSettingsConnection *connection,
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS);
g_object_unref (reread);
- /* Don't bother writing anything out if nothing really changed */
- if (same == TRUE)
+ /* Don't bother writing anything out if in-memory and on-disk data are the same */
+ if (same) {
+ /* But chain up to parent to handle success - emits updated signal */
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data);
return;
+ }
}
if (writer_update_connection (NM_CONNECTION (connection),
@@ -227,7 +230,7 @@ commit_changes (NMSettingsConnection *connection,
}
}
-static void
+static void
do_delete (NMSettingsConnection *connection,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index 7d2765651a..ed0dceca31 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -269,20 +269,24 @@ connection_new_or_changed (SCPluginIfcfg *self,
/* Successfully read connection changes */
- /* When the connections are the same, nothing is done */
- if (nm_connection_compare (NM_CONNECTION (existing),
- NM_CONNECTION (new),
- NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
- NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) {
+ old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing));
+ new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
+
+ /* When interface is unmanaged or the connections and unmanaged specs are the same
+ * there's nothing to do */
+ if ( (g_strcmp0 (old_unmanaged, new_unmanaged) == 0 && new_unmanaged != NULL)
+ || ( nm_connection_compare (NM_CONNECTION (existing),
+ NM_CONNECTION (new),
+ NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
+ NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
+ && g_strcmp0 (old_unmanaged, new_unmanaged) == 0)) {
+
g_object_unref (new);
return;
}
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
- old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing));
- new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
-
if (new_unmanaged) {
if (!old_unmanaged) {
/* Unexport the connection by telling the settings service it's
@@ -290,6 +294,11 @@ connection_new_or_changed (SCPluginIfcfg *self,
* unmanaged specs have changed.
*/
nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (existing));
+ /* Remove the path so that claim_connection() doesn't complain later when
+ * interface gets managed and connection is re-added. */
+ nm_connection_set_path (NM_CONNECTION (existing), NULL);
+
+ g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL);
g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
} else {
diff --git a/test/nm-tool.c b/test/nm-tool.c
index ffe70af9ff..9ce44f88a5 100644
--- a/test/nm-tool.c
+++ b/test/nm-tool.c
@@ -39,9 +39,7 @@
#include
#include
#include
-#if WITH_WIMAX
#include
-#endif
#include
#include
#include
@@ -198,7 +196,6 @@ detail_access_point (gpointer data, gpointer user_data)
g_free (tmp);
}
-#if WITH_WIMAX
static const char *
wimax_network_type_to_str (NMWimaxNspNetworkType type)
{
@@ -238,7 +235,6 @@ detail_nsp (gpointer data, gpointer user_data)
g_free (label);
g_free (data_str);
}
-#endif
static gchar *
ip4_address_as_string (guint32 ip)
@@ -370,10 +366,8 @@ detail_device (gpointer data, gpointer user_data)
print_string ("Type", "Mobile Broadband (unknown)");
} else if (NM_IS_DEVICE_BT (device))
print_string ("Type", "Bluetooth");
-#if WITH_WIMAX
else if (NM_IS_DEVICE_WIMAX (device))
print_string ("Type", "WiMAX");
-#endif
print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)");
@@ -390,10 +384,8 @@ detail_device (gpointer data, gpointer user_data)
tmp = g_strdup (nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
else if (NM_IS_DEVICE_WIFI (device))
tmp = g_strdup (nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)));
-#if WITH_WIMAX
else if (NM_IS_DEVICE_WIMAX (device))
tmp = g_strdup (nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)));
-#endif
if (tmp) {
print_string ("HW Address", tmp);
@@ -459,7 +451,6 @@ detail_device (gpointer data, gpointer user_data)
print_string (" Carrier", "on");
else
print_string (" Carrier", "off");
-#if WITH_WIMAX
} else if (NM_IS_DEVICE_WIMAX (device)) {
NMDeviceWimax *wimax = NM_DEVICE_WIMAX (device);
NMWimaxNsp *active_nsp = NULL;
@@ -520,7 +511,6 @@ detail_device (gpointer data, gpointer user_data)
nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device));
if (nsps && nsps->len)
g_ptr_array_foreach ((GPtrArray *) nsps, detail_nsp, (gpointer) active_name);
-#endif
}
/* IP Setup info */