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 */