about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-05-27 19:57:25 +0200
committerMichael Biebl <biebl@debian.org>2011-05-27 19:57:25 +0200
commitd465e5fac63f36bcf4069e36827f4b62c494556d (patch)
tree65f4ba9567e091233cdf3279f7ba3c9479e74a1c /src
parent9f806e97a24bba61417ae312fcc0da40914266fb (diff)
Imported Upstream version 0.8.9997 upstream/0.8.9997
Diffstat (limited to 'src')
-rw-r--r--src/NetworkManagerUtils.c36
-rw-r--r--src/backends/Makefile.am2
-rw-r--r--src/backends/Makefile.in8
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.c15
-rw-r--r--src/dns-manager/Makefile.am2
-rw-r--r--src/dns-manager/Makefile.in5
-rw-r--r--src/ip6-manager/Makefile.am2
-rw-r--r--src/ip6-manager/Makefile.in5
-rw-r--r--src/logging/nm-logging.c6
-rw-r--r--src/logging/nm-logging.h1
-rw-r--r--src/modem-manager/Makefile.am2
-rw-r--r--src/modem-manager/Makefile.in4
-rw-r--r--src/nm-device-interface.c8
-rw-r--r--src/nm-device-interface.h2
-rw-r--r--src/nm-device-wifi.c53
-rw-r--r--src/nm-device.c12
-rw-r--r--src/nm-dhcp4-config.c17
-rw-r--r--src/nm-dhcp4-config.h2
-rw-r--r--src/nm-dhcp6-config.c17
-rw-r--r--src/nm-dhcp6-config.h2
-rw-r--r--src/nm-manager-auth.c222
-rw-r--r--src/nm-manager-auth.h18
-rw-r--r--src/nm-manager.c152
-rw-r--r--src/nm-policy.c35
-rw-r--r--src/nm-session-monitor.c16
-rw-r--r--src/nm-udev-manager.c8
-rw-r--r--src/nm-wifi-ap.c39
-rw-r--r--src/nm-wifi-ap.h3
-rw-r--r--src/ppp-manager/nm-ppp-manager.c8
-rw-r--r--src/settings/Makefile.am1
-rw-r--r--src/settings/Makefile.in1
-rw-r--r--src/settings/nm-agent-manager.c29
-rw-r--r--src/settings/nm-polkit-helpers.h41
-rw-r--r--src/settings/nm-settings-connection.c204
-rw-r--r--src/settings/nm-settings.c64
-rw-r--r--src/settings/plugins/keyfile/writer.c33
-rw-r--r--src/vpn-manager/Makefile.am2
-rw-r--r--src/vpn-manager/Makefile.in4
-rw-r--r--src/wimax/nm-device-wimax.c62
39 files changed, 707 insertions, 436 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index d069eca7..5a6a61b6 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -391,6 +391,38 @@ dump_object_to_props (GObject *object, GHashTable *hash)
 }
 
 static void
+dump_dhcp4_to_props (NMDHCP4Config *config, GHashTable *hash)
+{
+	GSList *options, *iter;
+
+	options = nm_dhcp4_config_list_options (config);
+	for (iter = options; iter; iter = g_slist_next (iter)) {
+		const char *option = (const char *) iter->data;
+		const char *val;
+
+		val = nm_dhcp4_config_get_option (config, option);
+		value_hash_add_str (hash, option, val);
+	}
+	g_slist_free (options);
+}
+
+static void
+dump_dhcp6_to_props (NMDHCP6Config *config, GHashTable *hash)
+{
+	GSList *options, *iter;
+
+	options = nm_dhcp6_config_list_options (config);
+	for (iter = options; iter; iter = g_slist_next (iter)) {
+		const char *option = (const char *) iter->data;
+		const char *val;
+
+		val = nm_dhcp6_config_get_option (config, option);
+		value_hash_add_str (hash, option, val);
+	}
+	g_slist_free (options);
+}
+
+static void
 fill_device_props (NMDevice *device,
                    GHashTable *dev_hash,
                    GHashTable *ip4_hash,
@@ -420,11 +452,11 @@ fill_device_props (NMDevice *device,
 
 	dhcp4_config = nm_device_get_dhcp4_config (device);
 	if (dhcp4_config)
-		dump_object_to_props (G_OBJECT (dhcp4_config), dhcp4_hash);
+		dump_dhcp4_to_props (dhcp4_config, dhcp4_hash);
 
 	dhcp6_config = nm_device_get_dhcp6_config (device);
 	if (dhcp6_config)
-		dump_object_to_props (G_OBJECT (dhcp6_config), dhcp6_hash);
+		dump_dhcp6_to_props (dhcp6_config, dhcp6_hash);
 }
 
 static void
diff --git a/src/backends/Makefile.am b/src/backends/Makefile.am
index fbec9aaf..c0780d0b 100644
--- a/src/backends/Makefile.am
+++ b/src/backends/Makefile.am
@@ -63,10 +63,12 @@ endif
 
 libnmbackend_la_LIBADD += \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
 libnmbackend_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DG_DISABLE_DEPRECATED \
diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in
index a9ea3e80..2f489e75 100644
--- a/src/backends/Makefile.in
+++ b/src/backends/Makefile.in
@@ -71,7 +71,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libnmbackend_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/logging/libnm-logging.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am__libnmbackend_la_SOURCES_DIST = NetworkManagerGeneric.c \
 	NetworkManagerGeneric.h NetworkManagerRedHat.c \
 	NetworkManagerSuSE.c NetworkManagerGentoo.c \
@@ -362,9 +363,10 @@ libnmbackend_la_SOURCES = NetworkManagerGeneric.c \
 	$(am__append_10) $(am__append_11) $(am__append_12) \
 	$(am__append_13)
 libnmbackend_la_LIBADD = $(am__append_9) \
-	$(top_builddir)/src/logging/libnm-logging.la $(DBUS_LIBS) \
-	$(GLIB_LIBS)
+	$(top_builddir)/src/logging/libnm-logging.la $(LIBNL_LIBS) \
+	$(DBUS_LIBS) $(GLIB_LIBS)
 libnmbackend_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DG_DISABLE_DEPRECATED \
diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
index cc5255ab..caf90f11 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
@@ -14,7 +14,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) 2010 Red Hat, Inc.
+ * Copyright (C) 2011 Red Hat, Inc.
  */
 
 #include <config.h>
@@ -166,8 +166,19 @@ nm_dhcp_dhclient_create_config (const char *interface,
 		}
 
 		if (hostname) {
-			g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", hostname);
+			char *plain_hostname, *dot;
+
+			plain_hostname = g_strdup (hostname);
+			dot = strchr (plain_hostname, '.');
+
+			/* get rid of the domain */
+			if (dot)
+				*dot = '\0';
+
+			g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", plain_hostname);
 			added = TRUE;
+
+			g_free (plain_hostname);
 		}
 
 		if (added)
diff --git a/src/dns-manager/Makefile.am b/src/dns-manager/Makefile.am
index 7b5fc4f8..b51f667b 100644
--- a/src/dns-manager/Makefile.am
+++ b/src/dns-manager/Makefile.am
@@ -19,12 +19,14 @@ libdns_manager_la_SOURCES = \
 	nm-dns-utils.c
 
 libdns_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DLOCALSTATEDIR=\"$(localstatedir)\"
 
 libdns_manager_la_LIBADD = \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in
index 4937a601..aad1c562 100644
--- a/src/dns-manager/Makefile.in
+++ b/src/dns-manager/Makefile.in
@@ -58,7 +58,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libdns_manager_la_DEPENDENCIES =  \
 	$(top_builddir)/src/logging/libnm-logging.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_libdns_manager_la_OBJECTS = libdns_manager_la-nm-dns-manager.lo \
 	libdns_manager_la-nm-dns-plugin.lo \
 	libdns_manager_la-nm-dns-dnsmasq.lo \
@@ -325,12 +326,14 @@ libdns_manager_la_SOURCES = \
 	nm-dns-utils.c
 
 libdns_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DLOCALSTATEDIR=\"$(localstatedir)\"
 
 libdns_manager_la_LIBADD = \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/ip6-manager/Makefile.am b/src/ip6-manager/Makefile.am
index b56b197e..b98d6def 100644
--- a/src/ip6-manager/Makefile.am
+++ b/src/ip6-manager/Makefile.am
@@ -13,6 +13,7 @@ libip6_manager_la_SOURCES = \
 	nm-ip6-manager.h
 
 libip6_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DG_DISABLE_DEPRECATED
@@ -20,6 +21,7 @@ libip6_manager_la_CPPFLAGS = \
 libip6_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in
index 344ca0ea..33539f51 100644
--- a/src/ip6-manager/Makefile.in
+++ b/src/ip6-manager/Makefile.in
@@ -59,7 +59,8 @@ am__DEPENDENCIES_1 =
 libip6_manager_la_DEPENDENCIES =  \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_libip6_manager_la_OBJECTS = libip6_manager_la-nm-ip6-manager.lo
 libip6_manager_la_OBJECTS = $(am_libip6_manager_la_OBJECTS)
 AM_V_lt = $(am__v_lt_$(V))
@@ -316,6 +317,7 @@ libip6_manager_la_SOURCES = \
 	nm-ip6-manager.h
 
 libip6_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	-DG_DISABLE_DEPRECATED
@@ -323,6 +325,7 @@ libip6_manager_la_CPPFLAGS = \
 libip6_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c
index 1e289d37..d8353f27 100644
--- a/src/logging/nm-logging.c
+++ b/src/logging/nm-logging.c
@@ -218,6 +218,12 @@ nm_logging_level_enabled (guint32 level)
 	return !!(log_level & level);
 }
 
+gboolean
+nm_logging_domain_enabled (guint32 domain)
+{
+	return !!(log_domains & domain);
+}
+
 void
 _nm_log (const char *loc,
          const char *func,
diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h
index 44e49a71..e3e05f59 100644
--- a/src/logging/nm-logging.h
+++ b/src/logging/nm-logging.h
@@ -95,6 +95,7 @@ void _nm_log (const char *loc,
 const char *nm_logging_level_to_string (void);
 char *nm_logging_domains_to_string (void);
 gboolean nm_logging_level_enabled (guint32 level);
+gboolean nm_logging_domain_enabled (guint32 domain);
 
 /* Undefine the nm-utils.h logging stuff to ensure errors */
 #undef nm_print_backtrace
diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am
index db680aea..3c3af16c 100644
--- a/src/modem-manager/Makefile.am
+++ b/src/modem-manager/Makefile.am
@@ -19,10 +19,12 @@ libmodem_manager_la_SOURCES = \
 	nm-modem-types.h
 
 libmodem_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS)
 
 libmodem_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS)
 
diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in
index 66f7c1bc..2a054f70 100644
--- a/src/modem-manager/Makefile.in
+++ b/src/modem-manager/Makefile.in
@@ -59,7 +59,7 @@ am__DEPENDENCIES_1 =
 libmodem_manager_la_DEPENDENCIES =  \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
-	$(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am_libmodem_manager_la_OBJECTS = libmodem_manager_la-nm-modem.lo \
 	libmodem_manager_la-nm-modem-cdma.lo \
 	libmodem_manager_la-nm-modem-gsm.lo \
@@ -325,11 +325,13 @@ libmodem_manager_la_SOURCES = \
 	nm-modem-types.h
 
 libmodem_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS) \
 	$(DBUS_CFLAGS)
 
 libmodem_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS)
 
 all: all-am
diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c
index 6d2b8762..fb471f57 100644
--- a/src/nm-device-interface.c
+++ b/src/nm-device-interface.c
@@ -166,6 +166,14 @@ nm_device_interface_init (gpointer g_iface)
 
 	g_object_interface_install_property
 		(g_iface,
+		 g_param_spec_boxed (NM_DEVICE_INTERFACE_ACTIVE_CONNECTION,
+		                     "ActiveConnection",
+		                     "ActiveConnection",
+		                     DBUS_TYPE_G_OBJECT_PATH,
+		                     G_PARAM_READABLE));
+
+	g_object_interface_install_property
+		(g_iface,
 		 g_param_spec_uint (NM_DEVICE_INTERFACE_DEVICE_TYPE,
 							"DeviceType",
 							"DeviceType",
diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h
index f39e8459..560cdfe5 100644
--- a/src/nm-device-interface.h
+++ b/src/nm-device-interface.h
@@ -58,6 +58,7 @@ typedef enum
 #define NM_DEVICE_INTERFACE_IP6_CONFIG       "ip6-config"
 #define NM_DEVICE_INTERFACE_DHCP6_CONFIG     "dhcp6-config"
 #define NM_DEVICE_INTERFACE_STATE            "state"
+#define NM_DEVICE_INTERFACE_ACTIVE_CONNECTION "active-connection"
 #define NM_DEVICE_INTERFACE_DEVICE_TYPE      "device-type" /* ugh */
 #define NM_DEVICE_INTERFACE_MANAGED          "managed"
 #define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing"
@@ -79,6 +80,7 @@ typedef enum {
 	NM_DEVICE_INTERFACE_PROP_IP6_CONFIG,
 	NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG,
 	NM_DEVICE_INTERFACE_PROP_STATE,
+	NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION,
 	NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
 	NM_DEVICE_INTERFACE_PROP_MANAGED,
 	NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING,
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 9258f77c..7a6e7528 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -1460,6 +1460,26 @@ real_complete_connection (NMDevice *device,
 	if (ap) {
 		ssid = nm_ap_get_ssid (ap);
 
+		if (ssid == NULL) {
+			/* The AP must be hidden.  Connecting to a WiFi AP requires the SSID
+			 * as part of the initial handshake, so check the connection details
+			 * for the SSID.  The AP object will still be used for encryption
+			 * settings and such.
+			 */
+			ssid = nm_setting_wireless_get_ssid (s_wifi);
+		}
+
+		if (ssid == NULL) {
+			/* If there's no SSID on the AP itself, and no SSID in the
+			 * connection data, then we cannot connect at all.  Return an error.
+			 */
+			g_set_error_literal (error,
+			                     NM_WIFI_ERROR,
+			                     NM_WIFI_ERROR_CONNECTION_INVALID,
+			                     "A 'wireless' setting with a valid SSID is required for hidden access points.");
+			return FALSE;
+		}
+
 		/* If the SSID is a well-known SSID, lock the connection to the AP's
 		 * specific BSSID so NM doesn't autoconnect to some random wifi net.
 		 */
@@ -2851,7 +2871,7 @@ remove_supplicant_timeouts (NMDeviceWifi *self)
 }
 
 static guint32
-find_supported_frequency (NMDeviceWifi *self, guint32 *freqs)
+find_supported_frequency (NMDeviceWifi *self, const guint32 *freqs)
 {
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 	int i;
@@ -2887,25 +2907,25 @@ build_supplicant_config (NMDeviceWifi *self,
 	if (!config)
 		return NULL;
 
-	/* Figure out the Ad-Hoc frequency to use if creating an adhoc network; if
-	 * nothing was specified then pick something usable.
+	/* Supplicant requires an initial frequency for Ad-Hoc networks; if the user
+	 * didn't specify one and we didn't find an AP that matched the connection,
+	 * just pick a frequency the device supports.
 	 */
-	if ((nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) && nm_ap_get_user_created (ap)) {
+	if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) {
 		const char *band = nm_setting_wireless_get_band (s_wireless);
+		const guint32 a_freqs[] = { 5180, 5200, 5220, 5745, 5765, 5785, 5805, 0 };
+		const guint32 bg_freqs[] = { 2412, 2437, 2462, 2472, 0 };
 
 		adhoc_freq = nm_ap_get_freq (ap);
 		if (!adhoc_freq) {
-			if (band && !strcmp (band, "a")) {
-				guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0};
+			if (g_strcmp0 (band, "a") == 0)
 				adhoc_freq = find_supported_frequency (self, a_freqs);
-			} else {
-				guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0};
+			else
 				adhoc_freq = find_supported_frequency (self, bg_freqs);
-			}
 		}
 
 		if (!adhoc_freq) {
-			if (band && !strcmp (band, "a"))
+			if (g_strcmp0 (band, "a") == 0)
 				adhoc_freq = 5180;
 			else
 				adhoc_freq = 2462;
@@ -3098,15 +3118,8 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
 		ap = nm_ap_new_fake_from_connection (connection);
 		g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE);
 
-		switch (nm_ap_get_mode (ap)) {
-			case NM_802_11_MODE_ADHOC:
-				nm_ap_set_user_created (ap, TRUE);
-				break;
-			case NM_802_11_MODE_INFRA:
-			default:
-				nm_ap_set_broadcast (ap, FALSE);
-				break;
-		}
+		if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA)
+			nm_ap_set_broadcast (ap, FALSE);
 
 		priv->ap_list = g_slist_prepend (priv->ap_list, ap);
 		nm_ap_export_to_dbus (ap);
@@ -3399,7 +3412,7 @@ activation_success_handler (NMDevice *dev)
 		nm_ap_set_address (ap, &bssid);
 	if (!nm_ap_get_freq (ap))
 		nm_ap_set_freq (ap, nm_device_wifi_get_frequency (self));
-	if (!nm_ap_get_max_bitrate (ap) && nm_ap_get_user_created (ap))
+	if (!nm_ap_get_max_bitrate (ap))
 		nm_ap_set_max_bitrate (ap, nm_device_wifi_get_bitrate (self));
 
 	tmp_ap = get_active_ap (self, ap, TRUE);
diff --git a/src/nm-device.c b/src/nm-device.c
index ebd8cdb9..4b7ec5df 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -3463,6 +3463,7 @@ get_property (GObject *object, guint prop_id,
 	NMDevice *self = NM_DEVICE (object);
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 	NMDeviceState state;
+	const char *ac_path = NULL;
 
 	state = nm_device_get_state (self);
 
@@ -3518,6 +3519,11 @@ get_property (GObject *object, guint prop_id,
 	case NM_DEVICE_INTERFACE_PROP_STATE:
 		g_value_set_uint (value, priv->state);
 		break;
+	case NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION:
+		if (priv->act_request)
+			ac_path = nm_act_request_get_active_connection_path (priv->act_request);
+		g_value_set_boxed (value, ac_path ? ac_path : "/");
+		break;
 	case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE:
 		g_value_set_uint (value, priv->type);
 		break;
@@ -3616,6 +3622,10 @@ nm_device_class_init (NMDeviceClass *klass)
 									  NM_DEVICE_INTERFACE_STATE);
 
 	g_object_class_override_property (object_class,
+	                                  NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION,
+	                                  NM_DEVICE_INTERFACE_ACTIVE_CONNECTION);
+
+	g_object_class_override_property (object_class,
 									  NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
 									  NM_DEVICE_INTERFACE_DEVICE_TYPE);
 
@@ -3809,7 +3819,7 @@ reason_to_string (NMDeviceStateReason reason)
 	case NM_DEVICE_STATE_REASON_USER_REQUESTED:
 		return "user-requested";
 	case NM_DEVICE_STATE_REASON_CARRIER:
-		return "carrier-chagned";
+		return "carrier-changed";
 	case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED:
 		return "connection-assumed";
 	case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE:
diff --git a/src/nm-dhcp4-config.c b/src/nm-dhcp4-config.c
index 5acf053f..567ba687 100644
--- a/src/nm-dhcp4-config.c
+++ b/src/nm-dhcp4-config.c
@@ -101,6 +101,23 @@ nm_dhcp4_config_get_option (NMDHCP4Config *self, const char *key)
 	return value ? g_value_get_string (value) : NULL;
 }
 
+/* Caller owns the list, but not the values in the list */
+GSList *
+nm_dhcp4_config_list_options (NMDHCP4Config *self)
+{
+	GHashTableIter iter;
+	const char *option = NULL;
+	GSList *list = NULL;
+
+	g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL);
+
+	g_hash_table_iter_init (&iter, NM_DHCP4_CONFIG_GET_PRIVATE (self)->options);
+	while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL))
+		list = g_slist_prepend (list, (gpointer) option);
+
+	return list;
+}
+
 const char *
 nm_dhcp4_config_get_dbus_path (NMDHCP4Config *self)
 {
diff --git a/src/nm-dhcp4-config.h b/src/nm-dhcp4-config.h
index ffaa8430..4729da4c 100644
--- a/src/nm-dhcp4-config.h
+++ b/src/nm-dhcp4-config.h
@@ -58,4 +58,6 @@ void nm_dhcp4_config_reset (NMDHCP4Config *config);
 
 const char *nm_dhcp4_config_get_option (NMDHCP4Config *config, const char *option);
 
+GSList *nm_dhcp4_config_list_options (NMDHCP4Config *config);
+
 #endif /* NM_DHCP4_CONFIG_H */
diff --git a/src/nm-dhcp6-config.c b/src/nm-dhcp6-config.c
index fb6ccce5..885e5f84 100644
--- a/src/nm-dhcp6-config.c
+++ b/src/nm-dhcp6-config.c
@@ -101,6 +101,23 @@ nm_dhcp6_config_get_option (NMDHCP6Config *self, const char *key)
 	return value ? g_value_get_string (value) : NULL;
 }
 
+/* Caller owns the list, but not the values in the list */
+GSList *
+nm_dhcp6_config_list_options (NMDHCP6Config *self)
+{
+	GHashTableIter iter;
+	const char *option = NULL;
+	GSList *list = NULL;
+
+	g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL);
+
+	g_hash_table_iter_init (&iter, NM_DHCP6_CONFIG_GET_PRIVATE (self)->options);
+	while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL))
+		list = g_slist_prepend (list, (gpointer) option);
+
+	return list;
+}
+
 const char *
 nm_dhcp6_config_get_dbus_path (NMDHCP6Config *self)
 {
diff --git a/src/nm-dhcp6-config.h b/src/nm-dhcp6-config.h
index 90eb10ff..5e83b904 100644
--- a/src/nm-dhcp6-config.h
+++ b/src/nm-dhcp6-config.h
@@ -58,4 +58,6 @@ void nm_dhcp6_config_reset (NMDHCP6Config *config);
 
 const char *nm_dhcp6_config_get_option (NMDHCP6Config *config, const char *option);
 
+GSList *nm_dhcp6_config_list_options (NMDHCP6Config *self);
+
 #endif /* NM_DHCP6_CONFIG_H */
diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c
index 8515959e..9171663b 100644
--- a/src/nm-manager-auth.c
+++ b/src/nm-manager-auth.c
@@ -18,17 +18,25 @@
  * Copyright (C) 2010 Red Hat, Inc.
  */
 
+#include <config.h>
 #include <string.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
 
-#include <nm-setting-connection.h>
+#if WITH_POLKIT
+#include <polkit/polkit.h>
+#endif
+
+#include "nm-setting-connection.h"
 #include "nm-manager-auth.h"
 #include "nm-logging.h"
 #include "nm-dbus-manager.h"
 
 struct NMAuthChain {
 	guint32 refcount;
+#if WITH_POLKIT
 	PolkitAuthority *authority;
+#endif
 	GSList *calls;
 	GHashTable *data;
 
@@ -37,7 +45,6 @@ struct NMAuthChain {
 	GError *error;
 
 	NMAuthChainResultFunc done_func;
-	NMAuthChainCallFunc call_func;
 	gpointer user_data;
 };
 
@@ -45,8 +52,9 @@ typedef struct {
 	NMAuthChain *chain;
 	GCancellable *cancellable;
 	char *permission;
+	guint idle_id;
 	gboolean disposed;
-} PolkitCall;
+} AuthCall;
 
 typedef struct {
 	gpointer data;
@@ -64,20 +72,31 @@ free_data (gpointer data)
 	g_free (tmp);
 }
 
-static void
-default_call_func (NMAuthChain *chain,
-                   const char *permission,
-                   GError *error,
-                   NMAuthCallResult result,
-                   gpointer user_data)
+#if WITH_POLKIT
+static PolkitAuthority *
+pk_authority_get (void)
 {
-	if (!error)
-		nm_auth_chain_set_data (chain, permission, GUINT_TO_POINTER (result), NULL);
+	static PolkitAuthority *authority = NULL;
+	GError *error = NULL;
+
+	if (authority == NULL) {
+		authority = polkit_authority_get_sync (NULL, &error);
+		if (authority == NULL) {
+			nm_log_err (LOGD_CORE, "Failed to initialize PolicyKit: (%d) %s",
+			            error ? error->code : -1,
+			            (error && error->message) ? error->message : "(unknown)");
+			g_clear_error (&error);
+			return NULL;
+		}
+	}
+
+	/* Yes, ref every time; we want to keep the object alive */
+	return g_object_ref (authority);
 }
+#endif
 
 static NMAuthChain *
-_auth_chain_new (PolkitAuthority *authority,
-                 DBusGMethodInvocation *context,
+_auth_chain_new (DBusGMethodInvocation *context,
                  DBusGProxy *proxy,
                  DBusMessage *message,
                  const char *dbus_sender,
@@ -90,10 +109,11 @@ _auth_chain_new (PolkitAuthority *authority,
 
 	self = g_malloc0 (sizeof (NMAuthChain));
 	self->refcount = 1;
-	self->authority = g_object_ref (authority);
+#if WITH_POLKIT
+	self->authority = pk_authority_get ();
+#endif
 	self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_data);
 	self->done_func = done_func;
-	self->call_func = /* call_func ? call_func : */ default_call_func;
 	self->user_data = user_data;
 	self->context = context;
 
@@ -117,31 +137,28 @@ _auth_chain_new (PolkitAuthority *authority,
 }
 
 NMAuthChain *
-nm_auth_chain_new (PolkitAuthority *authority,
-                   DBusGMethodInvocation *context,
+nm_auth_chain_new (DBusGMethodInvocation *context,
                    DBusGProxy *proxy,
                    NMAuthChainResultFunc done_func,
                    gpointer user_data)
 {
-	return _auth_chain_new (authority, context, proxy, NULL, NULL, done_func, user_data);
+	return _auth_chain_new (context, proxy, NULL, NULL, done_func, user_data);
 }
 
 NMAuthChain *
-nm_auth_chain_new_raw_message (PolkitAuthority *authority,
-                               DBusMessage *message,
+nm_auth_chain_new_raw_message (DBusMessage *message,
                                NMAuthChainResultFunc done_func,
                                gpointer user_data)
 {
-	return _auth_chain_new (authority, NULL, NULL, message, NULL, done_func, user_data);
+	return _auth_chain_new (NULL, NULL, message, NULL, done_func, user_data);
 }
 
 NMAuthChain *
-nm_auth_chain_new_dbus_sender (PolkitAuthority *authority,
-                               const char *dbus_sender,
+nm_auth_chain_new_dbus_sender (const char *dbus_sender,
                                NMAuthChainResultFunc done_func,
                                gpointer user_data)
 {
-	return _auth_chain_new (authority, NULL, NULL, NULL, dbus_sender, done_func, user_data);
+	return _auth_chain_new (NULL, NULL, NULL, dbus_sender, done_func, user_data);
 }
 
 gpointer
@@ -229,14 +246,36 @@ nm_auth_chain_check_done (NMAuthChain *self)
 }
 
 static void
-polkit_call_cancel (PolkitCall *call)
+nm_auth_chain_remove_call (NMAuthChain *self, AuthCall *call)
+{
+	g_return_if_fail (self != NULL);
+	g_return_if_fail (call != NULL);
+
+	self->calls = g_slist_remove (self->calls, call);
+}
+
+static AuthCall *
+auth_call_new (NMAuthChain *chain, const char *permission)
+{
+	AuthCall *call;
+
+	call = g_malloc0 (sizeof (AuthCall));
+	call->chain = chain;
+	call->permission = g_strdup (permission);
+	call->cancellable = g_cancellable_new ();
+	chain->calls = g_slist_append (chain->calls, call);
+	return call;
+}
+
+static void
+auth_call_cancel (AuthCall *call)
 {
 	call->disposed = TRUE;
 	g_cancellable_cancel (call->cancellable);
 }
 
 static void
-polkit_call_free (PolkitCall *call)
+auth_call_free (AuthCall *call)
 {
 	g_return_if_fail (call != NULL);
 
@@ -246,30 +285,49 @@ polkit_call_free (PolkitCall *call)
 	call->chain = NULL;
 	g_object_unref (call->cancellable);
 	call->cancellable = NULL;
+	if (call->idle_id)
+		g_source_remove (call->idle_id);
+	memset (call, 0, sizeof (*call));
 	g_free (call);
 }
 
+/* This can get used from scheduled idles, hence the boolean return */
+static gboolean
+auth_call_complete (AuthCall *call)
+{
+	g_return_val_if_fail (call != NULL, FALSE);
+
+	call->idle_id = 0;
+	nm_auth_chain_remove_call (call->chain, call);
+	nm_auth_chain_check_done (call->chain);
+	auth_call_free (call);
+	return FALSE;
+}
+
+static void
+auth_call_schedule_early_finish (AuthCall *call, GError *error)
+{
+	if (!call->chain->error)
+		call->chain->error = error;
+	call->idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call);
+}
+
+#if WITH_POLKIT
 static void
 pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 {
-	PolkitCall *call = user_data;
-	NMAuthChain *chain;
+	AuthCall *call = user_data;
+	NMAuthChain *chain = call->chain;
 	PolkitAuthorizationResult *pk_result;
 	GError *error = NULL;
-	guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN;
 
 	/* If the call is already disposed do nothing */
 	if (call->disposed) {
-		polkit_call_free (call);
+		auth_call_free (call);
 		return;
 	}
 
-	chain = call->chain;
-	chain->calls = g_slist_remove (chain->calls, call);
-
-	pk_result = polkit_authority_check_authorization_finish (chain->authority,
-	                                                         result,
-	                                                         &error);
+	pk_result = polkit_authority_check_authorization_finish (chain->authority, result, &error);
 	if (error) {
 		if (!chain->error)
 			chain->error = g_error_copy (error);
@@ -279,6 +337,8 @@ pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 		             error ? error->code : -1,
 		             error && error->message ? error->message : "(unknown)");
 	} else {
+		guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN;
+
 		if (polkit_authorization_result_get_is_authorized (pk_result)) {
 			/* Caller has the permission */
 			call_result = NM_AUTH_CALL_RESULT_YES;
@@ -287,23 +347,26 @@ pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 			call_result = NM_AUTH_CALL_RESULT_AUTH;
 		} else
 			call_result = NM_AUTH_CALL_RESULT_NO;
-	}
 
-	chain->call_func (chain, call->permission, error, call_result, chain->user_data);
-	nm_auth_chain_check_done (chain);
+		nm_auth_chain_set_data (chain, call->permission, GUINT_TO_POINTER (call_result), NULL);
+	}
 
 	g_clear_error (&error);
-	polkit_call_free (call);
 	if (pk_result)
 		g_object_unref (pk_result);
+
+	auth_call_complete (call);
 }
+#endif
 
 gboolean
 nm_auth_chain_add_call (NMAuthChain *self,
                         const char *permission,
                         gboolean allow_interaction)
 {
-	PolkitCall *call;
+	AuthCall *call;
+
+#if WITH_POLKIT
 	PolkitSubject *subject;
 	PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
 
@@ -315,12 +378,14 @@ nm_auth_chain_add_call (NMAuthChain *self,
 	if (!subject)
 		return FALSE;
 
-	call = g_malloc0 (sizeof (PolkitCall));
-	call->chain = self;
-	call->permission = g_strdup (permission);
-	call->cancellable = g_cancellable_new ();
+	call = auth_call_new (self, permission);
 
-	self->calls = g_slist_append (self->calls, call);
+	if (self->authority == NULL) {
+		/* No polkit, no authorization */
+		auth_call_schedule_early_finish (call, g_error_new_literal (0, 0, "PolicyKit unavailable"));
+		g_object_unref (subject);
+		return FALSE;
+	}
 
 	if (allow_interaction)
 		flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
@@ -334,6 +399,17 @@ nm_auth_chain_add_call (NMAuthChain *self,
 	                                      pk_call_cb,
 	                                      call);
 	g_object_unref (subject);
+#else
+	/* -- NO POLKIT -- */
+
+	g_return_val_if_fail (self != NULL, FALSE);
+
+	/* When PolicyKit is disabled, everything is authorized */
+	call = auth_call_new (self, permission);
+	nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL);
+	auth_call_schedule_early_finish (call, NULL);
+#endif
+
 	return TRUE;
 }
 
@@ -348,11 +424,14 @@ nm_auth_chain_unref (NMAuthChain *self)
 	if (self->refcount > 0)
 		return;
 
-	g_object_unref (self->authority);
+#if WITH_POLKIT
+	if (self->authority)
+		g_object_unref (self->authority);
+#endif
 	g_free (self->owner);
 
 	for (iter = self->calls; iter; iter = g_slist_next (iter))
-		polkit_call_cancel ((PolkitCall *) iter->data);
+		auth_call_cancel ((AuthCall *) iter->data);
 	g_slist_free (self->calls);
 
 	g_clear_error (&self->error);
@@ -460,3 +539,50 @@ nm_auth_uid_in_acl (NMConnection *connection,
 	return TRUE;
 }
 
+typedef struct {
+	GDestroyNotify changed_callback;
+	gpointer changed_data;
+} PkChangedInfo;
+
+#if WITH_POLKIT
+static void
+pk_authority_changed_cb (GObject *object, PkChangedInfo *info)
+{
+	info->changed_callback (info->changed_data);
+}
+#endif
+
+void
+nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data)
+{
+#if WITH_POLKIT
+	static PkChangedInfo info = { NULL, NULL };
+	static guint32 changed_id = 0;
+	PolkitAuthority *authority;
+
+	authority = pk_authority_get ();
+	if (!authority)
+		return;
+
+	if (callback == NULL) {
+		/* Clearing the callback */
+		info.changed_callback = NULL;
+		info.changed_data = NULL;
+		g_signal_handler_disconnect (authority, changed_id);
+		changed_id = 0;
+	} else {
+		info.changed_callback = callback;
+		info.changed_data= callback_data;
+
+		if (changed_id == 0) {
+			changed_id = g_signal_connect (authority,
+			                               "changed",
+			                               G_CALLBACK (pk_authority_changed_cb),
+			                               &info);
+		}
+	}
+
+	g_object_unref (authority);
+#endif
+}
+
diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h
index 7e7ff7a1..ad14d306 100644
--- a/src/nm-manager-auth.h
+++ b/src/nm-manager-auth.h
@@ -21,7 +21,6 @@
 #ifndef NM_MANAGER_AUTH_H
 #define NM_MANAGER_AUTH_H
 
-#include <polkit/polkit.h>
 #include <glib.h>
 #include <dbus/dbus-glib.h>
 
@@ -56,25 +55,16 @@ typedef void (*NMAuthChainResultFunc) (NMAuthChain *chain,
                                        DBusGMethodInvocation *context,
                                        gpointer user_data);
 
-typedef void (*NMAuthChainCallFunc) (NMAuthChain *chain,
-                                     const char *permission,
-                                     GError *error,
-                                     NMAuthCallResult result,
-                                     gpointer user_data);
-
-NMAuthChain *nm_auth_chain_new (PolkitAuthority *authority,
-                                DBusGMethodInvocation *context,
+NMAuthChain *nm_auth_chain_new (DBusGMethodInvocation *context,
                                 DBusGProxy *proxy,
                                 NMAuthChainResultFunc done_func,
                                 gpointer user_data);
 
-NMAuthChain *nm_auth_chain_new_raw_message (PolkitAuthority *authority,
-                                            DBusMessage *message,
+NMAuthChain *nm_auth_chain_new_raw_message (DBusMessage *message,
                                             NMAuthChainResultFunc done_func,
                                             gpointer user_data);
 
-NMAuthChain *nm_auth_chain_new_dbus_sender (PolkitAuthority *authority,
-                                            const char *dbus_sender,
+NMAuthChain *nm_auth_chain_new_dbus_sender (const char *dbus_sender,
                                             NMAuthChainResultFunc done_func,
                                             gpointer user_data);
 
@@ -112,5 +102,7 @@ gboolean nm_auth_uid_in_acl (NMConnection *connection,
                              gulong uid,
                              char **out_error_desc);
 
+void nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data);
+
 #endif /* NM_MANAGER_AUTH_H */
 
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 568ff2ae..961c9d8c 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 #include <glib/gi18n.h>
 
 #include "nm-glib-compat.h"
@@ -158,22 +159,6 @@ static GSList * remove_one_device (NMManager *manager,
                                    NMDevice *device,
                                    gboolean quitting);
 
-static NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi);
-
-/* Fix for polkit 0.97 and later */
-#if !HAVE_POLKIT_AUTHORITY_GET_SYNC
-static inline PolkitAuthority *
-polkit_authority_get_sync (GCancellable *cancellable, GError **error)
-{
-	PolkitAuthority *authority;
-
-	authority = polkit_authority_get ();
-	if (!authority)
-		g_set_error (error, 0, 0, "failed to get the PolicyKit authority");
-	return authority;
-}
-#endif
-
 #define SSD_POKE_INTERVAL 120
 #define ORIGDEV_TAG "originating-device"
 
@@ -185,7 +170,6 @@ struct PendingActivation {
 	NMManager *manager;
 
 	DBusGMethodInvocation *context;
-	PolkitAuthority *authority;
 	PendingActivationFunc callback;
 	NMAuthChain *chain;
 
@@ -237,8 +221,6 @@ typedef struct {
 	DBusGProxy *aipd_proxy;
 	DBusGProxy *upower_proxy;
 
-	PolkitAuthority *authority;
-	guint auth_changed_id;
 	GSList *auth_chains;
 
 	/* Firmware dir monitor */
@@ -679,7 +661,6 @@ try_complete_vpn (NMConnection *connection, GSList *existing, GError **error)
 
 static PendingActivation *
 pending_activation_new (NMManager *manager,
-                        PolkitAuthority *authority,
                         DBusGMethodInvocation *context,
                         const char *device_path,
                         const char *connection_path,
@@ -696,7 +677,6 @@ pending_activation_new (NMManager *manager,
 	gboolean success;
 
 	g_return_val_if_fail (manager != NULL, NULL);
-	g_return_val_if_fail (authority != NULL, NULL);
 	g_return_val_if_fail (context != NULL, NULL);
 	g_return_val_if_fail (device_path != NULL, NULL);
 
@@ -744,7 +724,6 @@ pending_activation_new (NMManager *manager,
 
 	pending = g_slice_new0 (PendingActivation);
 	pending->manager = manager;
-	pending->authority = authority;
 	pending->context = context;
 	pending->callback = callback;
 
@@ -767,31 +746,23 @@ pending_auth_net_done (NMAuthChain *chain,
 {
 	PendingActivation *pending = user_data;
 	NMAuthCallResult result;
+	GError *tmp_error = NULL;
 
 	pending->chain = NULL;
 
-	if (error) {
-		pending->callback (pending, error);
-		goto out;
-	}
-
 	/* Caller has had a chance to obtain authorization, so we only need to
 	 * check for 'yes' here.
 	 */
 	result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL));
 	if (result != NM_AUTH_CALL_RESULT_YES) {
-		error = g_error_new_literal (NM_MANAGER_ERROR,
-		                             NM_MANAGER_ERROR_PERMISSION_DENIED,
-		                             "Not authorized to control networking.");
-		pending->callback (pending, error);
-		g_error_free (error);
-		goto out;
+		tmp_error = g_error_new_literal (NM_MANAGER_ERROR,
+		                                 NM_MANAGER_ERROR_PERMISSION_DENIED,
+		                                 "Not authorized to control networking.");
 	}
 
-	pending->callback (pending, NULL);
-
-out:
+	pending->callback (pending, tmp_error);
 	nm_auth_chain_unref (chain);
+	g_clear_error (&tmp_error);
 }
 
 static void
@@ -827,8 +798,7 @@ pending_activation_check_authorized (PendingActivation *pending,
 	/* First check if the user is allowed to use networking at all, giving
 	 * the user a chance to authenticate to gain the permission.
 	 */
-	pending->chain = nm_auth_chain_new (pending->authority,
-	                                    pending->context,
+	pending->chain = nm_auth_chain_new (pending->context,
 	                                    NULL,
 	                                    pending_auth_net_done,
 	                                    pending);
@@ -1110,7 +1080,7 @@ manager_hidden_ap_found (NMDeviceInterface *device,
 			struct ether_addr seen_addr;
 
 			if (ether_aton_r (seen_bssid, &seen_addr)) {
-				if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr))) {
+				if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr)) == 0) {
 					/* Copy the SSID from the connection to the AP */
 					nm_ap_set_ssid (ap, ssid);
 					done = TRUE;
@@ -1388,7 +1358,7 @@ manager_device_disconnect_request (NMDevice *device,
 		NMAuthChain *chain;
 
 		/* Otherwise validate the user request */
-		chain = nm_auth_chain_new (priv->authority, context, NULL, disconnect_net_auth_done_cb, self);
+		chain = nm_auth_chain_new (context, NULL, disconnect_net_auth_done_cb, self);
 		g_assert (chain);
 		priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 
@@ -2103,7 +2073,6 @@ impl_manager_activate_connection (NMManager *self,
 	 * activate the connection.
 	 */
 	pending = pending_activation_new (self,
-	                                  priv->authority,
 	                                  context,
 	                                  device_path,
 	                                  connection_path,
@@ -2172,7 +2141,6 @@ impl_manager_add_and_activate_connection (NMManager *self,
 	 * activate the connection.
 	 */
 	pending = pending_activation_new (self,
-	                                  priv->authority,
 	                                  context,
 	                                  device_path,
 	                                  NULL,
@@ -2236,37 +2204,35 @@ done:
 
 static void
 deactivate_net_auth_done_cb (NMAuthChain *chain,
-                             GError *error,
+                             GError *auth_error,
                              DBusGMethodInvocation *context,
                              gpointer user_data)
 {
 	NMManager *self = NM_MANAGER (user_data);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	GError *ret_error = NULL;
+	GError *error = NULL;
 	NMAuthCallResult result;
 	const char *active_path;
 
 	priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
 
 	result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL));
-	ret_error = deactivate_disconnect_check_error (error, result, "Deactivate");
-	if (ret_error) {
-		dbus_g_method_return_error (context, ret_error);
-		g_error_free (ret_error);
-		goto done;
+	error = deactivate_disconnect_check_error (auth_error, result, "Deactivate");
+	if (!error) {
+		active_path = nm_auth_chain_get_data (chain, "path");
+		if (!nm_manager_deactivate_connection (self,
+		                                       active_path,
+		                                       NM_DEVICE_STATE_REASON_USER_REQUESTED,
+		                                       &error))
+			g_assert (error);
 	}
 
-	active_path = nm_auth_chain_get_data (chain, "path");
-	if (!nm_manager_deactivate_connection (self,
-	                                       active_path,
-	                                       NM_DEVICE_STATE_REASON_USER_REQUESTED,
-	                                       &ret_error)) {
-		dbus_g_method_return_error (context, ret_error);
-		g_clear_error (&ret_error);
-	} else
+	if (error)
+		dbus_g_method_return_error (context, error);
+	else
 		dbus_g_method_return (context);
 
-done:
+	g_clear_error (&error);
 	nm_auth_chain_unref (chain);
 }
 
@@ -2342,7 +2308,7 @@ impl_manager_deactivate_connection (NMManager *self,
 	}
 
 	/* Otherwise validate the user request */
-	chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_net_auth_done_cb, self);
+	chain = nm_auth_chain_new (context, NULL, deactivate_net_auth_done_cb, self);
 	g_assert (chain);
 	priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 
@@ -2415,25 +2381,6 @@ do_sleep_wake (NMManager *self)
 	nm_manager_update_state (self);
 }
 
-static gboolean
-return_no_pk_error (PolkitAuthority *authority,
-                    const char *detail,
-                    DBusGMethodInvocation *context)
-{
-	GError *error;
-
-	if (!authority) {
-		error = g_error_new (NM_MANAGER_ERROR,
-		                     NM_MANAGER_ERROR_PERMISSION_DENIED,
-		                     "%s request failed: PolicyKit not initialized",
-		                     detail);
-		dbus_g_method_return_error (context, error);
-		g_error_free (error);
-		return FALSE;
-	}
-	return TRUE;
-}
-
 static void
 _internal_sleep (NMManager *self, gboolean do_sleep)
 {
@@ -2550,10 +2497,7 @@ impl_manager_sleep (NMManager *self,
 		return;
 	}
 
-	if (!return_no_pk_error (priv->authority, "Sleep/wake", context))
-		return;
-
-	chain = nm_auth_chain_new (priv->authority, context, NULL, sleep_auth_done_cb, self);
+	chain = nm_auth_chain_new (context, NULL, sleep_auth_done_cb, self);
 	g_assert (chain);
 	priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 
@@ -2688,10 +2632,7 @@ impl_manager_enable (NMManager *self,
 		return;
 	}
 
-	if (!return_no_pk_error (priv->authority, "Enable/disable", context))
-		return;
-
-	chain = nm_auth_chain_new (priv->authority, context, NULL, enable_net_done_cb, self);
+	chain = nm_auth_chain_new (context, NULL, enable_net_done_cb, self);
 	g_assert (chain);
 	priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 
@@ -2702,13 +2643,6 @@ impl_manager_enable (NMManager *self,
 /* Permissions */
 
 static void
-pk_authority_changed_cb (GObject *object, gpointer user_data)
-{
-	/* Let clients know they should re-check their authorization */
-	g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
-}
-
-static void
 get_perm_add_result (NMAuthChain *chain, GHashTable *results, const char *permission)
 {
 	NMAuthCallResult result;
@@ -2772,10 +2706,7 @@ impl_manager_get_permissions (NMManager *self,
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	NMAuthChain *chain;
 
-	if (!return_no_pk_error (priv->authority, "Permissions", context))
-		return;
-
-	chain = nm_auth_chain_new (priv->authority, context, NULL, get_permissions_done_cb, self);
+	chain = nm_auth_chain_new (context, NULL, get_permissions_done_cb, self);
 	g_assert (chain);
 	priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 
@@ -3059,7 +2990,7 @@ prop_filter (DBusConnection *connection,
 
 	if (uid > 0) {
 		/* Otherwise validate the user request */
-		chain = nm_auth_chain_new_raw_message (priv->authority, message, prop_set_auth_done_cb, self);
+		chain = nm_auth_chain_new_raw_message (message, prop_set_auth_done_cb, self);
 		g_assert (chain);
 		priv->auth_chains = g_slist_append (priv->auth_chains, chain);
 		nm_auth_chain_set_data (chain, "prop", g_strdup (glib_propname), g_free);
@@ -3189,7 +3120,8 @@ dispose (GObject *object)
 
 	g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL);
 	g_slist_free (priv->auth_chains);
-	g_object_unref (priv->authority);
+
+	nm_auth_set_changed_func (NULL, NULL);
 
 	while (g_slist_length (priv->devices)) {
 		priv->devices = remove_one_device (manager,
@@ -3466,13 +3398,19 @@ periodic_update_active_connection_timestamps (gpointer user_data)
 }
 
 static void
+authority_changed_cb (gpointer user_data)
+{
+	/* Let clients know they should re-check their authorization */
+	g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
+}
+
+static void
 nm_manager_init (NMManager *manager)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
 	DBusGConnection *g_connection;
 	guint id, i;
 	GFile *file;
-	GError *error = NULL;
 
 	/* Initialize rfkill structures and states */
 	memset (priv->radio_states, 0, sizeof (priv->radio_states));
@@ -3563,18 +3501,8 @@ nm_manager_init (NMManager *manager)
 	} else
 		nm_log_warn (LOGD_SUSPEND, "could not initialize UPower D-Bus proxy");
 
-	priv->authority = polkit_authority_get_sync (NULL, &error);
-	if (priv->authority) {
-		priv->auth_changed_id = g_signal_connect (priv->authority,
-		                                          "changed",
-		                                          G_CALLBACK (pk_authority_changed_cb),
-		                                          manager);
-	} else {
-		nm_log_warn (LOGD_CORE, "failed to create PolicyKit authority: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-		g_clear_error (&error);
-	}
+	/* Listen for authorization changes */
+	nm_auth_set_changed_func (authority_changed_cb, manager);
 
 	/* Monitor the firmware directory */
 	if (strlen (KERNEL_FIRMWARE_DIR)) {
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 5c30828b..194d1111 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.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) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
  * Copyright (C) 2007 - 2008 Novell, Inc.
  */
 
@@ -817,22 +817,28 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
 }
 
 static void
+reset_retries_all (NMSettings *settings)
+{
+	GSList *connections, *iter;
+
+	connections = nm_settings_get_connections (settings);
+	for (iter = connections; iter; iter = g_slist_next (iter))
+		set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
+	g_slist_free (connections);
+}
+
+static void
 sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
 {
 	NMPolicy *policy = user_data;
 	gboolean sleeping = FALSE, enabled = FALSE;
-	GSList *connections, *iter;
 
 	g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
 	g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL);
 
 	/* Reset retries on all connections so they'll checked on wakeup */
-	if (sleeping || !enabled) {
-		connections = nm_settings_get_connections (policy->settings);
-		for (iter = connections; iter; iter = g_slist_next (iter))
-			set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
-		g_slist_free (connections);
-	}
+	if (sleeping || !enabled)
+		reset_retries_all (policy->settings);
 }
 
 static void
@@ -1045,9 +1051,15 @@ connection_added (NMSettings *settings,
 }
 
 static void
-connections_loaded (NMSettings *settings,
-					gpointer user_data)
+connections_loaded (NMSettings *settings, gpointer user_data)
 {
+	// FIXME: "connections-loaded" signal is emmitted *before* we connect to it
+	// in nm_policy_new(). So this function is never called. Currently we work around
+	// that by calling reset_retries_all() in nm_policy_new()
+	
+	/* Initialize connections' auto-retries */
+	reset_retries_all (settings);
+
 	schedule_activate_all ((NMPolicy *) user_data);
 }
 
@@ -1175,6 +1187,9 @@ nm_policy_new (NMManager *manager,
 	_connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
 	                          connection_visibility_changed);
 
+	/* Initialize connections' auto-retries */
+	reset_retries_all (policy->settings);
+
 	initialized = TRUE;
 	return policy;
 }
diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c
index c163ee6a..7ee9013a 100644
--- a/src/nm-session-monitor.c
+++ b/src/nm-session-monitor.c
@@ -74,6 +74,7 @@ typedef enum {
 	NM_SESSION_MONITOR_ERROR_IO_ERROR = 0,
 	NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE,
 	NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+	NM_SESSION_MONITOR_ERROR_NO_DATABASE,
 } NMSessionMonitorError;
 
 GQuark
@@ -101,6 +102,8 @@ nm_session_monitor_error_get_type (void)
 			ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "MalformedDatabase"),
 			/* Username or UID could could not be found */
 			ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"),
+			/* No ConsoleKit database */
+			ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NoDatabase"),
 			{ 0, 0, 0 }
 		};
 
@@ -226,10 +229,11 @@ reload_database (NMSessionMonitor *self, GError **error)
 
 	free_database (self);
 
+	errno = 0;
 	if (stat (CKDB_PATH, &statbuf) != 0) {
 		g_set_error (error,
 		             NM_SESSION_MONITOR_ERROR,
-		             NM_SESSION_MONITOR_ERROR_IO_ERROR,
+		             errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR,
 		             "Error statting file " CKDB_PATH ": %s",
 		             strerror (errno));
 		goto error;
@@ -292,10 +296,11 @@ ensure_database (NMSessionMonitor *self, GError **error)
 	if (self->database != NULL) {
 		struct stat statbuf;
 
+		errno = 0;
 		if (stat (CKDB_PATH, &statbuf) != 0) {
 			g_set_error (error,
 			             NM_SESSION_MONITOR_ERROR,
-			             NM_SESSION_MONITOR_ERROR_IO_ERROR,
+			             errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR,
 			             "Error statting file " CKDB_PATH " to check timestamp: %s",
 			             strerror (errno));
 			goto out;
@@ -346,7 +351,12 @@ nm_session_monitor_init (NMSessionMonitor *self)
 
 	error = NULL;
 	if (!ensure_database (self, &error)) {
-		nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
+		/* Ignore the first error if the CK database isn't found yet */
+		if (g_error_matches (error,
+		                     NM_SESSION_MONITOR_ERROR,
+		                     NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) {
+			nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
+		}
 		g_error_free (error);
 	}
 
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index 41a4e15b..e0795e81 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -439,9 +439,13 @@ device_creator (NMUdevManager *manager,
 		if (parent) {
 			driver = g_udev_device_get_driver (parent);
 			if (!driver) {
-				/* try the grandparent only if it's an ibmebus device */
+				/* try the grandparent if it's an ibmebus device or if the
+				 * subsys is NULL which usually indicates some sort of
+				 * platform device like a 'gadget' net interface.
+				 */
 				subsys = g_udev_device_get_subsystem (parent);
-				if (subsys && !strcmp (subsys, "ibmebus")) {
+				if (   (g_strcmp0 (subsys, "ibmebus") == 0)
+				    || (subsys == NULL)) {
 					grandparent = g_udev_device_get_parent (parent);
 					if (grandparent)
 						driver = g_udev_device_get_driver (grandparent);
diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c
index 6eab9581..f9c66473 100644
--- a/src/nm-wifi-ap.c
+++ b/src/nm-wifi-ap.c
@@ -58,12 +58,6 @@ typedef struct
 	/* Non-scanned attributes */
 	gboolean			fake;	/* Whether or not the AP is from a scan */
 	gboolean			broadcast;	/* Whether or not the AP is broadcasting (hidden) */
-	gboolean			user_created;	/* Whether or not the AP was created
-										 * by the user with "Create network..."
-										 * A subset of Ad-Hoc mode.  user_created
-										 * implies Ad-Hoc, but not necessarily
-										 * the other way around.
-										 */
 	glong				last_seen;	/* Last time the AP was seen in a scan in seconds */
 
 	/* Things from user prefs/NetworkManagerInfo */
@@ -863,9 +857,14 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid)
 	}
 
 	if (ssid) {
-		priv->ssid = g_byte_array_sized_new (ssid->len);
-		priv->ssid->len = ssid->len;
-		memcpy (priv->ssid->data, ssid->data, ssid->len);
+		/* Should never get zero-length SSIDs */
+		g_warn_if_fail (ssid->len > 0);
+
+		if (ssid->len) {
+			priv->ssid = g_byte_array_sized_new (ssid->len);
+			priv->ssid->len = ssid->len;
+			memcpy (priv->ssid->data, ssid->data, ssid->len);
+		}
 	}
 
 	g_object_notify (G_OBJECT (ap), NM_AP_SSID);
@@ -1154,28 +1153,6 @@ void nm_ap_set_last_seen (NMAccessPoint *ap, const glong last_seen)
 
 
 /*
- * Get/Set functions to indicate that an access point is
- * user-created, ie whether or not its a network filled with
- * information from the user and intended to create a new Ad-Hoc
- * wireless network.
- *
- */
-gboolean nm_ap_get_user_created (const NMAccessPoint *ap)
-{
-	g_return_val_if_fail (NM_IS_AP (ap), FALSE);
-
-	return NM_AP_GET_PRIVATE (ap)->user_created;
-}
-
-void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created)
-{
-	g_return_if_fail (NM_IS_AP (ap));
-
-	NM_AP_GET_PRIVATE (ap)->user_created = user_created;
-}
-
-
-/*
  * Get/Set functions for user address list
  *
  * The internal address list is always "owned" by the AP and
diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h
index 4c98f248..95514ba6 100644
--- a/src/nm-wifi-ap.h
+++ b/src/nm-wifi-ap.h
@@ -104,9 +104,6 @@ void				nm_ap_set_broadcast		(NMAccessPoint *ap, gboolean broadcast);
 glong			nm_ap_get_last_seen		(const NMAccessPoint *ap);
 void				nm_ap_set_last_seen		(NMAccessPoint *ap, const glong last_seen);
 
-gboolean			nm_ap_get_user_created	(const NMAccessPoint *ap);
-void				nm_ap_set_user_created	(NMAccessPoint *ap, gboolean user_created);
-
 GSList *			nm_ap_get_user_addresses	(const NMAccessPoint *ap);
 void				nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
 
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 767b9315..e863aaba 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -798,7 +798,7 @@ create_pppd_cmd_line (NMPPPManager *self,
 	NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
 	const char *ppp_binary;
 	NMCmdLine *cmd;
-	const char *ppp_debug;
+	gboolean ppp_debug;
 
 	g_return_val_if_fail (setting != NULL, NULL);
 
@@ -819,7 +819,11 @@ create_pppd_cmd_line (NMPPPManager *self,
 	/* NM handles setting the default route */
 	nm_cmd_line_add_string (cmd, "nodefaultroute");
 
-	ppp_debug = getenv ("NM_PPP_DEBUG");
+	ppp_debug = !!getenv ("NM_PPP_DEBUG");
+	if (   nm_logging_level_enabled (LOGL_DEBUG)
+	    && nm_logging_domain_enabled (LOGD_PPP))
+		ppp_debug = TRUE;
+
 	if (ppp_debug)
 		nm_cmd_line_add_string (cmd, "debug");
 
diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am
index 55b5b7ef..21dc5bb0 100644
--- a/src/settings/Makefile.am
+++ b/src/settings/Makefile.am
@@ -32,7 +32,6 @@ libsettings_la_SOURCES = \
 	nm-settings.h \
 	nm-inotify-helper.c \
 	nm-inotify-helper.h \
-	nm-polkit-helpers.h \
 	nm-settings-error.c \
 	nm-settings-error.h \
 	nm-system-config-interface.c \
diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in
index 123132b7..980f35cb 100644
--- a/src/settings/Makefile.in
+++ b/src/settings/Makefile.in
@@ -396,7 +396,6 @@ libsettings_la_SOURCES = \
 	nm-settings.h \
 	nm-inotify-helper.c \
 	nm-inotify-helper.h \
-	nm-polkit-helpers.h \
 	nm-settings-error.c \
 	nm-settings-error.h \
 	nm-system-config-interface.c \
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
index dbc29cae..8a5ea106 100644
--- a/src/settings/nm-agent-manager.c
+++ b/src/settings/nm-agent-manager.c
@@ -33,7 +33,6 @@
 #include "nm-secret-agent.h"
 #include "nm-manager-auth.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-polkit-helpers.h"
 #include "nm-manager-auth.h"
 #include "nm-setting-vpn.h"
 #include "nm-setting-connection.h"
@@ -49,7 +48,6 @@ typedef struct {
 
 	NMDBusManager *dbus_mgr;
 	NMSessionMonitor *session_monitor;
-	PolkitAuthority *authority;
 
 	/* Hashed by owner name, not identifier, since two agents in different
 	 * sessions can use the same identifier.
@@ -338,7 +336,6 @@ typedef void (*RequestCancelFunc) (Request *req);
 
 struct _Request {
 	guint32 reqid;
-	PolkitAuthority *authority;
 	NMAuthChain *chain;
 
 	NMConnection *connection;
@@ -381,7 +378,6 @@ static guint32 next_req_id = 1;
 
 static Request *
 request_new_get (NMConnection *connection,
-                 PolkitAuthority *authority,
                  gboolean filter_by_uid,
                  gulong uid_filter,
                  GHashTable *existing_secrets,
@@ -402,7 +398,6 @@ request_new_get (NMConnection *connection,
 	req = g_malloc0 (sizeof (Request));
 	req->reqid = next_req_id++;
 	req->connection = g_object_ref (connection);
-	req->authority = g_object_ref (authority);
 	req->filter_by_uid = filter_by_uid;
 	req->uid_filter = uid_filter;
 	if (existing_secrets)
@@ -462,8 +457,6 @@ request_free (Request *req)
 		g_hash_table_unref (req->existing_secrets);
 	if (req->chain)
 		nm_auth_chain_unref (req->chain);
-	if (req->authority)
-		g_object_unref (req->authority);
 	memset (req, 0, sizeof (Request));
 	g_free (req);
 }
@@ -853,10 +846,10 @@ check_system_secrets_cb (NMSetting *setting,
 		/* 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)) {
-			if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
-				if (secret_flags == NM_SETTING_SECRET_FLAG_NONE)
-					*has_system = TRUE;
-			}
+			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_NONE)
+				*has_system = TRUE;
 		}
 	} else {
 		nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
@@ -896,8 +889,7 @@ get_next_cb (Request *req)
 		nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY",
 		            req, req->setting_name, agent_dbus_owner);
 
-		req->chain = nm_auth_chain_new_dbus_sender (req->authority,
-		                                            agent_dbus_owner,
+		req->chain = nm_auth_chain_new_dbus_sender (agent_dbus_owner,
 		                                            get_agent_modify_auth_cb,
 		                                            req);
 		g_assert (req->chain);
@@ -1050,7 +1042,6 @@ nm_agent_manager_get_secrets (NMAgentManager *self,
 	 */
 
 	req = request_new_get (connection,
-	                       priv->authority,
 	                       filter_by_uid,
 	                       uid_filter,
 	                       existing_secrets,
@@ -1335,15 +1326,6 @@ static void
 nm_agent_manager_init (NMAgentManager *self)
 {
 	NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
-	GError *error = NULL;
-
-	priv->authority = polkit_authority_get_sync (NULL, &error);
-	if (!priv->authority) {
-		nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-		g_clear_error (&error);
-	}
 
 	priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 	priv->requests = g_hash_table_new_full (g_direct_hash,
@@ -1365,7 +1347,6 @@ dispose (GObject *object)
 
 		g_object_unref (priv->session_monitor);
 		g_object_unref (priv->dbus_mgr);
-		g_object_unref (priv->authority);
 	}
 
 	G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
diff --git a/src/settings/nm-polkit-helpers.h b/src/settings/nm-polkit-helpers.h
deleted file mode 100644
index d812e944..00000000
--- a/src/settings/nm-polkit-helpers.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * 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.
- *
- * (C) Copyright 2008 Novell, Inc.
- * (C) Copyright 2008 - 2010 Red Hat, Inc.
- */
-
-#ifndef NM_POLKIT_HELPERS_H
-#define NM_POLKIT_HELPERS_H
-
-#include <polkit/polkit.h>
-
-/* Fix for polkit 0.97 and later */
-#if !HAVE_POLKIT_AUTHORITY_GET_SYNC
-static inline PolkitAuthority *
-polkit_authority_get_sync (GCancellable *cancellable, GError **error)
-{
-	PolkitAuthority *authority;
-
-	authority = polkit_authority_get ();
-	if (!authority)
-		g_set_error (error, 0, 0, "failed to get the PolicyKit authority");
-	return authority;
-}
-#endif
-
-#endif /* NM_POLKIT_HELPERS_H */
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 22aef716..60de6b06 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -34,7 +34,6 @@
 #include "nm-dbus-manager.h"
 #include "nm-settings-error.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-polkit-helpers.h"
 #include "nm-logging.h"
 #include "nm-manager-auth.h"
 #include "nm-marshal.h"
@@ -83,7 +82,6 @@ typedef struct {
 	NMDBusManager *dbus_mgr;
 	NMAgentManager *agent_mgr;
 
-	PolkitAuthority *authority;
 	GSList *pending_auths; /* List of pending authentication requests */
 	NMConnection *secrets;
 	gboolean visible; /* Is this connection is visible by some session? */
@@ -98,6 +96,83 @@ typedef struct {
 
 /**************************************************************/
 
+/* Return TRUE to continue, FALSE to stop */
+typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter,
+                                       NMSettingSecretFlags flags,
+                                       gpointer user_data);
+
+static void
+for_each_secret (NMConnection *connection,
+                 GHashTable *secrets,
+                 ForEachSecretFunc callback,
+                 gpointer callback_data)
+{
+	GHashTableIter iter;
+	const char *setting_name;
+	GHashTable *setting_hash;
+
+	/* This function, given a hash of hashes representing new secrets of
+	 * an NMConnection, walks through each toplevel hash (which represents a
+	 * NMSetting), and for each setting, walks through that setting hash's
+	 * properties.  For each property that's a secret, it will check that
+	 * secret's flags in the backing NMConnection object, and call a supplied
+	 * callback.
+	 *
+	 * The one complexity is that the VPN setting's 'secrets' property is
+	 * *also* a hash table (since the key/value pairs are arbitrary and known
+	 * only to the VPN plugin itself).  That means we have three levels of
+	 * GHashTables that we potentially have to traverse here.  When we hit the
+	 * VPN setting's 'secrets' property, we special-case that and iterate over
+	 * each item in that 'secrets' hash table, calling the supplied callback
+	 * each time.
+	 */
+
+	/* Walk through the list of setting hashes */
+	g_hash_table_iter_init (&iter, secrets);
+	while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
+		NMSetting *setting;
+		GHashTableIter secret_iter;
+		const char *secret_name;
+		GValue *val;
+
+		/* Get the actual NMSetting from the connection so we can get secret flags
+		 * from the connection data, since flags aren't secrets.  What we're
+		 * iterating here is just the secrets, not a whole connection.
+		 */
+		setting = nm_connection_get_setting_by_name (connection, setting_name);
+		if (setting == NULL)
+			continue;
+
+		/* Walk through the list of keys in each setting hash */
+		g_hash_table_iter_init (&secret_iter, setting_hash);
+		while (g_hash_table_iter_next (&secret_iter, (gpointer) &secret_name, (gpointer) &val)) {
+			NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+			/* VPN secrets need slightly different treatment here since the
+			 * "secrets" property is actually a hash table of secrets.
+			 */
+			if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS) == 0)) {
+				GHashTableIter vpn_secrets_iter;
+
+				/* Iterate through each secret from the VPN hash in the overall secrets hash */
+				g_hash_table_iter_init (&vpn_secrets_iter, g_value_get_boxed (val));
+				while (g_hash_table_iter_next (&vpn_secrets_iter, (gpointer) &secret_name, NULL)) {
+					secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+					nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
+					if (callback (&vpn_secrets_iter, secret_flags, callback_data) == FALSE)
+						return;
+				}
+			} else {
+				nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL);
+				if (callback (&secret_iter, secret_flags, callback_data) == FALSE)
+					return;
+			}
+		}
+	}
+}
+
+/**************************************************************/
+
 static void
 set_visible (NMSettingsConnection *self, gboolean new_visible)
 {
@@ -112,7 +187,8 @@ set_visible (NMSettingsConnection *self, gboolean new_visible)
 gboolean
 nm_settings_connection_is_visible (NMSettingsConnection *self)
 {
-	g_return_val_if_fail (NM_SETTINGS_CONNECTION (self), FALSE);
+	g_return_val_if_fail (self != NULL, FALSE);
+	g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
 
 	return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible;
 }
@@ -124,7 +200,8 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self)
 	NMSettingConnection *s_con;
 	guint32 num, i;
 
-	g_return_if_fail (NM_SETTINGS_CONNECTION (self));
+	g_return_if_fail (self != NULL);
+	g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
 
 	priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 
@@ -178,10 +255,10 @@ only_system_secrets_cb (NMSetting *setting,
 
 			g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
 			while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
-				if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
-					if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
-						nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
-				}
+				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_NONE)
+					nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
 			}
 		} else {
 			nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
@@ -204,15 +281,26 @@ update_secrets_cache (NMSettingsConnection *self)
 	nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL);
 }
 
+static gboolean
+clear_system_secrets (GHashTableIter *iter,
+                      NMSettingSecretFlags flags,
+                      gpointer user_data)
+{
+	if (flags == NM_SETTING_SECRET_FLAG_NONE)
+		g_hash_table_iter_remove (iter);
+	return TRUE;
+}
+
 /* Update the settings of this connection to match that of 'new', taking care to
- * make a private copy of secrets. */
+ * make a private copy of secrets.
+ */
 gboolean
 nm_settings_connection_replace_settings (NMSettingsConnection *self,
                                          NMConnection *new,
                                          GError **error)
 {
 	NMSettingsConnectionPrivate *priv;
-	GHashTable *new_settings;
+	GHashTable *new_settings, *transient_secrets;
 	gboolean success = FALSE;
 
 	g_return_val_if_fail (self != NULL, FALSE);
@@ -222,18 +310,48 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
 
 	priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 
+	/* Replacing the settings might replace transient secrets, such as when
+	 * a user agent returns secrets, which might trigger the connection to be
+	 * written out, which triggers an inotify event to re-read and update the
+	 * connection, which, if we're not careful, could wipe out the transient
+	 * secrets the user agent just sent us.  Basically, only
+	 * nm_connection_clear_secrets() should wipe out transient secrets but
+	 * re-reading a connection from on-disk and updating our in-memory copy
+	 * should not.  Thus we preserve non-system-owned secrets here.
+	 */
+	transient_secrets = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+	if (transient_secrets)
+		for_each_secret (NM_CONNECTION (self), transient_secrets, clear_system_secrets, NULL);
+
 	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);
+			}
+		}
+
 		nm_settings_connection_recheck_visibility (self);
 		success = TRUE;
 	}
 	g_hash_table_destroy (new_settings);
+	if (transient_secrets)
+		g_hash_table_destroy (transient_secrets);
 	return success;
 }
 
@@ -398,11 +516,6 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name)
 	return TRUE;
 }
 
-/* Return TRUE to continue, FALSE to stop */
-typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter,
-                                       NMSettingSecretFlags flags,
-                                       gpointer user_data);
-
 static gboolean
 clear_nonagent_secrets (GHashTableIter *iter,
                         NMSettingSecretFlags flags,
@@ -430,7 +543,7 @@ has_system_owned_secrets (GHashTableIter *iter,
 {
 	gboolean *has_system_owned = user_data;
 
-	if (!(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) {
+	if (flags == NM_SETTING_SECRET_FLAG_NONE) {
 		*has_system_owned = TRUE;
 		return FALSE;
 	}
@@ -438,40 +551,6 @@ has_system_owned_secrets (GHashTableIter *iter,
 }
 
 static void
-for_each_secret (NMConnection *connection,
-                 GHashTable *secrets,
-                 ForEachSecretFunc callback,
-                 gpointer callback_data)
-{
-	GHashTableIter iter;
-	const char *setting_name;
-	GHashTable *setting_hash;
-
-	/* Walk through the list of setting hashes */
-	g_hash_table_iter_init (&iter, secrets);
-	while (g_hash_table_iter_next (&iter,
-	                               (gpointer *) &setting_name,
-	                               (gpointer *) &setting_hash)) {
-		GHashTableIter setting_iter;
-		const char *secret_name;
-
-		/* Walk through the list of keys in each setting hash */
-		g_hash_table_iter_init (&setting_iter, setting_hash);
-		while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) {
-			NMSetting *setting;
-			NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
-
-			/* Get the actual NMSetting from the connection so we can get secret flags */
-			setting = nm_connection_get_setting_by_name (connection, setting_name);
-			if (setting && nm_setting_get_secret_flags (setting, secret_name, &flags, NULL)) {
-				if (callback (&setting_iter, flags, callback_data) == FALSE)
-					return;
-			}
-		}
-	}
-}
-
-static void
 new_secrets_commit_cb (NMSettingsConnection *connection,
                        GError *error,
                        gpointer user_data)
@@ -850,7 +929,7 @@ auth_start (NMSettingsConnection *self,
 	}
 
 	if (check_permission) {
-		chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self);
+		chain = nm_auth_chain_new (context, NULL, pk_auth_cb, self);
 		g_assert (chain);
 		nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL);
 		nm_auth_chain_set_data (chain, "callback", callback, NULL);
@@ -980,10 +1059,10 @@ only_agent_secrets_cb (NMSetting *setting,
 			/* 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)) {
-				if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
-					if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
-						nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
-				}
+				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)
+					nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
 			}
 		} else {
 			nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
@@ -1271,7 +1350,8 @@ nm_settings_connection_signal_remove (NMSettingsConnection *self)
 guint64
 nm_settings_connection_get_timestamp (NMSettingsConnection *connection)
 {
-	g_return_val_if_fail (NM_SETTINGS_CONNECTION (connection), 0);
+	g_return_val_if_fail (connection != NULL, 0);
+	g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0);
 
 	return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->timestamp;
 }
@@ -1368,18 +1448,9 @@ nm_settings_connection_init (NMSettingsConnection *self)
 	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 	static guint32 dbus_counter = 0;
 	char *dbus_path;
-	GError *error = NULL;
 
 	priv->dbus_mgr = nm_dbus_manager_get ();
 
-	priv->authority = polkit_authority_get_sync (NULL, &error);
-	if (!priv->authority) {
-		nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-		g_clear_error (&error);
-	}
-
 	dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++);
 	nm_connection_set_path (NM_CONNECTION (self), dbus_path);
 	g_free (dbus_path);
@@ -1421,10 +1492,11 @@ dispose (GObject *object)
 
 	set_visible (self, FALSE);
 
+	if (priv->session_changed_id)
+		g_signal_handler_disconnect (priv->session_monitor, priv->session_changed_id);
 	g_object_unref (priv->session_monitor);
 	g_object_unref (priv->agent_mgr);
 	g_object_unref (priv->dbus_mgr);
-	g_object_unref (priv->authority);
 
 out:
 	G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object);
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 87fa4b6c..e23e8d13 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -56,7 +56,6 @@
 #include "nm-dbus-glib-types.h"
 #include "nm-settings.h"
 #include "nm-settings-connection.h"
-#include "nm-polkit-helpers.h"
 #include "nm-settings-error.h"
 #include "nm-default-wired-connection.h"
 #include "nm-logging.h"
@@ -114,8 +113,6 @@ typedef struct {
 
 	NMAgentManager *agent_mgr;
 
-	PolkitAuthority *authority;
-	guint auth_changed_id;
 	char *config_file;
 
 	NMSessionMonitor *session_monitor;
@@ -702,6 +699,46 @@ connection_visibility_changed (NMSettingsConnection *connection,
 	               connection);
 }
 
+#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"
+#define NM_OPENCONNECT_KEY_XMLCONFIG "xmlconfig"
+#define NM_OPENCONNECT_KEY_LASTHOST "lasthost"
+#define NM_OPENCONNECT_KEY_AUTOCONNECT "autoconnect"
+#define NM_OPENCONNECT_KEY_CERTSIGS "certsigs"
+
+static void
+openconnect_migrate_hack (NMConnection *connection)
+{
+	NMSettingVPN *s_vpn;
+	NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NOT_SAVED;
+
+	/* Huge hack.  There were some openconnect changes that needed to happen
+	 * pretty late, too late to get into distros.  Migration has already
+	 * happened for many people, and their secret flags are wrong.  But we
+	 * don't want to requrie re-migration, so we have to fix it up here. Ugh.
+	 */
+
+	s_vpn = nm_connection_get_setting_vpn (connection);
+	if (s_vpn == NULL)
+		return;
+
+	if (g_strcmp0 (nm_setting_vpn_get_service_type (s_vpn), NM_DBUS_SERVICE_OPENCONNECT) == 0) {
+		/* These are different for every login session, and should not be stored */
+		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);
+
+		/* 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);
+	}
+}
+
 static void
 claim_connection (NMSettings *self,
                   NMSettingsConnection *connection,
@@ -739,6 +776,9 @@ claim_connection (NMSettings *self,
 	/* Ensure it's initial visibility is up-to-date */
 	nm_settings_connection_recheck_visibility (connection);
 
+	/* Evil openconnect migration hack */
+	openconnect_migrate_hack (NM_CONNECTION (connection));
+
 	id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED,
 	                       G_CALLBACK (connection_removed),
 	                       self);
@@ -999,7 +1039,7 @@ nm_settings_add_connection (NMSettings *self,
 		perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
 
 	/* Otherwise validate the user request */
-	chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self);
+	chain = nm_auth_chain_new (context, NULL, pk_add_cb, self);
 	g_assert (chain);
 	priv->auths = g_slist_append (priv->auths, chain);
 	nm_auth_chain_add_call (chain, perm, TRUE);
@@ -1111,7 +1151,7 @@ impl_settings_save_hostname (NMSettings *self,
 	}
 
 	/* Otherwise validate the user request */
-	chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self);
+	chain = nm_auth_chain_new (context, NULL, pk_hostname_cb, self);
 	g_assert (chain);
 	priv->auths = g_slist_append (priv->auths, chain);
 	nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE);
@@ -1476,18 +1516,9 @@ static void
 nm_settings_init (NMSettings *self)
 {
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
-	GError *error = NULL;
 
 	priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
 
-	priv->authority = polkit_authority_get_sync (NULL, &error);
-	if (!priv->authority) {
-		nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
-		g_clear_error (&error);
-	}
-
 	priv->session_monitor = nm_session_monitor_get ();
 
 	/* Hold a reference to the agent manager so it stays alive; the only
@@ -1505,11 +1536,6 @@ dispose (GObject *object)
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	GSList *iter;
 
-	if (priv->auth_changed_id) {
-		g_signal_handler_disconnect (priv->authority, priv->auth_changed_id);
-		priv->auth_changed_id = 0;
-	}
-
 	for (iter = priv->auths; iter; iter = g_slist_next (iter))
 		nm_auth_chain_unref ((NMAuthChain *) iter->data);
 	g_slist_free (priv->auths);
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index 5ecf5891..eeb14556 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -453,17 +453,22 @@ write_hash_of_string (GKeyFile *file,
 
 	g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
 	while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) {
-		NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+		gboolean write_item = TRUE;
 
 		/* Handle VPN secrets specially; they are nested in the property's hash;
-		 * we don't want to write them if the secret is not saved or not required.
+		 * we don't want to write them if the secret is not saved, not required,
+		 * or owned by a user's secret agent.
 		 */
-		if (vpn_secrets && nm_setting_get_secret_flags (setting, property, &flags, NULL)) {
-			if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
-				continue;
+		if (vpn_secrets) {
+			NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+			nm_setting_get_secret_flags (setting, property, &secret_flags, NULL);
+			if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
+				write_item = FALSE;
 		}
 
-		g_key_file_set_string (file, group_name, property, data);
+		if (write_item)
+			g_key_file_set_string (file, group_name, property, data);
 	}
 }
 
@@ -799,7 +804,6 @@ write_setting_value (NMSetting *setting,
 	GType type = G_VALUE_TYPE (value);
 	KeyWriter *writer = &key_writers[0];
 	GParamSpec *pspec;
-	NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
 
 	/* Setting name gets picked up from the keyfile's section name instead */
 	if (!strcmp (key, NM_SETTING_NAME))
@@ -822,12 +826,17 @@ write_setting_value (NMSetting *setting,
 	}
 
 	/* Don't write secrets that are owned by user secret agents or aren't
-	 * supposed to be saved.
+	 * supposed to be saved.  VPN secrets are handled specially though since
+	 * the secret flags there are in a third-level hash in the 'secrets'
+	 * property.
 	 */
-	if (   (pspec->flags & NM_SETTING_PARAM_SECRET)
-	    && nm_setting_get_secret_flags (setting, key, &flags, NULL)
-	    && (flags != NM_SETTING_SECRET_FLAG_NONE))
-		return;
+	if (pspec->flags & NM_SETTING_PARAM_SECRET && !NM_IS_SETTING_VPN (setting)) {
+		NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
+		if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
+			return;
+	}
 
 	/* Look through the list of handlers for non-standard format key values */
 	while (writer->setting_name) {
diff --git a/src/vpn-manager/Makefile.am b/src/vpn-manager/Makefile.am
index 3b206617..ce99728e 100644
--- a/src/vpn-manager/Makefile.am
+++ b/src/vpn-manager/Makefile.am
@@ -22,6 +22,7 @@ libvpn_manager_la_SOURCES = \
 	nm-vpn-connection.h
 
 libvpn_manager_la_CPPFLAGS =	\
+	$(LIBNL_CFLAGS)		\
 	$(DBUS_CFLAGS)		\
 	$(GLIB_CFLAGS)		\
 	-DG_DISABLE_DEPRECATED
@@ -30,6 +31,7 @@ libvpn_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in
index a8fea32d..3785667e 100644
--- a/src/vpn-manager/Makefile.in
+++ b/src/vpn-manager/Makefile.in
@@ -60,7 +60,7 @@ libvpn_manager_la_DEPENDENCIES =  \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am_libvpn_manager_la_OBJECTS = libvpn_manager_la-nm-vpn-manager.lo \
 	libvpn_manager_la-nm-vpn-service.lo \
 	libvpn_manager_la-nm-vpn-connection-base.lo \
@@ -328,6 +328,7 @@ libvpn_manager_la_SOURCES = \
 	nm-vpn-connection.h
 
 libvpn_manager_la_CPPFLAGS = \
+	$(LIBNL_CFLAGS)		\
 	$(DBUS_CFLAGS)		\
 	$(GLIB_CFLAGS)		\
 	-DG_DISABLE_DEPRECATED
@@ -336,6 +337,7 @@ libvpn_manager_la_LIBADD = \
 	$(top_builddir)/marshallers/libmarshallers.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
+	$(LIBNL_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
 
diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c
index 12db7e27..9dff503d 100644
--- a/src/wimax/nm-device-wimax.c
+++ b/src/wimax/nm-device-wimax.c
@@ -278,6 +278,8 @@ remove_all_nsps (NMDeviceWimax *self)
 {
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 
+	set_current_nsp (self, NULL);
+
 	while (g_slist_length (priv->nsp_list)) {
 		NMWimaxNsp *nsp = NM_WIMAX_NSP (priv->nsp_list->data);
 
@@ -717,29 +719,43 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
 	NMActRequest *req;
 	GSList *iter;
 	const char *path;
+	NMWimaxNsp *nsp = NULL;
 
 	clear_link_timeout (NM_DEVICE_WIMAX (device));
 
+	*reason = NM_DEVICE_STATE_REASON_NONE;
+
 	req = nm_device_get_act_request (device);
 	if (!req)
-		goto err;
+		return NM_ACT_STAGE_RETURN_FAILURE;
 
 	path = nm_act_request_get_specific_object (req);
 	if (!path)
-		goto err;
+		return NM_ACT_STAGE_RETURN_FAILURE;
 
+	/* Find the NSP in the scan list */
 	for (iter = priv->nsp_list; iter; iter = iter->next) {
-		NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+		NMWimaxNsp *candidate = NM_WIMAX_NSP (iter->data);
 
-		if (!strcmp (path, nm_wimax_nsp_get_dbus_path (nsp))) {
-			set_current_nsp (NM_DEVICE_WIMAX (device), nsp);
-			return NM_ACT_STAGE_RETURN_SUCCESS;
+		if (!strcmp (path, nm_wimax_nsp_get_dbus_path (candidate))) {
+			nsp = candidate;
+			break;
 		}
 	}
 
- err:
-	*reason = NM_DEVICE_STATE_REASON_NONE;
-	return NM_ACT_STAGE_RETURN_FAILURE;
+	/* Couldn't find the NSP for some reason */
+	if (nsp == NULL)
+		return NM_ACT_STAGE_RETURN_FAILURE;
+
+	set_current_nsp (NM_DEVICE_WIMAX (device), nsp);
+
+	/* If the device is scanning, it won't connect, so we have to wait until
+	 * it's not scanning to proceed to stage 2.
+	 */
+	if (priv->status == WIMAX_API_DEVICE_STATUS_Scanning)
+		return NM_ACT_STAGE_RETURN_POSTPONE;
+
+	return NM_ACT_STAGE_RETURN_SUCCESS;
 }
 
 static NMActStageReturn
@@ -857,11 +873,11 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 	if (priv->current_nsp)
 		nsp_name = nm_wimax_nsp_get_name (priv->current_nsp);
 
-	nm_log_dbg (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)",
-	            iface,
-	            iwmx_sdk_dev_status_to_str (old_status),
-	            iwmx_sdk_dev_status_to_str (new_status),
-	            reason);
+	nm_log_info (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)",
+	             iface,
+	             iwmx_sdk_dev_status_to_str (old_status),
+	             iwmx_sdk_dev_status_to_str (new_status),
+	             reason);
 
 	switch (new_status) {
 	case WIMAX_API_DEVICE_STATUS_UnInitialized:
@@ -915,6 +931,18 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 			                         NM_DEVICE_STATE_REASON_CONFIG_FAILED);
 			return;
 		}
+
+		/* If stage2 was postponed because the device was scanning or something,
+		 * then check if we need to move to stage2 now that the device might be
+		 * ready.
+		 */
+		if (state == NM_DEVICE_STATE_PREPARE) {
+			if (   new_status == WIMAX_API_DEVICE_STATUS_Ready
+			    || new_status == WIMAX_API_DEVICE_STATUS_Connecting) {
+				nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self));
+				return;
+			}
+		}
 	}
 
 	/* Handle disconnection */
@@ -1252,15 +1280,17 @@ device_state_changed (NMDevice *device,
 	if (new_state < NM_DEVICE_STATE_DISCONNECTED)
 		remove_all_nsps (self);
 
-	/* Request initial NSP list */
+	/* Request initial NSP list when device is first started */
 	if (   new_state == NM_DEVICE_STATE_DISCONNECTED
 	    && old_state < NM_DEVICE_STATE_DISCONNECTED) {
 		if (priv->sdk)
 			iwmx_sdk_get_networks (priv->sdk);
 	}
 
-	if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED)
+	if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) {
+		set_current_nsp (self, NULL);
 		clear_activation_timeout (self);
+	}
 
 	if (new_state == NM_DEVICE_STATE_ACTIVATED) {
 		/* poll link quality and BSID */