1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Copyright (C) 2007 - 2009 Novell, Inc.
19 * Copyright (C) 2007 - 2012 Red Hat, Inc.
22 #include "nm-default.h"
30 #include "nm-manager.h"
31 #include "nm-bus-manager.h"
32 #include "nm-vpn-manager.h"
33 #include "nm-device.h"
34 #include "nm-device-generic.h"
35 #include "nm-platform.h"
36 #include "nm-rfkill-manager.h"
37 #include "nm-dhcp-manager.h"
38 #include "nm-settings.h"
39 #include "nm-settings-connection.h"
40 #include "nm-auth-utils.h"
41 #include "nm-auth-manager.h"
42 #include "NetworkManagerUtils.h"
43 #include "nm-device-factory.h"
44 #include "nm-enum-types.h"
45 #include "nm-sleep-monitor.h"
46 #include "nm-connectivity.h"
47 #include "nm-policy.h"
48 #include "nm-connection-provider.h"
49 #include "nm-session-monitor.h"
50 #include "nm-activation-request.h"
51 #include "nm-core-internal.h"
52 #include "nm-config.h"
53 #include "nm-audit-manager.h"
54 #include "nm-dbus-compat.h"
55 #include "NetworkManagerUtils.h"
57 #include "nmdbus-manager.h"
58 #include "nmdbus-device.h"
60 static gboolean add_device (NMManager *self, NMDevice *device, GError **error);
62 static NMActiveConnection *_new_active_connection (NMManager *self,
63 NMConnection *connection,
64 const char *specific_object,
66 NMAuthSubject *subject,
69 static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
71 static void rfkill_change (const char *desc, RfKillType rtype, gboolean enabled);
73 static gboolean find_master (NMManager *self,
74 NMConnection *connection,
76 NMSettingsConnection **out_master_connection,
77 NMDevice **out_master_device,
78 NMActiveConnection **out_master_ac,
81 static void nm_manager_update_state (NMManager *manager);
83 static void connection_changed (NMSettings *settings, NMConnection *connection,
86 #define TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE "act-con-add-and-activate"
89 gboolean user_enabled;
102 GSList *active_connections;
103 GSList *authorizing_connections;
105 NMActiveConnection *primary_connection;
106 NMActiveConnection *activating_connection;
112 NMConnectivity *connectivity;
116 NMBusManager *dbus_mgr;
118 GDBusConnection *connection;
121 NMRfkillManager *rfkill_mgr;
123 NMSettings *settings;
126 RadioState radio_states[RFKILL_TYPE_MAX];
128 gboolean net_enabled;
130 NMVpnManager *vpn_manager;
132 NMSleepMonitor *sleep_monitor;
136 /* Firmware dir monitor */
137 GFileMonitor *fw_monitor;
140 guint timestamp_update_id;
143 gboolean devices_inited;
146 #define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
148 G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
152 INTERNAL_DEVICE_ADDED,
154 INTERNAL_DEVICE_REMOVED,
157 USER_PERMISSIONS_CHANGED,
158 ACTIVE_CONNECTION_ADDED,
159 ACTIVE_CONNECTION_REMOVED,
165 static guint signals[LAST_SIGNAL] = { 0 };
173 PROP_NETWORKING_ENABLED,
174 PROP_WIRELESS_ENABLED,
175 PROP_WIRELESS_HARDWARE_ENABLED,
177 PROP_WWAN_HARDWARE_ENABLED,
179 PROP_WIMAX_HARDWARE_ENABLED,
180 PROP_ACTIVE_CONNECTIONS,
182 PROP_PRIMARY_CONNECTION,
183 PROP_PRIMARY_CONNECTION_TYPE,
184 PROP_ACTIVATING_CONNECTION,
187 PROP_GLOBAL_DNS_CONFIGURATION,
197 NM_DEFINE_SINGLETON_INSTANCE (NMManager);
199 /************************************************************************/
201 #define _NMLOG_PREFIX_NAME "manager"
202 #define _NMLOG(level, domain, ...) \
204 const NMLogLevel __level = (level); \
205 const NMLogDomain __domain = (domain); \
207 if (nm_logging_enabled (__level, __domain)) { \
208 const NMManager *const __self = (self); \
211 _nm_log (__level, __domain, 0, \
212 "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
213 _NMLOG_PREFIX_NAME, \
214 (__self && __self != singleton_instance) \
215 ? nm_sprintf_buf (__sbuf, "[%p]", __self) \
217 _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
221 /************************************************************************/
223 static void active_connection_state_changed (NMActiveConnection *active,
226 static void active_connection_default_changed (NMActiveConnection *active,
229 static void active_connection_parent_active (NMActiveConnection *active,
230 NMActiveConnection *parent_ac,
233 /* Returns: whether to notify D-Bus of the removal or not */
235 active_connection_remove (NMManager *self, NMActiveConnection *active)
237 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
238 gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
241 /* FIXME: switch to a GList for faster removal */
242 found = g_slist_find (priv->active_connections, active);
244 NMSettingsConnection *connection;
246 priv->active_connections = g_slist_remove (priv->active_connections, active);
247 g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
248 g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
249 g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
250 g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
252 if ( nm_active_connection_get_assumed (active)
253 && (connection = nm_active_connection_get_settings_connection (active))
254 && nm_settings_connection_get_nm_generated_assumed (connection))
255 g_object_ref (connection);
259 nm_exported_object_clear_and_unexport (&active);
262 && nm_settings_has_connection (priv->settings, connection)) {
263 _LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
264 nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
265 nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL);
266 g_object_unref (connection);
270 return found && notify;
274 _active_connection_cleanup (gpointer user_data)
276 NMManager *self = NM_MANAGER (user_data);
277 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
280 priv->ac_cleanup_id = 0;
282 g_object_freeze_notify (G_OBJECT (self));
283 iter = priv->active_connections;
285 NMActiveConnection *ac = iter->data;
288 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
289 if (active_connection_remove (self, ac))
290 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
293 g_object_thaw_notify (G_OBJECT (self));
299 active_connection_state_changed (NMActiveConnection *active,
303 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
304 NMActiveConnectionState state;
306 state = nm_active_connection_get_state (active);
307 if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
308 /* Destroy active connections from an idle handler to ensure that
309 * their last property change notifications go out, which wouldn't
310 * happen if we destroyed them immediately when their state was set
313 if (!priv->ac_cleanup_id)
314 priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
317 nm_manager_update_state (self);
321 active_connection_default_changed (NMActiveConnection *active,
325 nm_manager_update_state (self);
329 * active_connection_add():
330 * @self: the #NMManager
331 * @active: the #NMActiveConnection to manage
333 * Begins to track and manage @active. Increases the refcount of @active.
336 active_connection_add (NMManager *self, NMActiveConnection *active)
338 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
340 g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
342 priv->active_connections = g_slist_prepend (priv->active_connections,
343 g_object_ref (active));
345 g_signal_connect (active,
346 "notify::" NM_ACTIVE_CONNECTION_STATE,
347 G_CALLBACK (active_connection_state_changed),
349 g_signal_connect (active,
350 "notify::" NM_ACTIVE_CONNECTION_DEFAULT,
351 G_CALLBACK (active_connection_default_changed),
353 g_signal_connect (active,
354 "notify::" NM_ACTIVE_CONNECTION_DEFAULT6,
355 G_CALLBACK (active_connection_default_changed),
358 g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
360 /* Only notify D-Bus if the active connection is actually exported */
361 if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active)))
362 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
366 nm_manager_get_active_connections (NMManager *manager)
368 return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
371 static NMActiveConnection *
372 find_ac_for_connection (NMManager *manager, NMConnection *connection)
374 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
376 const char *uuid = NULL;
377 gboolean is_settings_connection;
379 is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
381 if (!is_settings_connection)
382 uuid = nm_connection_get_uuid (connection);
384 for (iter = priv->active_connections; iter; iter = iter->next) {
385 NMActiveConnection *ac = iter->data;
386 NMSettingsConnection *con;
388 con = nm_active_connection_get_settings_connection (ac);
390 /* depending on whether we have a NMSettingsConnection or a NMConnection,
391 * we lookup by UUID or by reference. */
392 if (is_settings_connection) {
393 if (con != (NMSettingsConnection *) connection)
396 if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
399 if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
406 /* Filter out connections that are already active.
407 * nm_settings_get_connections() returns sorted list. We need to preserve the
408 * order so that we didn't change auto-activation order (recent timestamps
410 * Caller is responsible for freeing the returned list with g_slist_free().
413 nm_manager_get_activatable_connections (NMManager *manager)
415 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
416 GSList *all_connections = nm_settings_get_connections (priv->settings);
417 GSList *connections = NULL, *iter;
418 NMSettingsConnection *connection;
420 for (iter = all_connections; iter; iter = iter->next) {
421 connection = iter->data;
423 if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
424 connections = g_slist_prepend (connections, connection);
427 g_slist_free (all_connections);
428 return g_slist_reverse (connections);
431 static NMActiveConnection *
432 active_connection_get_by_path (NMManager *manager, const char *path)
434 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
437 g_return_val_if_fail (manager != NULL, NULL);
438 g_return_val_if_fail (path != NULL, NULL);
440 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
441 NMActiveConnection *candidate = iter->data;
443 if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
449 /************************************************************************/
452 _config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
454 g_object_set (NM_MANAGER_GET_PRIVATE (self)->connectivity,
455 NM_CONNECTIVITY_URI, nm_config_data_get_connectivity_uri (config_data),
456 NM_CONNECTIVITY_INTERVAL, nm_config_data_get_connectivity_interval (config_data),
457 NM_CONNECTIVITY_RESPONSE, nm_config_data_get_connectivity_response (config_data),
460 if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG))
461 g_object_notify (G_OBJECT (self), NM_MANAGER_GLOBAL_DNS_CONFIGURATION);
464 /************************************************************************/
467 nm_manager_get_device_by_path (NMManager *manager, const char *path)
471 g_return_val_if_fail (path != NULL, NULL);
473 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
474 if (!strcmp (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)), path))
475 return NM_DEVICE (iter->data);
481 nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
485 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
486 NMDevice *device = NM_DEVICE (iter->data);
488 if (nm_device_get_ifindex (device) == ifindex)
496 find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
499 const char *device_addr;
501 g_return_val_if_fail (hwaddr != NULL, NULL);
503 if (nm_utils_hwaddr_valid (hwaddr, -1)) {
504 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
505 device_addr = nm_device_get_hw_address (NM_DEVICE (iter->data));
506 if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
507 return NM_DEVICE (iter->data);
514 find_device_by_ip_iface (NMManager *self, const gchar *iface)
518 g_return_val_if_fail (iface != NULL, NULL);
520 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
521 NMDevice *candidate = iter->data;
523 if ( nm_device_is_real (candidate)
524 && g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
531 * find_device_by_iface:
532 * @self: the #NMManager
533 * @iface: the device interface to find
534 * @connection: a connection to ensure the returned device is compatible with
535 * @slave: a slave connection to ensure a master is compatible with
537 * Finds a device by interface name, preferring realized devices. If @slave
538 * is given, this function will only return master devices and will ensure
539 * @slave, when activated, can be a slave of the returned master device. If
540 * @connection is given, this function will only consider devices that are
541 * compatible with @connection.
543 * Returns: the matching #NMDevice
546 find_device_by_iface (NMManager *self,
548 NMConnection *connection,
551 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
552 NMDevice *fallback = NULL;
555 g_return_val_if_fail (iface != NULL, NULL);
557 for (iter = priv->devices; iter; iter = iter->next) {
558 NMDevice *candidate = iter->data;
560 if (strcmp (nm_device_get_iface (candidate), iface))
562 if (connection && !nm_device_check_connection_compatible (candidate, connection))
565 if (!nm_device_is_master (candidate))
567 if (!nm_device_check_slave_connection_compatible (candidate, slave))
571 if (nm_device_is_real (candidate))
574 fallback = candidate;
580 manager_sleeping (NMManager *self)
582 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
584 if (priv->sleeping || !priv->net_enabled)
590 _nm_state_to_string (NMState state)
593 case NM_STATE_ASLEEP:
595 case NM_STATE_DISCONNECTED:
596 return "DISCONNECTED";
597 case NM_STATE_DISCONNECTING:
598 return "DISCONNECTING";
599 case NM_STATE_CONNECTING:
601 case NM_STATE_CONNECTED_LOCAL:
602 return "CONNECTED_LOCAL";
603 case NM_STATE_CONNECTED_SITE:
604 return "CONNECTED_SITE";
605 case NM_STATE_CONNECTED_GLOBAL:
606 return "CONNECTED_GLOBAL";
607 case NM_STATE_UNKNOWN:
614 set_state (NMManager *self, NMState state)
616 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
618 if (priv->state == state)
623 _LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
625 g_object_notify (G_OBJECT (self), NM_MANAGER_STATE);
626 g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state);
630 checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
632 NMManager *manager = user_data;
633 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
634 NMConnectivityState connectivity;
636 if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
637 connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
639 if (connectivity == NM_CONNECTIVITY_FULL)
640 set_state (manager, NM_STATE_CONNECTED_GLOBAL);
641 else if ( connectivity == NM_CONNECTIVITY_PORTAL
642 || connectivity == NM_CONNECTIVITY_LIMITED)
643 set_state (manager, NM_STATE_CONNECTED_SITE);
644 g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY);
647 g_object_unref (manager);
651 find_best_device_state (NMManager *manager)
653 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
654 NMState best_state = NM_STATE_DISCONNECTED;
657 for (iter = priv->active_connections; iter; iter = iter->next) {
658 NMActiveConnection *ac = NM_ACTIVE_CONNECTION (iter->data);
659 NMActiveConnectionState ac_state = nm_active_connection_get_state (ac);
662 case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
663 if ( nm_active_connection_get_default (ac)
664 || nm_active_connection_get_default6 (ac)) {
665 if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL)
666 return NM_STATE_CONNECTED_GLOBAL;
668 best_state = NM_STATE_CONNECTED_SITE;
670 if (best_state < NM_STATE_CONNECTING)
671 best_state = NM_STATE_CONNECTED_LOCAL;
674 case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
675 if (!nm_active_connection_get_assumed (ac)) {
676 if (best_state != NM_STATE_CONNECTED_GLOBAL)
677 best_state = NM_STATE_CONNECTING;
680 case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
681 if (!nm_active_connection_get_assumed (ac)) {
682 if (best_state < NM_STATE_DISCONNECTING)
683 best_state = NM_STATE_DISCONNECTING;
695 nm_manager_update_metered (NMManager *self)
697 NMManagerPrivate *priv;
699 NMMetered value = NM_METERED_UNKNOWN;
701 g_return_if_fail (NM_IS_MANAGER (self));
702 priv = NM_MANAGER_GET_PRIVATE (self);
704 if (priv->primary_connection) {
705 device = nm_active_connection_get_device (priv->primary_connection);
707 value = nm_device_get_metered (device);
710 if (value != priv->metered) {
711 priv->metered = value;
712 _LOGD (LOGD_CORE, "new metered value: %d", (int) priv->metered);
713 g_object_notify (G_OBJECT (self), NM_MANAGER_METERED);
718 nm_manager_update_state (NMManager *manager)
720 NMManagerPrivate *priv;
721 NMState new_state = NM_STATE_DISCONNECTED;
723 g_return_if_fail (NM_IS_MANAGER (manager));
725 priv = NM_MANAGER_GET_PRIVATE (manager);
727 if (manager_sleeping (manager))
728 new_state = NM_STATE_ASLEEP;
730 new_state = find_best_device_state (manager);
732 nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
734 if (new_state == NM_STATE_CONNECTED_SITE) {
735 nm_connectivity_check_async (priv->connectivity,
736 checked_connectivity,
737 g_object_ref (manager));
740 set_state (manager, new_state);
744 manager_device_state_changed (NMDevice *device,
745 NMDeviceState new_state,
746 NMDeviceState old_state,
747 NMDeviceStateReason reason,
750 NMManager *self = NM_MANAGER (user_data);
751 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
754 case NM_DEVICE_STATE_UNMANAGED:
755 case NM_DEVICE_STATE_UNAVAILABLE:
756 case NM_DEVICE_STATE_DISCONNECTED:
757 case NM_DEVICE_STATE_PREPARE:
758 case NM_DEVICE_STATE_FAILED:
759 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
765 if ( new_state == NM_DEVICE_STATE_UNAVAILABLE
766 || new_state == NM_DEVICE_STATE_DISCONNECTED)
767 nm_settings_device_added (priv->settings, device);
770 static void device_has_pending_action_changed (NMDevice *device,
775 check_if_startup_complete (NMManager *self)
777 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
783 if (!priv->devices_inited)
786 if (!nm_settings_get_startup_complete (priv->settings)) {
787 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
791 for (iter = priv->devices; iter; iter = iter->next) {
792 NMDevice *dev = iter->data;
794 if (nm_device_has_pending_action (dev)) {
795 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
796 nm_device_get_iface (dev));
801 _LOGI (LOGD_CORE, "startup complete");
803 priv->startup = FALSE;
804 g_object_notify (G_OBJECT (self), "startup");
806 /* We don't have to watch notify::has-pending-action any more. */
807 for (iter = priv->devices; iter; iter = iter->next) {
808 NMDevice *dev = iter->data;
810 g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
813 if (nm_config_get_configure_and_quit (nm_config_get ()))
814 g_signal_emit (self, signals[CONFIGURE_QUIT], 0);
818 device_has_pending_action_changed (NMDevice *device,
822 check_if_startup_complete (self);
826 settings_startup_complete_changed (NMSettings *settings,
830 check_if_startup_complete (self);
834 remove_device (NMManager *self,
837 gboolean allow_unmanage)
839 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
841 _LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)",
842 nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
844 if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
845 NMActRequest *req = nm_device_get_act_request (device);
846 gboolean unmanage = FALSE;
848 /* Leave activated interfaces up when quitting so their configuration
849 * can be taken over when NM restarts. This ensures connectivity while
850 * NM is stopped. Devices which do not support connection assumption
853 if (!quitting) /* Forced removal; device already gone */
855 else if (!nm_device_can_assume_active_connection (device))
862 nm_device_set_unmanaged_by_quitting (device);
864 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
865 } else if (quitting && nm_config_get_configure_and_quit (nm_config_get ())) {
866 nm_device_spawn_iface_helper (device);
870 g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
872 nm_settings_device_removed (priv->settings, device, quitting);
873 priv->devices = g_slist_remove (priv->devices, device);
875 if (nm_device_is_real (device)) {
876 g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
877 g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
878 nm_device_removed (device);
880 g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device);
881 g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
883 nm_exported_object_clear_and_unexport (&device);
885 check_if_startup_complete (self);
889 device_removed_cb (NMDevice *device, gpointer user_data)
891 remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
895 nm_manager_get_state (NMManager *manager)
897 g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
899 return NM_MANAGER_GET_PRIVATE (manager)->state;
902 /***************************/
905 find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
907 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
908 NMDeviceFactory *factory;
909 const char *parent_name = NULL;
910 NMSettingsConnection *parent_connection;
911 NMDevice *parent, *first_compatible = NULL;
914 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
916 if (!cached_factory) {
917 factory = nm_device_factory_manager_find_factory_for_connection (connection);
921 factory = cached_factory;
923 parent_name = nm_device_factory_get_connection_parent (factory, connection);
927 /* Try as an interface name of a parent device */
928 parent = find_device_by_iface (self, parent_name, NULL, NULL);
932 /* Maybe a hardware address */
933 parent = find_device_by_hw_addr (self, parent_name);
937 /* Maybe a connection UUID */
938 parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name);
939 if (!parent_connection)
942 /* Check if the parent connection is currently activated or is comaptible
943 * with some known device.
945 for (iter = priv->devices; iter; iter = iter->next) {
946 NMDevice *candidate = iter->data;
948 if (nm_device_get_settings_connection (candidate) == parent_connection)
951 if ( !first_compatible
952 && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
953 first_compatible = candidate;
956 return first_compatible;
960 * nm_manager_get_connection_iface:
961 * @self: the #NMManager
962 * @connection: the #NMConnection to get the interface for
963 * @out_parent: on success, the parent device if any
964 * @error: an error if determining the virtual interface name failed
966 * Given @connection, returns the interface name that the connection
967 * would need to use when activated. %NULL is returned if the name
968 * is not specified in connection or a the name for a virtual device
969 * could not be generated.
971 * Returns: the expected interface name (caller takes ownership), or %NULL
974 nm_manager_get_connection_iface (NMManager *self,
975 NMConnection *connection,
976 NMDevice **out_parent,
979 NMDeviceFactory *factory;
981 NMDevice *parent = NULL;
986 factory = nm_device_factory_manager_find_factory_for_connection (connection);
990 NM_MANAGER_ERROR_FAILED,
991 "NetworkManager plugin for '%s' unavailable",
992 nm_connection_get_connection_type (connection));
997 && !NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_iface) {
998 /* optimization. Shortcut lookup of the partent device. */
999 iface = g_strdup (nm_connection_get_interface_name (connection));
1003 NM_MANAGER_ERROR_FAILED,
1004 "failed to determine interface name: error determine name for %s",
1005 nm_connection_get_connection_type (connection));
1010 parent = find_parent_device_for_connection (self, connection, factory);
1011 iface = nm_device_factory_get_connection_iface (factory,
1013 parent ? nm_device_get_ip_iface (parent) : NULL,
1019 *out_parent = parent;
1024 * system_create_virtual_device:
1025 * @self: the #NMManager
1026 * @connection: the connection which might require a virtual device
1028 * If @connection requires a virtual device and one does not yet exist for it,
1029 * creates that device.
1031 * Returns: A #NMDevice that was just realized; %NULL if none
1034 system_create_virtual_device (NMManager *self, NMConnection *connection)
1036 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1037 NMDeviceFactory *factory;
1038 gs_free_slist GSList *connections = NULL;
1040 gs_free char *iface = NULL;
1041 NMDevice *device = NULL, *parent = NULL;
1042 GError *error = NULL;
1044 g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
1045 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
1047 iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
1049 _LOGD (LOGD_DEVICE, "(%s) can't get a name of a virtual device: %s",
1050 nm_connection_get_id (connection), error->message);
1051 g_error_free (error);
1055 /* See if there's a device that is already compatible with this connection */
1056 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1057 NMDevice *candidate = iter->data;
1059 if (nm_device_check_connection_compatible (candidate, connection)) {
1060 if (nm_device_is_real (candidate)) {
1061 _LOGD (LOGD_DEVICE, "(%s) already created virtual interface name %s",
1062 nm_connection_get_id (connection), iface);
1072 /* No matching device found. Proceed creating a new one. */
1074 factory = nm_device_factory_manager_find_factory_for_connection (connection);
1076 _LOGE (LOGD_DEVICE, "(%s:%s) NetworkManager plugin for '%s' unavailable",
1077 nm_connection_get_id (connection), iface,
1078 nm_connection_get_connection_type (connection));
1082 device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, &error);
1084 _LOGW (LOGD_DEVICE, "(%s) factory can't create the device: %s",
1085 nm_connection_get_id (connection), error->message);
1086 g_error_free (error);
1090 _LOGD (LOGD_DEVICE, "(%s) create virtual device %s",
1091 nm_connection_get_id (connection),
1092 nm_device_get_iface (device));
1094 if (!add_device (self, device, &error)) {
1095 _LOGW (LOGD_DEVICE, "(%s) can't register the device with manager: %s",
1096 nm_connection_get_id (connection), error->message);
1097 g_error_free (error);
1098 g_object_unref (device);
1102 /* Add device takes a reference that NMManager still owns, so it's
1103 * safe to unref here and still return @device.
1105 g_object_unref (device);
1108 /* Create backing resources if the device has any autoconnect connections */
1109 connections = nm_settings_get_connections (priv->settings);
1110 for (iter = connections; iter; iter = g_slist_next (iter)) {
1111 NMConnection *candidate = iter->data;
1112 NMSettingConnection *s_con;
1114 if (!nm_device_check_connection_compatible (device, candidate))
1117 s_con = nm_connection_get_setting_connection (candidate);
1119 if (!nm_setting_connection_get_autoconnect (s_con))
1122 /* Create any backing resources the device needs */
1123 if (!nm_device_create_and_realize (device, connection, parent, &error)) {
1124 _LOGW (LOGD_DEVICE, "(%s) couldn't create the device: %s",
1125 nm_connection_get_id (connection), error->message);
1126 g_error_free (error);
1127 remove_device (self, device, FALSE, TRUE);
1137 retry_connections_for_parent_device (NMManager *self, NMDevice *device)
1139 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1140 GSList *connections, *iter;
1142 g_return_if_fail (device);
1144 connections = nm_settings_get_connections (priv->settings);
1145 for (iter = connections; iter; iter = g_slist_next (iter)) {
1146 NMConnection *candidate = iter->data;
1147 gs_free_error GError *error = NULL;
1148 gs_free char *ifname = NULL;
1151 parent = find_parent_device_for_connection (self, candidate, NULL);
1152 if (parent == device) {
1153 /* Only try to activate devices that don't already exist */
1154 ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error);
1156 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
1157 connection_changed (priv->settings, candidate, self);
1162 g_slist_free (connections);
1166 connection_changed (NMSettings *settings,
1167 NMConnection *connection,
1172 if (!nm_connection_is_virtual (connection))
1175 device = system_create_virtual_device (manager, connection);
1179 /* Maybe the device that was created was needed by some other
1180 * connection's device (parent of a VLAN). Let the connections
1181 * can use the newly created device as a parent know. */
1182 retry_connections_for_parent_device (manager, device);
1186 connection_removed (NMSettings *settings,
1187 NMSettingsConnection *connection,
1191 * Do not delete existing virtual devices to keep connectivity up.
1192 * Virtual devices are reused when NetworkManager is restarted.
1197 system_unmanaged_devices_changed_cb (NMSettings *settings,
1201 NMManager *self = NM_MANAGER (user_data);
1202 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1203 const GSList *unmanaged_specs, *iter;
1205 unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
1206 for (iter = priv->devices; iter; iter = g_slist_next (iter))
1207 nm_device_set_unmanaged_by_user_config (NM_DEVICE (iter->data), unmanaged_specs);
1211 system_hostname_changed_cb (NMSettings *settings,
1215 NMManager *self = NM_MANAGER (user_data);
1216 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1219 hostname = nm_settings_get_hostname (priv->settings);
1221 /* nm_settings_get_hostname() does not return an empty hostname. */
1222 nm_assert (!hostname || *hostname);
1224 if (!hostname && !priv->hostname)
1226 if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) {
1231 /* realloc, to free possibly trailing data after NUL. */
1233 hostname = g_realloc (hostname, strlen (hostname) + 1);
1235 g_free (priv->hostname);
1236 priv->hostname = hostname;
1237 g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
1239 nm_dhcp_manager_set_default_hostname (nm_dhcp_manager_get (), priv->hostname);
1242 /*******************************************************************/
1243 /* General NMManager stuff */
1244 /*******************************************************************/
1246 /* Store value into key-file; supported types: boolean, int, string */
1248 write_value_to_state_file (const char *filename,
1258 gboolean ret = FALSE;
1260 g_return_val_if_fail (filename != NULL, FALSE);
1261 g_return_val_if_fail (group != NULL, FALSE);
1262 g_return_val_if_fail (key != NULL, FALSE);
1263 g_return_val_if_fail (value_type == G_TYPE_BOOLEAN ||
1264 value_type == G_TYPE_INT ||
1265 value_type == G_TYPE_STRING,
1268 key_file = g_key_file_new ();
1270 g_key_file_set_list_separator (key_file, ',');
1271 g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
1272 switch (value_type) {
1273 case G_TYPE_BOOLEAN:
1274 g_key_file_set_boolean (key_file, group, key, *((gboolean *) value));
1277 g_key_file_set_integer (key_file, group, key, *((gint *) value));
1280 g_key_file_set_string (key_file, group, key, *((const gchar **) value));
1284 data = g_key_file_to_data (key_file, &len, NULL);
1286 ret = g_file_set_contents (filename, data, len, error);
1289 g_key_file_free (key_file);
1295 radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
1299 enabled = rstate->user_enabled && rstate->hw_enabled;
1300 if (check_changeable)
1301 enabled &= rstate->sw_enabled;
1306 radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
1308 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1310 return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
1314 manager_update_radio_enabled (NMManager *self,
1318 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1321 /* Do nothing for radio types not yet implemented */
1325 g_object_notify (G_OBJECT (self), rstate->prop);
1327 /* Don't touch devices if asleep/networking disabled */
1328 if (manager_sleeping (self))
1331 /* enable/disable wireless devices as required */
1332 for (iter = priv->devices; iter; iter = iter->next) {
1333 NMDevice *device = NM_DEVICE (iter->data);
1335 if (nm_device_get_rfkill_type (device) == rstate->rtype) {
1336 _LOGD (LOGD_RFKILL, "(%s): setting radio %s",
1337 nm_device_get_iface (device),
1338 enabled ? "enabled" : "disabled");
1339 nm_device_set_enabled (device, enabled);
1345 update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate)
1347 switch (nm_rfkill_manager_get_rfkill_state (rfkill_mgr, rstate->rtype)) {
1348 case RFKILL_UNBLOCKED:
1349 rstate->sw_enabled = TRUE;
1350 rstate->hw_enabled = TRUE;
1352 case RFKILL_SOFT_BLOCKED:
1353 rstate->sw_enabled = FALSE;
1354 rstate->hw_enabled = TRUE;
1356 case RFKILL_HARD_BLOCKED:
1357 rstate->sw_enabled = FALSE;
1358 rstate->hw_enabled = FALSE;
1361 g_warn_if_reached ();
1367 manager_rfkill_update_one_type (NMManager *self,
1371 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1372 gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
1374 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
1375 old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1376 old_hwe = rstate->hw_enabled;
1378 /* recheck kernel rfkill state */
1379 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
1381 /* Print out all states affecting device enablement */
1383 _LOGD (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
1384 rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
1387 /* Log new killswitch state */
1388 new_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1389 if (old_rfkilled != new_rfkilled) {
1390 _LOGI (LOGD_RFKILL, "%s now %s by radio killswitch",
1392 new_rfkilled ? "enabled" : "disabled");
1395 /* Send out property changed signal for HW enabled */
1396 if (rstate->hw_enabled != old_hwe) {
1397 if (rstate->hw_prop)
1398 g_object_notify (G_OBJECT (self), rstate->hw_prop);
1401 /* And finally update the actual device radio state itself; respect the
1402 * daemon state here because this is never called from user-triggered
1403 * radio changes and we only want to ignore the daemon enabled state when
1404 * handling user radio change requests.
1406 new_enabled = radio_enabled_for_rstate (rstate, TRUE);
1407 if (new_enabled != old_enabled)
1408 manager_update_radio_enabled (self, rstate, new_enabled);
1412 nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
1414 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1417 if (rtype != RFKILL_TYPE_UNKNOWN)
1418 manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
1420 /* Otherwise sync all radio types */
1421 for (i = 0; i < RFKILL_TYPE_MAX; i++)
1422 manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
1427 device_auth_done_cb (NMAuthChain *chain,
1429 GDBusMethodInvocation *context,
1432 NMManager *self = NM_MANAGER (user_data);
1433 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1434 GError *error = NULL;
1435 NMAuthCallResult result;
1437 const char *permission;
1438 NMDeviceAuthRequestFunc callback;
1439 NMAuthSubject *subject;
1443 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
1445 permission = nm_auth_chain_get_data (chain, "requested-permission");
1446 g_assert (permission);
1447 callback = nm_auth_chain_get_data (chain, "callback");
1448 g_assert (callback);
1449 device = nm_auth_chain_get_data (chain, "device");
1452 result = nm_auth_chain_get_result (chain, permission);
1453 subject = nm_auth_chain_get_subject (chain);
1456 /* translate the auth error into a manager permission denied error */
1457 _LOGD (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
1458 error = g_error_new (NM_MANAGER_ERROR,
1459 NM_MANAGER_ERROR_PERMISSION_DENIED,
1460 "%s request failed: %s",
1461 permission, auth_error->message);
1462 } else if (result != NM_AUTH_CALL_RESULT_YES) {
1463 _LOGD (LOGD_CORE, "%s request failed: not authorized", permission);
1464 error = g_error_new (NM_MANAGER_ERROR,
1465 NM_MANAGER_ERROR_PERMISSION_DENIED,
1466 "%s request failed: not authorized",
1470 g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
1476 nm_auth_chain_get_data (chain, "user-data"));
1478 g_clear_error (&error);
1479 nm_auth_chain_unref (chain);
1483 device_auth_request_cb (NMDevice *device,
1484 GDBusMethodInvocation *context,
1485 NMConnection *connection,
1486 const char *permission,
1487 gboolean allow_interaction,
1488 NMDeviceAuthRequestFunc callback,
1492 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1493 GError *error = NULL;
1494 NMAuthSubject *subject = NULL;
1495 char *error_desc = NULL;
1498 /* Validate the caller */
1499 subject = nm_auth_subject_new_unix_process_from_context (context);
1501 error = g_error_new_literal (NM_MANAGER_ERROR,
1502 NM_MANAGER_ERROR_PERMISSION_DENIED,
1503 "Failed to get request UID.");
1507 /* Ensure the subject has permissions for this connection */
1508 if (connection && !nm_auth_is_subject_in_acl (connection,
1511 error = g_error_new_literal (NM_MANAGER_ERROR,
1512 NM_MANAGER_ERROR_PERMISSION_DENIED,
1514 g_free (error_desc);
1518 /* Validate the request */
1519 chain = nm_auth_chain_new_subject (subject, context, device_auth_done_cb, self);
1521 error = g_error_new_literal (NM_MANAGER_ERROR,
1522 NM_MANAGER_ERROR_PERMISSION_DENIED,
1523 "Unable to authenticate request.");
1527 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
1528 nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
1529 nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
1530 nm_auth_chain_set_data (chain, "callback", callback, NULL);
1531 nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
1532 nm_auth_chain_add_call (chain, permission, allow_interaction);
1536 callback (device, context, subject, error, user_data);
1538 g_clear_object (&subject);
1539 g_clear_error (&error);
1543 match_connection_filter (NMConnection *connection, gpointer user_data)
1545 if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
1548 return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
1552 * get_existing_connection:
1553 * @manager: #NMManager instance
1554 * @device: #NMDevice instance
1555 * @out_generated: (allow-none): return TRUE, if the connection was generated.
1557 * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
1558 * the device does not support assuming existing connections.
1560 static NMSettingsConnection *
1561 get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
1563 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1564 gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self);
1565 NMConnection *connection = NULL;
1566 NMSettingsConnection *matched;
1567 NMSettingsConnection *added = NULL;
1568 GError *error = NULL;
1569 NMDevice *master = NULL;
1570 int ifindex = nm_device_get_ifindex (device);
1573 *out_generated = FALSE;
1575 nm_device_capture_initial_config (device);
1578 int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex);
1580 if (master_ifindex) {
1581 master = nm_manager_get_device_by_ifindex (self, master_ifindex);
1583 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)",
1584 nm_device_get_iface (device), nm_platform_link_get_name (NM_PLATFORM_GET, master_ifindex), master_ifindex);
1587 if (!nm_device_get_act_request (master)) {
1588 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates",
1589 nm_device_get_iface (device), nm_device_get_iface (master));
1595 /* The core of the API is nm_device_generate_connection() function and
1596 * update_connection() virtual method and the convenient connection_type
1597 * class attribute. Subclasses supporting the new API must have
1598 * update_connection() implemented, otherwise nm_device_generate_connection()
1601 connection = nm_device_generate_connection (device, master);
1605 /* Now we need to compare the generated connection to each configured
1606 * connection. The comparison function is the heart of the connection
1607 * assumption implementation and it must compare the connections very
1608 * carefully to sort out various corner cases. Also, the comparison is
1609 * not entirely symmetric.
1611 * When no configured connection matches the generated connection, we keep
1612 * the generated connection instead.
1614 connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections));
1615 matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
1617 nm_device_has_carrier (device),
1618 nm_device_get_ip4_route_metric (device),
1619 nm_device_get_ip6_route_metric (device),
1620 match_connection_filter,
1623 _LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
1624 nm_device_get_iface (device),
1625 nm_settings_connection_get_id (matched));
1626 g_object_unref (connection);
1630 _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
1631 nm_device_get_iface (device),
1632 nm_connection_get_id (connection));
1634 added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
1636 nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
1637 NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
1638 NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
1641 *out_generated = TRUE;
1643 _LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
1644 nm_device_get_iface (device),
1645 nm_connection_get_id (connection),
1647 g_clear_error (&error);
1649 g_object_unref (connection);
1651 return added ? added : NULL;
1655 assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
1657 NMActiveConnection *active, *master_ac;
1658 NMAuthSubject *subject;
1659 GError *error = NULL;
1661 _LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
1662 nm_device_get_iface (device));
1664 /* Move device to DISCONNECTED to activate the connection */
1665 if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
1666 nm_device_state_changed (device,
1667 NM_DEVICE_STATE_DISCONNECTED,
1668 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1670 g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1672 subject = nm_auth_subject_new_internal ();
1673 active = _new_active_connection (self, NM_CONNECTION (connection), NULL, device, subject, &error);
1674 g_object_unref (subject);
1677 _LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
1678 nm_connection_get_path (NM_CONNECTION (connection)),
1680 g_error_free (error);
1684 /* If the device is a slave or VLAN, find the master ActiveConnection */
1686 if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
1687 nm_active_connection_set_master (active, master_ac);
1689 nm_active_connection_set_assumed (active, TRUE);
1690 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
1691 active_connection_add (self, active);
1692 nm_device_queue_activation (device, NM_ACT_REQUEST (active));
1693 g_object_unref (active);
1699 recheck_assume_connection (NMManager *self, NMDevice *device)
1701 NMSettingsConnection *connection;
1702 gboolean was_unmanaged = FALSE, success, generated = FALSE;
1703 NMDeviceState state;
1705 g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
1706 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1708 if (nm_device_get_is_nm_owned (device))
1711 if (!nm_device_get_managed (device, FALSE))
1714 state = nm_device_get_state (device);
1715 if (state > NM_DEVICE_STATE_DISCONNECTED)
1718 connection = get_existing_connection (self, device, &generated);
1720 _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
1721 nm_device_get_iface (device));
1725 if (state == NM_DEVICE_STATE_UNMANAGED) {
1726 was_unmanaged = TRUE;
1727 nm_device_state_changed (device,
1728 NM_DEVICE_STATE_UNAVAILABLE,
1729 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1732 success = assume_connection (self, device, connection);
1734 if (was_unmanaged) {
1735 nm_device_state_changed (device,
1736 NM_DEVICE_STATE_UNAVAILABLE,
1737 NM_DEVICE_STATE_REASON_CONFIG_FAILED);
1741 _LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
1742 nm_device_get_iface (device));
1744 nm_settings_connection_delete (connection, NULL, NULL);
1752 recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
1754 recheck_assume_connection (user_data, device);
1758 device_ip_iface_changed (NMDevice *device,
1762 const char *ip_iface = nm_device_get_ip_iface (device);
1765 /* Remove NMDevice objects that are actually child devices of others,
1766 * when the other device finally knows its IP interface name. For example,
1767 * remove the PPP interface that's a child of a WWAN device, since it's
1768 * not really a standalone NMDevice.
1770 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
1771 NMDevice *candidate = NM_DEVICE (iter->data);
1773 if ( candidate != device
1774 && g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
1775 && nm_device_is_real (candidate)) {
1776 remove_device (self, candidate, FALSE, FALSE);
1783 device_iface_changed (NMDevice *device,
1787 /* Virtual connections may refer to the new device name as
1788 * parent device, retry to activate them.
1790 retry_connections_for_parent_device (self, device);
1795 device_realized (NMDevice *device,
1799 /* Emit D-Bus signals */
1800 g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
1801 g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
1805 _device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
1807 g_return_if_fail (NM_IS_MANAGER (self));
1808 g_return_if_fail (NM_IS_DEVICE (device));
1810 nm_device_realize_finish (device, plink);
1812 if (!nm_device_get_managed (device, FALSE))
1815 if (recheck_assume_connection (self, device))
1818 /* if we failed to assume a connection for the managed device, but the device
1819 * is still unavailable. Set UNAVAILABLE state again, this time with NOW_MANAGED. */
1820 nm_device_state_changed (device,
1821 NM_DEVICE_STATE_UNAVAILABLE,
1822 NM_DEVICE_STATE_REASON_NOW_MANAGED);
1823 nm_device_emit_recheck_auto_activate (device);
1828 * @self: the #NMManager
1829 * @device: the #NMDevice to add
1830 * @error: (out): the #GError
1832 * If successful, this function will increase the references count of @device.
1833 * Callers should decrease the reference count.
1836 add_device (NMManager *self, NMDevice *device, GError **error)
1838 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1839 const char *iface, *type_desc;
1841 GSList *iter, *remove = NULL;
1843 const char *dbus_path;
1846 ifindex = nm_device_get_ifindex (device);
1847 if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) {
1848 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
1849 "A device with ifindex %d already exists", ifindex);
1853 /* Remove existing devices owned by the new device; eg remove ethernet
1854 * ports that are owned by a WWAN modem, since udev may announce them
1855 * before the modem is fully discovered.
1857 * FIXME: use parent/child device relationships instead of removing
1858 * the child NMDevice entirely
1860 for (iter = priv->devices; iter; iter = iter->next) {
1861 NMDevice *candidate = iter->data;
1863 iface = nm_device_get_ip_iface (candidate);
1864 if (nm_device_is_real (candidate) && nm_device_owns_iface (device, iface))
1865 remove = g_slist_prepend (remove, candidate);
1867 for (iter = remove; iter; iter = iter->next)
1868 remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
1869 g_slist_free (remove);
1871 priv->devices = g_slist_append (priv->devices, g_object_ref (device));
1873 g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
1874 G_CALLBACK (manager_device_state_changed),
1877 g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
1878 G_CALLBACK (device_auth_request_cb),
1881 g_signal_connect (device, NM_DEVICE_REMOVED,
1882 G_CALLBACK (device_removed_cb),
1885 g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
1886 G_CALLBACK (recheck_assume_connection_cb),
1889 g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
1890 G_CALLBACK (device_ip_iface_changed),
1893 g_signal_connect (device, "notify::" NM_DEVICE_IFACE,
1894 G_CALLBACK (device_iface_changed),
1897 g_signal_connect (device, "notify::" NM_DEVICE_REAL,
1898 G_CALLBACK (device_realized),
1901 if (priv->startup) {
1902 g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
1903 G_CALLBACK (device_has_pending_action_changed),
1907 /* Update global rfkill state for this device type with the device's
1908 * rfkill state, and then set this device's rfkill state based on the
1911 rtype = nm_device_get_rfkill_type (device);
1912 if (rtype != RFKILL_TYPE_UNKNOWN) {
1913 nm_manager_rfkill_update (self, rtype);
1914 nm_device_set_enabled (device, radio_enabled_for_type (self, rtype, TRUE));
1917 iface = nm_device_get_iface (device);
1919 type_desc = nm_device_get_type_desc (device);
1920 g_assert (type_desc);
1922 nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings));
1924 nm_device_set_unmanaged_flags (device,
1925 NM_UNMANAGED_SLEEPING,
1926 manager_sleeping (self));
1928 dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
1929 _LOGI (LOGD_DEVICE, "(%s): new %s device (%s)", iface, type_desc, dbus_path);
1931 nm_settings_device_added (priv->settings, device);
1932 g_signal_emit (self, signals[INTERNAL_DEVICE_ADDED], 0, device);
1933 g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
1935 for (iter = priv->devices; iter; iter = iter->next) {
1936 NMDevice *d = iter->data;
1939 nm_device_notify_new_device_added (d, device);
1942 /* Virtual connections may refer to the new device as
1943 * parent device, retry to activate them.
1945 retry_connections_for_parent_device (self, device);
1950 /*******************************************************************/
1953 factory_device_added_cb (NMDeviceFactory *factory,
1957 NMManager *self = user_data;
1958 GError *error = NULL;
1960 g_return_if_fail (NM_IS_MANAGER (self));
1962 if (nm_device_realize_start (device, NULL, NULL, &error)) {
1963 add_device (self, device, NULL);
1964 _device_realize_finish (self, device, NULL);
1966 _LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
1967 nm_device_get_iface (device), error->message);
1968 g_error_free (error);
1973 factory_component_added_cb (NMDeviceFactory *factory,
1979 g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE);
1981 for (iter = NM_MANAGER_GET_PRIVATE (user_data)->devices; iter; iter = iter->next) {
1982 if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
1989 _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
1991 NMManager *self = NM_MANAGER (user_data);
1993 g_signal_connect (factory,
1994 NM_DEVICE_FACTORY_DEVICE_ADDED,
1995 G_CALLBACK (factory_device_added_cb),
1997 g_signal_connect (factory,
1998 NM_DEVICE_FACTORY_COMPONENT_ADDED,
1999 G_CALLBACK (factory_component_added_cb),
2003 /*******************************************************************/
2006 platform_link_added (NMManager *self,
2008 const NMPlatformLink *plink)
2010 NMDeviceFactory *factory;
2011 NMDevice *device = NULL;
2012 GError *error = NULL;
2013 gboolean nm_plugin_missing = FALSE;
2016 g_return_if_fail (ifindex > 0);
2018 if (nm_manager_get_device_by_ifindex (self, ifindex))
2021 /* Let unrealized devices try to realize themselves with the link */
2022 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
2023 NMDevice *candidate = iter->data;
2024 gboolean compatible = TRUE;
2026 if (strcmp (nm_device_get_iface (candidate), plink->name))
2029 if (nm_device_is_real (candidate)) {
2030 /* Ignore the link added event since there's already a realized
2031 * device with the link's name.
2034 } else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
2036 _device_realize_finish (self, candidate, plink);
2040 _LOGD (LOGD_DEVICE, "(%s): failed to realize from plink: '%s'",
2041 plink->name, error->message);
2042 g_clear_error (&error);
2044 /* Try next unrealized device */
2047 /* Try registered device factories */
2048 factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
2050 gboolean ignore = FALSE;
2052 device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
2055 _LOGW (LOGD_HW, "%s: factory failed to create device: %s",
2056 plink->name, error->message);
2057 g_clear_error (&error);
2063 if (device == NULL) {
2064 switch (plink->type) {
2065 case NM_LINK_TYPE_WWAN_ETHERNET:
2066 case NM_LINK_TYPE_BNEP:
2067 case NM_LINK_TYPE_OLPC_MESH:
2068 case NM_LINK_TYPE_TEAM:
2069 case NM_LINK_TYPE_WIFI:
2070 _LOGI (LOGD_HW, "(%s): '%s' plugin not available; creating generic device",
2071 plink->name, nm_link_type_to_string (plink->type));
2072 nm_plugin_missing = TRUE;
2075 device = nm_device_generic_new (plink);
2081 if (nm_plugin_missing)
2082 nm_device_set_nm_plugin_missing (device, TRUE);
2083 if (nm_device_realize_start (device, plink, NULL, &error)) {
2084 add_device (self, device, NULL);
2085 _device_realize_finish (self, device, plink);
2087 _LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
2088 plink->name, error->message);
2089 g_clear_error (&error);
2091 g_object_unref (device);
2098 } PlatformLinkCbData;
2101 _platform_link_cb_idle (PlatformLinkCbData *data)
2103 NMManager *self = data->self;
2104 const NMPlatformLink *l;
2109 g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
2111 l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
2113 NMPlatformLink pllink;
2115 pllink = *l; /* make a copy of the link instance */
2116 platform_link_added (self, data->ifindex, &pllink);
2119 GError *error = NULL;
2121 device = nm_manager_get_device_by_ifindex (self, data->ifindex);
2123 if (nm_device_is_software (device)) {
2124 /* Our software devices stick around until their connection is removed */
2125 if (!nm_device_unrealize (device, FALSE, &error)) {
2126 _LOGW (LOGD_DEVICE, "(%s): failed to unrealize: %s",
2127 nm_device_get_iface (device),
2129 g_clear_error (&error);
2130 remove_device (self, device, FALSE, TRUE);
2133 /* Hardware and external devices always get removed when their kernel link is gone */
2134 remove_device (self, device, FALSE, TRUE);
2140 g_slice_free (PlatformLinkCbData, data);
2141 return G_SOURCE_REMOVE;
2145 platform_link_cb (NMPlatform *platform,
2146 NMPObjectType obj_type,
2148 NMPlatformLink *plink,
2149 NMPlatformSignalChangeType change_type,
2152 PlatformLinkCbData *data;
2154 switch (change_type) {
2155 case NM_PLATFORM_SIGNAL_ADDED:
2156 case NM_PLATFORM_SIGNAL_REMOVED:
2157 data = g_slice_new (PlatformLinkCbData);
2158 data->self = NM_MANAGER (user_data);
2159 data->ifindex = ifindex;
2160 g_object_add_weak_pointer (G_OBJECT (data->self), (gpointer *) &data->self);
2161 g_idle_add ((GSourceFunc) _platform_link_cb_idle, data);
2169 platform_query_devices (NMManager *self)
2171 GArray *links_array;
2172 NMPlatformLink *links;
2175 links_array = nm_platform_link_get_all (NM_PLATFORM_GET);
2176 links = (NMPlatformLink *) links_array->data;
2177 for (i = 0; i < links_array->len; i++)
2178 platform_link_added (self, links[i].ifindex, &links[i]);
2180 g_array_unref (links_array);
2184 rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
2186 RfKillState udev_state,
2189 nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
2193 nm_manager_get_devices (NMManager *manager)
2195 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2197 return NM_MANAGER_GET_PRIVATE (manager)->devices;
2201 nm_manager_get_connection_device (NMManager *self,
2202 NMConnection *connection)
2204 NMActiveConnection *ac = find_ac_for_connection (self, connection);
2208 return nm_active_connection_get_device (ac);
2212 nm_manager_get_best_device_for_connection (NMManager *self,
2213 NMConnection *connection,
2214 gboolean for_user_request)
2216 const GSList *devices, *iter;
2217 NMDevice *act_device = nm_manager_get_connection_device (self, connection);
2218 NMDeviceCheckConAvailableFlags flags;
2223 flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
2225 /* Pick the first device that's compatible with the connection. */
2226 devices = nm_manager_get_devices (self);
2227 for (iter = devices; iter; iter = g_slist_next (iter)) {
2228 NMDevice *device = NM_DEVICE (iter->data);
2230 if (nm_device_check_connection_available (device, connection, flags, NULL))
2239 _get_devices (NMManager *self,
2240 GDBusMethodInvocation *context,
2241 gboolean all_devices)
2243 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2244 gs_free const char **paths = NULL;
2248 paths = g_new (const char *, g_slist_length (priv->devices) + 1);
2250 for (i = 0, iter = priv->devices; iter; iter = iter->next) {
2253 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
2255 && (all_devices || nm_device_is_real (iter->data)))
2260 g_dbus_method_invocation_return_value (context,
2261 g_variant_new ("(^ao)", (char **) paths));
2265 impl_manager_get_devices (NMManager *self,
2266 GDBusMethodInvocation *context)
2268 _get_devices (self, context, FALSE);
2272 impl_manager_get_all_devices (NMManager *self,
2273 GDBusMethodInvocation *context)
2275 _get_devices (self, context, TRUE);
2279 impl_manager_get_device_by_ip_iface (NMManager *self,
2280 GDBusMethodInvocation *context,
2284 const char *path = NULL;
2286 device = find_device_by_ip_iface (self, iface);
2288 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
2291 g_dbus_method_invocation_return_error (context,
2293 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2294 "No device found for the requested iface.");
2296 g_dbus_method_invocation_return_value (context,
2297 g_variant_new ("(o)", path));
2302 is_compatible_with_slave (NMConnection *master, NMConnection *slave)
2304 NMSettingConnection *s_con;
2306 g_return_val_if_fail (master, FALSE);
2307 g_return_val_if_fail (slave, FALSE);
2309 s_con = nm_connection_get_setting_connection (slave);
2312 return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
2317 * @self: #NMManager object
2318 * @connection: the #NMConnection to find the master connection and device for
2319 * @device: the #NMDevice, if any, which will activate @connection
2320 * @out_master_connection: on success, the master connection of @connection if
2321 * that master connection was found
2322 * @out_master_device: on success, the master device of @connection if that
2323 * master device was found
2324 * @out_master_ac: on success, the master ActiveConnection of @connection if
2325 * there already is one
2326 * @error: the error, if an error occurred
2328 * Given an #NMConnection, attempts to find its master. If @connection has
2329 * no master, this will return %TRUE and @out_master_connection and
2330 * @out_master_device will be untouched.
2332 * If @connection does have a master, then the outputs depend on what is in its
2333 * #NMSettingConnection:master property:
2335 * If "master" is the ifname of an existing #NMDevice, and that device has a
2336 * compatible master connection activated or activating on it, then
2337 * @out_master_device, @out_master_connection, and @out_master_ac will all be
2338 * set. If the device exists and is idle, only @out_master_device will be set.
2339 * If the device exists and has an incompatible connection on it, an error
2342 * If "master" is the ifname of a non-existent device, then @out_master_device
2343 * will be %NULL, and @out_master_connection will be a connection whose
2344 * activation would cause the creation of that device. @out_master_ac MAY be
2345 * set in this case as well (if the connection has started activating, but has
2346 * not yet created its device).
2348 * If "master" is the UUID of a compatible master connection, then
2349 * @out_master_connection will be the identified connection, and @out_master_device
2350 * and/or @out_master_ac will be set if the connection is currently activating.
2351 * (@out_master_device will not be set if the device exists but does not have
2352 * @out_master_connection active/activating on it.)
2354 * Returns: %TRUE if the master device and/or connection could be found or if
2355 * the connection did not require a master, %FALSE otherwise
2358 find_master (NMManager *self,
2359 NMConnection *connection,
2361 NMSettingsConnection **out_master_connection,
2362 NMDevice **out_master_device,
2363 NMActiveConnection **out_master_ac,
2366 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2367 NMSettingConnection *s_con;
2369 NMDevice *master_device = NULL;
2370 NMSettingsConnection *master_connection = NULL;
2373 s_con = nm_connection_get_setting_connection (connection);
2375 master = nm_setting_connection_get_master (s_con);
2378 return TRUE; /* success, but no master */
2380 /* Try as an interface name first */
2381 master_device = find_device_by_iface (self, master, NULL, connection);
2382 if (master_device) {
2383 if (master_device == device) {
2384 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2385 "Device cannot be its own master");
2389 master_connection = nm_device_get_settings_connection (master_device);
2390 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) {
2391 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2392 "The active connection on %s is not a valid master for '%s'",
2393 nm_device_get_iface (master_device),
2394 nm_connection_get_id (connection));
2398 /* Try master as a connection UUID */
2399 master_connection = nm_settings_get_connection_by_uuid (priv->settings, master);
2400 if (master_connection) {
2401 /* Check if the master connection is activated on some device already */
2402 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2403 NMDevice *candidate = NM_DEVICE (iter->data);
2405 if (candidate == device)
2408 if (nm_device_get_settings_connection (candidate) == master_connection) {
2409 master_device = candidate;
2416 if (out_master_connection)
2417 *out_master_connection = master_connection;
2418 if (out_master_device)
2419 *out_master_device = master_device;
2420 if (out_master_ac && master_connection)
2421 *out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection));
2423 if (master_device || master_connection)
2426 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2427 "Master connection not found or invalid");
2433 * ensure_master_active_connection:
2434 * @self: the #NMManager
2435 * @subject: the #NMAuthSubject representing the requestor of this activation
2436 * @connection: the connection that should depend on @master_connection
2437 * @device: the #NMDevice, if any, which will activate @connection
2438 * @master_connection: the master connection, or %NULL
2439 * @master_device: the master device, or %NULL
2440 * @error: the error, if an error occurred
2442 * Determines whether a given #NMConnection depends on another connection to
2443 * be activated, and if so, finds that master connection or creates it.
2445 * If @master_device and @master_connection are both set then @master_connection
2446 * MUST already be activated or activating on @master_device, and the function will
2447 * return the existing #NMActiveConnection.
2449 * If only @master_device is set, and it has an #NMActiveConnection, then the
2450 * function will return it if it is a compatible master, or an error if not. If it
2451 * doesn't have an AC, then the function will create one if a compatible master
2452 * connection exists, or return an error if not.
2454 * If only @master_connection is set, then this will try to find or create a compatible
2455 * #NMDevice, and either activate @master_connection on that device or return an error.
2457 * Returns: the master #NMActiveConnection that the caller should depend on, or
2458 * %NULL if an error occurred
2460 static NMActiveConnection *
2461 ensure_master_active_connection (NMManager *self,
2462 NMAuthSubject *subject,
2463 NMConnection *connection,
2465 NMSettingsConnection *master_connection,
2466 NMDevice *master_device,
2469 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2470 NMActiveConnection *master_ac = NULL;
2471 NMDeviceState master_state;
2474 g_assert (connection);
2475 g_assert (master_connection || master_device);
2477 /* If the master device isn't activated then we need to activate it using
2478 * compatible connection. If it's already activating we can just proceed.
2480 if (master_device) {
2481 NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device);
2483 /* If we're passed a connection and a device, we require that connection
2484 * be already activated on the device, eg returned from find_master().
2486 g_assert (!master_connection || master_connection == device_connection);
2487 if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) {
2488 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2489 "The active connection on %s is not a valid master for '%s'",
2490 nm_device_get_iface (master_device),
2491 nm_connection_get_id (connection));
2495 master_state = nm_device_get_state (master_device);
2496 if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
2497 || nm_device_is_activating (master_device)) {
2498 /* Device already using master_connection */
2499 g_assert (device_connection);
2500 return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
2503 /* If the device is disconnected, find a compatible connection and
2504 * activate it on the device.
2506 if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
2507 GSList *connections;
2509 g_assert (master_connection == NULL);
2511 /* Find a compatible connection and activate this device using it */
2512 connections = nm_manager_get_activatable_connections (self);
2513 for (iter = connections; iter; iter = g_slist_next (iter)) {
2514 NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
2516 /* Ensure eg bond/team slave and the candidate master is a
2519 if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
2522 if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2523 master_ac = nm_manager_activate_connection (self,
2530 g_prefix_error (error, "%s", "Master device activation failed: ");
2531 g_slist_free (connections);
2535 g_slist_free (connections);
2539 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2540 "No compatible connection found for master device %s.",
2541 nm_device_get_iface (master_device));
2545 /* Otherwise, the device is unmanaged, unavailable, or disconnecting */
2548 NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2549 "Master device %s unmanaged or not available for activation",
2550 nm_device_get_iface (master_device));
2551 } else if (master_connection) {
2552 gboolean found_device = FALSE;
2554 /* Find a compatible device and activate it using this connection */
2555 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2556 NMDevice *candidate = NM_DEVICE (iter->data);
2558 if (candidate == device) {
2559 /* A device obviously can't be its own master */
2563 if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
2566 found_device = TRUE;
2567 if (!nm_device_is_software (candidate)) {
2568 master_state = nm_device_get_state (candidate);
2569 if (nm_device_is_real (candidate) && master_state != NM_DEVICE_STATE_DISCONNECTED)
2573 master_ac = nm_manager_activate_connection (self,
2580 g_prefix_error (error, "%s", "Master device activation failed: ");
2586 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2587 "No compatible disconnected device found for master connection %s.",
2588 nm_settings_connection_get_uuid (master_connection));
2590 g_assert_not_reached ();
2597 * @manager: #NMManager object
2598 * @connection: the master #NMSettingsConnection to find slave connections for
2599 * @device: the master #NMDevice for the @connection
2601 * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
2602 * master, or has not any slaves, this will return %NULL.
2604 * Returns: list of slave connections for given master @connection, or %NULL
2607 find_slaves (NMManager *manager,
2608 NMSettingsConnection *connection,
2611 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
2612 GSList *all_connections, *iter;
2613 GSList *slaves = NULL;
2614 NMSettingConnection *s_con;
2617 s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
2619 master = nm_setting_connection_get_master (s_con);
2622 return NULL; /* connection is not master */
2624 /* Search through all connections, not only inactive ones, because
2625 * even if a slave was already active, it might be deactivated during
2626 * master reactivation.
2628 all_connections = nm_settings_get_connections (priv->settings);
2629 for (iter = all_connections; iter; iter = iter->next) {
2630 NMSettingsConnection *master_connection = NULL;
2631 NMDevice *master_device = NULL;
2632 NMConnection *candidate = iter->data;
2634 find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL);
2635 if ( (master_connection && master_connection == connection)
2636 || (master_device && master_device == device)) {
2637 slaves = g_slist_prepend (slaves, candidate);
2640 g_slist_free (all_connections);
2642 return g_slist_reverse (slaves);
2646 should_connect_slaves (NMConnection *connection, NMDevice *device)
2648 NMSettingConnection *s_con;
2649 NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
2650 gs_free char *value = NULL;
2652 s_con = nm_connection_get_setting_connection (connection);
2655 /* Check autoconnect-slaves property */
2656 autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con);
2657 if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT)
2660 /* Check configuration default for autoconnect-slaves property */
2661 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
2662 "connection.autoconnect-slaves", device);
2664 autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
2667 if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
2669 if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
2675 autoconnect_slaves (NMManager *self,
2676 NMSettingsConnection *master_connection,
2677 NMDevice *master_device,
2678 NMAuthSubject *subject)
2680 GError *local_err = NULL;
2681 gboolean ret = FALSE;
2683 if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
2684 GSList *slaves, *iter;
2686 iter = slaves = find_slaves (self, master_connection, master_device);
2687 ret = slaves != NULL;
2690 NMSettingsConnection *slave_connection = iter->data;
2693 _LOGD (LOGD_CORE, "will activate slave connection '%s' (%s) as a dependency for master '%s' (%s)",
2694 nm_settings_connection_get_id (slave_connection),
2695 nm_settings_connection_get_uuid (slave_connection),
2696 nm_settings_connection_get_id (master_connection),
2697 nm_settings_connection_get_uuid (master_connection));
2699 /* Schedule slave activation */
2700 nm_manager_activate_connection (self,
2703 nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
2707 _LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
2708 g_error_free (local_err);
2711 g_slist_free (slaves);
2717 _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **error)
2721 g_assert (NM_IS_VPN_CONNECTION (active));
2723 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2724 success = nm_vpn_manager_activate_connection (NM_MANAGER_GET_PRIVATE (self)->vpn_manager,
2725 NM_VPN_CONNECTION (active),
2728 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2730 nm_exported_object_unexport (NM_EXPORTED_OBJECT (active));
2734 /* Traverse the device to disconnected state. This means that the device is ready
2735 * for connection and will proceed activating if there's an activation request
2739 unmanaged_to_disconnected (NMDevice *device)
2741 /* when creating the software device, it can happen that the device is
2742 * still unmanaged by NM_UNMANAGED_PLATFORM_INIT because we didn't yet
2743 * get the udev event. At this point, we can no longer delay the activation
2744 * and force the device to be managed. */
2745 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2747 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_USER_EXPLICIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2749 g_return_if_fail (nm_device_get_managed (device, FALSE));
2751 if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
2752 nm_device_state_changed (device,
2753 NM_DEVICE_STATE_UNAVAILABLE,
2754 NM_DEVICE_STATE_REASON_USER_REQUESTED);
2757 if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)
2758 && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
2759 nm_device_state_changed (device,
2760 NM_DEVICE_STATE_DISCONNECTED,
2761 NM_DEVICE_STATE_REASON_USER_REQUESTED);
2765 /* The parent connection is ready; we can proceed realizing the device and
2766 * progressing the device to disconencted state.
2769 active_connection_parent_active (NMActiveConnection *active,
2770 NMActiveConnection *parent_ac,
2773 NMDevice *device = nm_active_connection_get_device (active);
2774 GError *error = NULL;
2776 g_signal_handlers_disconnect_by_func (active,
2777 (GCallback) active_connection_parent_active,
2781 NMSettingsConnection *connection = nm_active_connection_get_settings_connection (active);
2782 NMDevice *parent = nm_active_connection_get_device (parent_ac);
2784 if (nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) {
2785 /* We can now proceed to disconnected state so that activation proceeds. */
2786 unmanaged_to_disconnected (device);
2788 nm_log_warn (LOGD_CORE, "Could not realize device '%s': %s",
2789 nm_device_get_iface (device), error->message);
2790 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
2793 nm_log_warn (LOGD_CORE, "The parent connection device '%s' depended on disappeared.",
2794 nm_device_get_iface (device));
2795 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
2800 _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
2802 NMDevice *device, *existing, *master_device = NULL;
2803 NMConnection *applied;
2804 NMSettingsConnection *connection;
2805 NMSettingsConnection *master_connection = NULL;
2806 NMConnection *existing_connection = NULL;
2807 NMActiveConnection *master_ac = NULL;
2808 NMAuthSubject *subject;
2809 char *error_desc = NULL;
2811 g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
2812 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
2813 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2815 g_assert (NM_IS_VPN_CONNECTION (active) == FALSE);
2817 connection = nm_active_connection_get_settings_connection (active);
2818 g_assert (connection);
2820 applied = nm_active_connection_get_applied_connection (active);
2822 device = nm_active_connection_get_device (active);
2823 g_return_val_if_fail (device != NULL, FALSE);
2825 /* If the device is active and its connection is not visible to the
2826 * user that's requesting this new activation, fail, since other users
2827 * should not be allowed to implicitly deactivate private connections
2828 * by activating a connection of their own.
2830 existing_connection = nm_device_get_applied_connection (device);
2831 subject = nm_active_connection_get_subject (active);
2832 if (existing_connection &&
2833 !nm_auth_is_subject_in_acl (existing_connection,
2838 NM_MANAGER_ERROR_PERMISSION_DENIED,
2839 "Private connection already active on the device: %s",
2841 g_free (error_desc);
2845 /* Final connection must be available on device */
2846 if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2847 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2848 "Connection '%s' is not available on the device %s at this time.",
2849 nm_settings_connection_get_id (connection), nm_device_get_iface (device));
2853 /* Create any backing resources the device needs */
2854 if (!nm_device_is_real (device)) {
2857 parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
2859 if (parent && !nm_device_is_real (parent)) {
2860 NMSettingsConnection *parent_con;
2861 NMActiveConnection *parent_ac;
2863 parent_con = nm_device_get_best_connection (parent, NULL, error);
2865 g_prefix_error (error, "%s failed to create parent: ", nm_device_get_iface (device));
2869 parent_ac = nm_manager_activate_connection (self, parent_con, NULL, parent, subject, error);
2871 g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
2875 /* We can't realize now; defer until the parent device is ready. */
2876 g_signal_connect (active,
2877 NM_ACTIVE_CONNECTION_PARENT_ACTIVE,
2878 (GCallback) active_connection_parent_active,
2880 nm_active_connection_set_parent (active, parent_ac);
2882 /* We can realize now; no need to wait for a parent device. */
2883 if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
2884 g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
2890 /* Try to find the master connection/device if the connection has a dependency */
2891 if (!find_master (self, applied, device,
2892 &master_connection, &master_device, &master_ac,
2896 /* Ensure there's a master active connection the new connection we're
2897 * activating can depend on.
2899 if (master_connection || master_device) {
2900 if (master_connection) {
2901 _LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
2902 nm_settings_connection_get_id (connection),
2903 nm_settings_connection_get_id (master_connection));
2905 if (master_device) {
2906 _LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'",
2907 nm_settings_connection_get_id (connection),
2908 nm_device_get_ip_iface (master_device));
2911 /* Ensure eg bond slave and the candidate master is a bond master */
2912 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) {
2913 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2914 "The master connection was not compatible");
2919 master_ac = ensure_master_active_connection (self,
2920 nm_active_connection_get_subject (active),
2933 nm_active_connection_set_master (active, master_ac);
2934 _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
2935 nm_settings_connection_get_id (connection),
2937 nm_exported_object_get_path (NM_EXPORTED_OBJECT (master_ac)) ?: "");
2940 /* Check slaves for master connection and possibly activate them */
2941 autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
2943 /* Disconnect the connection if connected or queued on another device */
2944 existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
2946 nm_device_steal_connection (existing, connection);
2948 /* If the device is there, we can ready it for the activation. */
2949 if (nm_device_is_real (device))
2950 unmanaged_to_disconnected (device);
2952 /* Export the new ActiveConnection to clients and start it on the device */
2953 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2954 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2955 nm_device_queue_activation (device, NM_ACT_REQUEST (active));
2960 _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError **error)
2962 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2963 gboolean success = FALSE;
2965 /* Ensure activation request is still valid, eg that its device hasn't gone
2966 * away or that some other dependency has not failed.
2968 if (nm_active_connection_get_state (active) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
2969 g_set_error_literal (error,
2971 NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2972 "Activation failed because dependencies failed.");
2976 if (NM_IS_VPN_CONNECTION (active))
2977 success = _internal_activate_vpn (self, active, error);
2979 success = _internal_activate_device (self, active, error);
2982 /* Force an update of the Manager's activating-connection property.
2983 * The device changes state before the AC gets exported, which causes
2984 * the manager's 'activating-connection' property to be NULL since the
2985 * AC only gets a D-Bus path when it's exported. So now that the AC
2986 * is exported, make sure the manager's activating-connection property
2989 active_connection_add (self, active);
2990 policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
2996 static NMActiveConnection *
2997 _new_vpn_active_connection (NMManager *self,
2998 NMSettingsConnection *settings_connection,
2999 const char *specific_object,
3000 NMAuthSubject *subject,
3003 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3004 NMActiveConnection *parent = NULL;
3005 NMDevice *device = NULL;
3007 g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
3009 if (specific_object) {
3010 /* Find the specific connection the client requested we use */
3011 parent = active_connection_get_by_path (self, specific_object);
3013 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3014 "Base connection for VPN connection not active.");
3018 parent = priv->primary_connection;
3021 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3022 "Could not find source connection.");
3026 device = nm_active_connection_get_device (parent);
3028 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3029 "Source connection had no active device.");
3033 return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
3035 nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)),
3039 static NMActiveConnection *
3040 _new_active_connection (NMManager *self,
3041 NMConnection *connection,
3042 const char *specific_object,
3044 NMAuthSubject *subject,
3047 NMSettingsConnection *settings_connection = NULL;
3048 NMActiveConnection *existing_ac;
3051 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
3052 g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
3054 /* Can't create new AC for already-active connection */
3055 existing_ac = find_ac_for_connection (self, connection);
3056 if (NM_IS_VPN_CONNECTION (existing_ac)) {
3057 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
3058 "Connection '%s' is already active",
3059 nm_connection_get_id (connection));
3063 /* Normalize the specific object */
3064 if (specific_object && g_strcmp0 (specific_object, "/") == 0)
3065 specific_object = NULL;
3067 is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME);
3069 if (NM_IS_SETTINGS_CONNECTION (connection))
3070 settings_connection = (NMSettingsConnection *) connection;
3073 return _new_vpn_active_connection (self,
3074 settings_connection,
3080 return (NMActiveConnection *) nm_act_request_new (settings_connection,
3087 _internal_activation_failed (NMManager *self,
3088 NMActiveConnection *active,
3089 const char *error_desc)
3091 _LOGD (LOGD_CORE, "Failed to activate '%s': %s",
3092 nm_active_connection_get_settings_connection_id (active),
3095 if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
3096 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
3097 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
3102 _internal_activation_auth_done (NMActiveConnection *active,
3104 const char *error_desc,
3105 gpointer user_data1,
3106 gpointer user_data2)
3108 NMManager *self = user_data1;
3109 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3110 GError *error = NULL;
3112 priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
3115 if (_internal_activate_generic (self, active, &error)) {
3116 g_object_unref (active);
3121 g_assert (error_desc || error);
3122 _internal_activation_failed (self, active, error_desc ? error_desc : error->message);
3123 g_object_unref (active);
3124 g_clear_error (&error);
3128 * nm_manager_activate_connection():
3129 * @self: the #NMManager
3130 * @connection: the #NMSettingsConnection to activate on @device
3131 * @specific_object: the specific object path, if any, for the activation
3132 * @device: the #NMDevice to activate @connection on
3133 * @subject: the subject which requested activation
3134 * @error: return location for an error
3136 * Begins a new internally-initiated activation of @connection on @device.
3137 * @subject should be the subject of the activation that triggered this
3138 * one, or if this is an autoconnect request, a new internal subject.
3139 * The returned #NMActiveConnection is owned by the Manager and should be
3140 * referenced by the caller if the caller continues to use it.
3142 * Returns: (transfer none): the new #NMActiveConnection that tracks
3143 * activation of @connection on @device
3145 NMActiveConnection *
3146 nm_manager_activate_connection (NMManager *self,
3147 NMSettingsConnection *connection,
3148 const char *specific_object,
3150 NMAuthSubject *subject,
3153 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3154 NMActiveConnection *active;
3155 char *error_desc = NULL;
3158 g_return_val_if_fail (self != NULL, NULL);
3159 g_return_val_if_fail (connection != NULL, NULL);
3160 g_return_val_if_fail (error != NULL, NULL);
3161 g_return_val_if_fail (*error == NULL, NULL);
3163 /* Ensure the subject has permissions for this connection */
3164 if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3167 g_set_error_literal (error,
3169 NM_MANAGER_ERROR_PERMISSION_DENIED,
3171 g_free (error_desc);
3175 /* Look for a active connection that's equivalent and is already pending authorization
3176 * and eventual activation. This is used to de-duplicate concurrent activations which would
3177 * otherwise race and cause the device to disconnect and reconnect repeatedly.
3178 * In particular, this allows the master and multiple slaves to concurrently auto-activate
3179 * while all the slaves would use the same active-connection. */
3180 for (iter = priv->authorizing_connections; iter; iter = g_slist_next (iter)) {
3181 active = iter->data;
3183 if ( connection == nm_active_connection_get_settings_connection (active)
3184 && g_strcmp0 (nm_active_connection_get_specific_object (active), specific_object) == 0
3185 && nm_active_connection_get_device (active) == device
3186 && nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
3187 && nm_auth_subject_is_internal (subject))
3191 active = _new_active_connection (self,
3192 NM_CONNECTION (connection),
3198 priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
3199 nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL);
3205 * validate_activation_request:
3206 * @self: the #NMManager
3207 * @context: the D-Bus context of the requestor
3208 * @connection: the partial or complete #NMConnection to be activated
3209 * @device_path: the object path of the device to be activated, or "/"
3210 * @out_device: on successful reutrn, the #NMDevice to be activated with @connection
3211 * @out_vpn: on successful return, %TRUE if @connection is a VPN connection
3212 * @error: location to store an error on failure
3214 * Performs basic validation on an activation request, including ensuring that
3215 * the requestor is a valid Unix process, is not disallowed in @connection
3216 * permissions, and that a device exists that can activate @connection.
3218 * Returns: on success, the #NMAuthSubject representing the requestor, or
3221 static NMAuthSubject *
3222 validate_activation_request (NMManager *self,
3223 GDBusMethodInvocation *context,
3224 NMConnection *connection,
3225 const char *device_path,
3226 NMDevice **out_device,
3230 NMDevice *device = NULL;
3231 gboolean vpn = FALSE;
3232 NMAuthSubject *subject = NULL;
3233 char *error_desc = NULL;
3235 g_assert (connection);
3236 g_assert (out_device);
3239 /* Validate the caller */
3240 subject = nm_auth_subject_new_unix_process_from_context (context);
3242 g_set_error_literal (error,
3244 NM_MANAGER_ERROR_PERMISSION_DENIED,
3245 "Failed to get request UID.");
3249 /* Ensure the subject has permissions for this connection */
3250 if (!nm_auth_is_subject_in_acl (connection,
3253 g_set_error_literal (error,
3255 NM_MANAGER_ERROR_PERMISSION_DENIED,
3257 g_free (error_desc);
3261 /* Not implemented yet, we want to fail early */
3262 if ( nm_connection_get_setting_connection (connection)
3263 && nm_connection_get_setting_ip6_config (connection)
3264 && !strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG),
3265 NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
3266 g_set_error_literal (error,
3268 NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
3269 "Sharing IPv6 connections is not supported yet.");
3273 /* Check whether it's a VPN or not */
3274 if ( nm_connection_get_setting_vpn (connection)
3275 || nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME))
3278 /* Normalize device path */
3279 if (device_path && g_strcmp0 (device_path, "/") == 0)
3282 /* And validate it */
3284 device = nm_manager_get_device_by_path (self, device_path);
3286 g_set_error_literal (error,
3288 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3289 "Device not found");
3293 device = nm_manager_get_best_device_for_connection (self, connection, TRUE);
3295 if (!device && !vpn) {
3296 gboolean is_software = nm_connection_is_virtual (connection);
3298 /* VPN and software-device connections don't need a device yet */
3300 g_set_error_literal (error,
3302 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3303 "No suitable device found for this connection.");
3310 /* Look for an existing device with the connection's interface name */
3311 iface = nm_manager_get_connection_iface (self, connection, NULL, error);
3315 device = find_device_by_iface (self, iface, connection, NULL);
3320 if ((!vpn || device_path) && !device) {
3321 g_set_error_literal (error,
3323 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3324 "Failed to find a compatible device for this connection");
3328 *out_device = device;
3333 g_object_unref (subject);
3337 /***********************************************************************/
3340 _activation_auth_done (NMActiveConnection *active,
3342 const char *error_desc,
3343 gpointer user_data1,
3344 gpointer user_data2)
3346 NMManager *self = user_data1;
3347 GDBusMethodInvocation *context = user_data2;
3348 GError *error = NULL;
3349 NMAuthSubject *subject;
3350 NMSettingsConnection *connection;
3352 subject = nm_active_connection_get_subject (active);
3353 connection = nm_active_connection_get_settings_connection (active);
3356 if (_internal_activate_generic (self, active, &error)) {
3357 g_dbus_method_invocation_return_value (context,
3358 g_variant_new ("(o)",
3359 nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3360 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE,
3362 g_object_unref (active);
3366 error = g_error_new_literal (NM_MANAGER_ERROR,
3367 NM_MANAGER_ERROR_PERMISSION_DENIED,
3372 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3373 subject, error->message);
3374 _internal_activation_failed (self, active, error->message);
3376 g_object_unref (active);
3377 g_dbus_method_invocation_take_error (context, error);
3381 impl_manager_activate_connection (NMManager *self,
3382 GDBusMethodInvocation *context,
3383 const char *connection_path,
3384 const char *device_path,
3385 const char *specific_object_path)
3387 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3388 NMActiveConnection *active = NULL;
3389 NMAuthSubject *subject = NULL;
3390 NMSettingsConnection *connection = NULL;
3391 NMDevice *device = NULL;
3392 gboolean is_vpn = FALSE;
3393 GError *error = NULL;
3395 /* Normalize object paths */
3396 if (g_strcmp0 (connection_path, "/") == 0)
3397 connection_path = NULL;
3398 if (g_strcmp0 (specific_object_path, "/") == 0)
3399 specific_object_path = NULL;
3400 if (g_strcmp0 (device_path, "/") == 0)
3403 /* If the connection path is given and valid, that connection is activated.
3404 * Otherwise the "best" connection for the device is chosen and activated,
3405 * regardless of whether that connection is autoconnect-enabled or not
3406 * (since this is an explicit request, not an auto-activation request).
3408 if (connection_path) {
3409 connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
3411 error = g_error_new_literal (NM_MANAGER_ERROR,
3412 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3413 "Connection could not be found.");
3417 /* If no connection is given, find a suitable connection for the given device path */
3419 error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3420 "Only devices may be activated without a specifying a connection");
3423 device = nm_manager_get_device_by_path (self, device_path);
3425 error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3426 "Cannot activate unknown device %s", device_path);
3430 connection = nm_device_get_best_connection (device, specific_object_path, &error);
3435 subject = validate_activation_request (self,
3437 NM_CONNECTION (connection),
3445 active = _new_active_connection (self,
3446 NM_CONNECTION (connection),
3447 specific_object_path,
3454 nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context);
3455 g_clear_object (&subject);
3460 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3461 subject, error->message);
3463 g_clear_object (&active);
3464 g_clear_object (&subject);
3467 g_dbus_method_invocation_take_error (context, error);
3470 /***********************************************************************/
3474 NMActiveConnection *active;
3475 } AddAndActivateInfo;
3478 activation_add_done (NMSettings *settings,
3479 NMSettingsConnection *new_connection,
3481 GDBusMethodInvocation *context,
3482 NMAuthSubject *subject,
3485 AddAndActivateInfo *info = user_data;
3487 gs_unref_object NMActiveConnection *active = NULL;
3488 GError *local = NULL;
3490 self = info->manager;
3491 active = info->active;
3492 g_slice_free (AddAndActivateInfo, info);
3495 nm_active_connection_set_settings_connection (active, new_connection);
3497 if (_internal_activate_generic (self, active, &local)) {
3498 nm_settings_connection_commit_changes (new_connection,
3499 NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
3501 g_dbus_method_invocation_return_value (
3503 g_variant_new ("(oo)",
3504 nm_connection_get_path (NM_CONNECTION (new_connection)),
3505 nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3506 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3507 nm_active_connection_get_settings_connection (active),
3509 nm_active_connection_get_subject (active),
3517 _internal_activation_failed (self, active, error->message);
3518 nm_settings_connection_delete (new_connection, NULL, NULL);
3519 g_dbus_method_invocation_return_gerror (context, error);
3520 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3523 nm_active_connection_get_subject (active),
3525 g_clear_error (&local);
3529 _add_and_activate_auth_done (NMActiveConnection *active,
3531 const char *error_desc,
3532 gpointer user_data1,
3533 gpointer user_data2)
3535 NMManager *self = user_data1;
3536 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3537 GDBusMethodInvocation *context = user_data2;
3538 AddAndActivateInfo *info;
3539 GError *error = NULL;
3542 NMConnection *connection;
3544 connection = g_object_steal_data (G_OBJECT (active),
3545 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE);
3547 info = g_slice_new (AddAndActivateInfo);
3548 info->manager = self;
3549 info->active = g_object_ref (active);
3551 /* Basic sender auth checks performed; try to add the connection */
3552 nm_settings_add_connection_dbus (priv->settings,
3556 activation_add_done,
3558 g_object_unref (connection);
3560 g_assert (error_desc);
3561 error = g_error_new_literal (NM_MANAGER_ERROR,
3562 NM_MANAGER_ERROR_PERMISSION_DENIED,
3564 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3567 nm_active_connection_get_subject (active),
3569 g_dbus_method_invocation_take_error (context, error);
3572 g_object_unref (active);
3576 impl_manager_add_and_activate_connection (NMManager *self,
3577 GDBusMethodInvocation *context,
3579 const char *device_path,
3580 const char *specific_object_path)
3582 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3583 NMConnection *connection = NULL;
3584 GSList *all_connections = NULL;
3585 NMActiveConnection *active = NULL;
3586 NMAuthSubject *subject = NULL;
3587 GError *error = NULL;
3588 NMDevice *device = NULL;
3589 gboolean vpn = FALSE;
3591 /* Normalize object paths */
3592 if (g_strcmp0 (specific_object_path, "/") == 0)
3593 specific_object_path = NULL;
3594 if (g_strcmp0 (device_path, "/") == 0)
3597 /* Try to create a new connection with the given settings.
3598 * We allow empty settings for AddAndActivateConnection(). In that case,
3599 * the connection will be completed in nm_utils_complete_generic() or
3600 * nm_device_complete_connection() below. Just make sure we don't expect
3601 * specific data being in the connection till then (especially in
3602 * validate_activation_request()).
3604 connection = nm_simple_connection_new ();
3605 if (settings && g_variant_n_children (settings))
3606 _nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL);
3608 subject = validate_activation_request (self,
3618 all_connections = nm_settings_get_connections (priv->settings);
3620 /* Try to fill the VPN's connection setting and name at least */
3621 if (!nm_connection_get_setting_vpn (connection)) {
3622 error = g_error_new_literal (NM_CONNECTION_ERROR,
3623 NM_CONNECTION_ERROR_MISSING_SETTING,
3624 "VPN connections require a 'vpn' setting");
3625 g_prefix_error (&error, "%s: ", NM_SETTING_VPN_SETTING_NAME);
3629 nm_utils_complete_generic (NM_PLATFORM_GET,
3631 NM_SETTING_VPN_SETTING_NAME,
3634 _("VPN connection"),
3636 FALSE); /* No IPv6 by default for now */
3638 /* Let each device subclass complete the connection */
3639 if (!nm_device_complete_connection (device,
3641 specific_object_path,
3646 g_slist_free (all_connections);
3647 all_connections = NULL;
3649 active = _new_active_connection (self,
3651 specific_object_path,
3658 g_object_set_data_full (G_OBJECT (active),
3659 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE,
3663 nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context);
3664 g_object_unref (subject);
3668 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, subject, error->message);
3669 g_clear_object (&connection);
3670 g_slist_free (all_connections);
3671 g_clear_object (&subject);
3672 g_clear_object (&active);
3675 g_dbus_method_invocation_take_error (context, error);
3678 /***********************************************************************/
3681 nm_manager_deactivate_connection (NMManager *manager,
3682 const char *connection_path,
3683 NMDeviceStateReason reason,
3686 NMActiveConnection *active;
3687 gboolean success = FALSE;
3689 active = active_connection_get_by_path (manager, connection_path);
3691 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3692 "The connection was not active.");
3696 if (NM_IS_VPN_CONNECTION (active)) {
3697 NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
3699 if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
3700 vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
3701 if (nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE))
3704 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3705 "The VPN connection was not active.");
3707 g_assert (NM_IS_ACT_REQUEST (active));
3708 nm_device_state_changed (nm_active_connection_get_device (active),
3709 NM_DEVICE_STATE_DEACTIVATING,
3715 g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
3721 deactivate_net_auth_done_cb (NMAuthChain *chain,
3723 GDBusMethodInvocation *context,
3726 NMManager *self = NM_MANAGER (user_data);
3727 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3728 GError *error = NULL;
3729 NMAuthCallResult result;
3730 NMActiveConnection *active;
3735 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3737 path = nm_auth_chain_get_data (chain, "path");
3738 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3741 _LOGD (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
3742 error = g_error_new (NM_MANAGER_ERROR,
3743 NM_MANAGER_ERROR_PERMISSION_DENIED,
3744 "Deactivate request failed: %s",
3745 auth_error->message);
3746 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3747 error = g_error_new_literal (NM_MANAGER_ERROR,
3748 NM_MANAGER_ERROR_PERMISSION_DENIED,
3749 "Not authorized to deactivate connections");
3751 /* success; deactivation allowed */
3752 if (!nm_manager_deactivate_connection (self,
3754 NM_DEVICE_STATE_REASON_USER_REQUESTED,
3759 active = active_connection_get_by_path (self, path);
3761 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
3762 nm_active_connection_get_settings_connection (active),
3764 nm_auth_chain_get_subject (chain),
3765 error ? error->message : NULL);
3769 g_dbus_method_invocation_take_error (context, error);
3771 g_dbus_method_invocation_return_value (context, NULL);
3773 nm_auth_chain_unref (chain);
3777 impl_manager_deactivate_connection (NMManager *self,
3778 GDBusMethodInvocation *context,
3779 const char *active_path)
3781 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3782 NMActiveConnection *ac;
3783 NMSettingsConnection *connection = NULL;
3784 GError *error = NULL;
3785 NMAuthSubject *subject = NULL;
3787 char *error_desc = NULL;
3789 /* Find the connection by its object path */
3790 ac = active_connection_get_by_path (self, active_path);
3792 connection = nm_active_connection_get_settings_connection (ac);
3795 error = g_error_new_literal (NM_MANAGER_ERROR,
3796 NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3797 "The connection was not active.");
3801 /* Validate the caller */
3802 subject = nm_auth_subject_new_unix_process_from_context (context);
3804 error = g_error_new_literal (NM_MANAGER_ERROR,
3805 NM_MANAGER_ERROR_PERMISSION_DENIED,
3806 "Failed to get request UID.");
3810 /* Ensure the subject has permissions for this connection */
3811 if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3814 error = g_error_new_literal (NM_MANAGER_ERROR,
3815 NM_MANAGER_ERROR_PERMISSION_DENIED,
3817 g_free (error_desc);
3821 /* Validate the user request */
3822 chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self);
3824 error = g_error_new_literal (NM_MANAGER_ERROR,
3825 NM_MANAGER_ERROR_PERMISSION_DENIED,
3826 "Unable to authenticate request.");
3830 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3831 nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
3832 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
3837 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE,
3838 subject, error->message);
3840 g_dbus_method_invocation_take_error (context, error);
3842 g_clear_object (&subject);
3846 device_is_wake_on_lan (NMDevice *device)
3848 return nm_platform_link_get_wake_on_lan (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device));
3852 do_sleep_wake (NMManager *self, gboolean sleeping_changed)
3854 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3855 gboolean suspending, waking_from_suspend;
3858 suspending = sleeping_changed && priv->sleeping;
3859 waking_from_suspend = sleeping_changed && !priv->sleeping;
3861 if (manager_sleeping (self)) {
3862 _LOGI (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling");
3864 /* FIXME: are there still hardware devices that need to be disabled around
3867 for (iter = priv->devices; iter; iter = iter->next) {
3868 NMDevice *device = iter->data;
3870 /* FIXME: shouldn't we be unmanaging software devices if !suspending? */
3871 if (nm_device_is_software (device))
3873 /* Wake-on-LAN devices will be taken down post-suspend rather than pre- */
3874 if (suspending && device_is_wake_on_lan (device))
3877 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3880 _LOGI (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling");
3882 if (waking_from_suspend) {
3883 /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this
3884 * but for now it's the only way to make sure we re-check their connectivity.
3886 for (iter = priv->devices; iter; iter = iter->next) {
3887 NMDevice *device = iter->data;
3889 if (nm_device_is_software (device))
3891 if (device_is_wake_on_lan (device))
3892 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3896 /* Ensure rfkill state is up-to-date since we don't respond to state
3897 * changes during sleep.
3899 nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
3901 /* Re-manage managed devices */
3902 for (iter = priv->devices; iter; iter = iter->next) {
3903 NMDevice *device = NM_DEVICE (iter->data);
3906 if (nm_device_is_software (device))
3909 /* enable/disable wireless devices since that we don't respond
3910 * to killswitch changes during sleep.
3912 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
3913 RadioState *rstate = &priv->radio_states[i];
3914 gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
3917 _LOGD (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)",
3918 enabled ? "enabling" : "disabling",
3919 rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled);
3922 if (nm_device_get_rfkill_type (device) == rstate->rtype)
3923 nm_device_set_enabled (device, enabled);
3926 nm_device_set_autoconnect (device, TRUE);
3928 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
3932 nm_manager_update_state (self);
3936 _internal_sleep (NMManager *self, gboolean do_sleep)
3938 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3940 if (priv->sleeping == do_sleep)
3943 _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
3944 do_sleep ? "sleep" : "wake",
3945 priv->sleeping ? "yes" : "no",
3946 priv->net_enabled ? "yes" : "no");
3948 priv->sleeping = do_sleep;
3950 do_sleep_wake (self, TRUE);
3952 g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
3957 sleep_auth_done_cb (NMAuthChain *chain,
3959 GDBusMethodInvocation *context,
3962 NMManager *self = NM_MANAGER (user_data);
3963 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3965 NMAuthCallResult result;
3968 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3970 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
3972 _LOGD (LOGD_SUSPEND, "Sleep/wake request failed: %s", error->message);
3973 ret_error = g_error_new (NM_MANAGER_ERROR,
3974 NM_MANAGER_ERROR_PERMISSION_DENIED,
3975 "Sleep/wake request failed: %s",
3977 g_dbus_method_invocation_take_error (context, ret_error);
3978 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3979 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
3980 NM_MANAGER_ERROR_PERMISSION_DENIED,
3981 "Not authorized to sleep/wake");
3982 g_dbus_method_invocation_take_error (context, ret_error);
3985 do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
3986 _internal_sleep (self, do_sleep);
3987 g_dbus_method_invocation_return_value (context, NULL);
3990 nm_auth_chain_unref (chain);
3995 impl_manager_sleep (NMManager *self,
3996 GDBusMethodInvocation *context,
3999 NMManagerPrivate *priv;
4000 GError *error = NULL;
4001 gs_unref_object NMAuthSubject *subject = NULL;
4004 const char *error_desc = NULL;
4007 g_return_if_fail (NM_IS_MANAGER (self));
4009 priv = NM_MANAGER_GET_PRIVATE (self);
4010 subject = nm_auth_subject_new_unix_process_from_context (context);
4012 if (priv->sleeping == do_sleep) {
4013 error = g_error_new (NM_MANAGER_ERROR,
4014 NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
4015 "Already %s", do_sleep ? "asleep" : "awake");
4016 nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", FALSE, subject,
4018 g_dbus_method_invocation_take_error (context, error);
4022 /* Unconditionally allow the request. Previously it was polkit protected
4023 * but unfortunately that doesn't work for short-lived processes like
4024 * pm-utils. It uses dbus-send without --print-reply, which quits
4025 * immediately after sending the request, and NM is unable to obtain the
4026 * sender's UID as dbus-send has already dropped off the bus. Thus NM
4027 * fails the request. Instead, don't validate the request, but rely on
4028 * D-Bus permissions to restrict the call to root.
4030 _internal_sleep (self, do_sleep);
4031 nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", TRUE, subject, NULL);
4032 g_dbus_method_invocation_return_value (context, NULL);
4036 chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
4038 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4039 nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
4040 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
4042 error = g_error_new_literal (NM_MANAGER_ERROR,
4043 NM_MANAGER_ERROR_PERMISSION_DENIED,
4045 g_dbus_method_invocation_take_error (context, error);
4051 sleeping_cb (NMSleepMonitor *monitor, gpointer user_data)
4053 nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
4054 _internal_sleep (NM_MANAGER (user_data), TRUE);
4058 resuming_cb (NMSleepMonitor *monitor, gpointer user_data)
4060 nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
4061 _internal_sleep (NM_MANAGER (user_data), FALSE);
4065 _internal_enable (NMManager *self, gboolean enable)
4067 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4070 /* Update "NetworkingEnabled" key in state file */
4071 if (priv->state_file) {
4072 if (!write_value_to_state_file (priv->state_file,
4073 "main", "NetworkingEnabled",
4074 G_TYPE_BOOLEAN, (gpointer) &enable,
4076 /* Not a hard error */
4077 _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s",
4083 _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
4084 enable ? "enable" : "disable",
4085 priv->sleeping ? "yes" : "no",
4086 priv->net_enabled ? "yes" : "no");
4088 priv->net_enabled = enable;
4090 do_sleep_wake (self, FALSE);
4092 g_object_notify (G_OBJECT (self), NM_MANAGER_NETWORKING_ENABLED);
4096 enable_net_done_cb (NMAuthChain *chain,
4098 GDBusMethodInvocation *context,
4101 NMManager *self = NM_MANAGER (user_data);
4102 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4103 GError *ret_error = NULL;
4104 NMAuthCallResult result;
4106 NMAuthSubject *subject;
4110 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4111 enable = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enable"));
4112 subject = nm_auth_chain_get_subject (chain);
4114 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4116 _LOGD (LOGD_CORE, "Enable request failed: %s", error->message);
4117 ret_error = g_error_new (NM_MANAGER_ERROR,
4118 NM_MANAGER_ERROR_PERMISSION_DENIED,
4119 "Enable request failed: %s",
4121 } else if (result != NM_AUTH_CALL_RESULT_YES) {
4122 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
4123 NM_MANAGER_ERROR_PERMISSION_DENIED,
4124 "Not authorized to enable/disable networking");
4127 _internal_enable (self, enable);
4128 g_dbus_method_invocation_return_value (context, NULL);
4129 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", TRUE,
4134 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", FALSE,
4135 subject, ret_error->message);
4136 g_dbus_method_invocation_take_error (context, ret_error);
4139 nm_auth_chain_unref (chain);
4143 impl_manager_enable (NMManager *self,
4144 GDBusMethodInvocation *context,
4147 NMManagerPrivate *priv;
4149 GError *error = NULL;
4151 g_return_if_fail (NM_IS_MANAGER (self));
4153 priv = NM_MANAGER_GET_PRIVATE (self);
4155 if (priv->net_enabled == enable) {
4156 error = g_error_new (NM_MANAGER_ERROR,
4157 NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
4158 "Already %s", enable ? "enabled" : "disabled");
4162 chain = nm_auth_chain_new_context (context, enable_net_done_cb, self);
4164 error = g_error_new_literal (NM_MANAGER_ERROR,
4165 NM_MANAGER_ERROR_PERMISSION_DENIED,
4166 "Unable to authenticate request.");
4170 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4171 nm_auth_chain_set_data (chain, "enable", GUINT_TO_POINTER (enable), NULL);
4172 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, TRUE);
4176 g_dbus_method_invocation_take_error (context, error);
4182 get_perm_add_result (NMAuthChain *chain, GVariantBuilder *results, const char *permission)
4184 NMAuthCallResult result;
4186 result = nm_auth_chain_get_result (chain, permission);
4187 if (result == NM_AUTH_CALL_RESULT_YES)
4188 g_variant_builder_add (results, "{ss}", permission, "yes");
4189 else if (result == NM_AUTH_CALL_RESULT_NO)
4190 g_variant_builder_add (results, "{ss}", permission, "no");
4191 else if (result == NM_AUTH_CALL_RESULT_AUTH)
4192 g_variant_builder_add (results, "{ss}", permission, "auth");
4194 nm_log_dbg (LOGD_CORE, "unknown auth chain result %d", result);
4199 get_permissions_done_cb (NMAuthChain *chain,
4201 GDBusMethodInvocation *context,
4204 NMManager *self = NM_MANAGER (user_data);
4205 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4207 GVariantBuilder results;
4211 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4213 _LOGD (LOGD_CORE, "Permissions request failed: %s", error->message);
4214 ret_error = g_error_new (NM_MANAGER_ERROR,
4215 NM_MANAGER_ERROR_PERMISSION_DENIED,
4216 "Permissions request failed: %s",
4218 g_dbus_method_invocation_take_error (context, ret_error);
4220 g_variant_builder_init (&results, G_VARIANT_TYPE ("a{ss}"));
4222 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4223 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SLEEP_WAKE);
4224 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
4225 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
4226 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
4227 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4228 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
4229 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
4230 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
4231 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
4232 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
4234 g_dbus_method_invocation_return_value (context,
4235 g_variant_new ("(a{ss})", &results));
4238 nm_auth_chain_unref (chain);
4242 impl_manager_get_permissions (NMManager *self,
4243 GDBusMethodInvocation *context)
4245 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4247 GError *error = NULL;
4249 chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self);
4251 error = g_error_new_literal (NM_MANAGER_ERROR,
4252 NM_MANAGER_ERROR_PERMISSION_DENIED,
4253 "Unable to authenticate request.");
4254 g_dbus_method_invocation_take_error (context, error);
4258 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4259 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
4260 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
4261 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
4262 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
4263 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
4264 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
4265 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
4266 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
4267 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
4268 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
4269 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
4273 impl_manager_get_state (NMManager *self,
4274 GDBusMethodInvocation *context)
4276 nm_manager_update_state (self);
4277 g_dbus_method_invocation_return_value (context,
4278 g_variant_new ("(u)", NM_MANAGER_GET_PRIVATE (self)->state));
4282 impl_manager_set_logging (NMManager *self,
4283 GDBusMethodInvocation *context,
4285 const char *domains)
4287 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4288 GError *error = NULL;
4289 gulong caller_uid = G_MAXULONG;
4291 if (!nm_bus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) {
4292 error = g_error_new_literal (NM_MANAGER_ERROR,
4293 NM_MANAGER_ERROR_PERMISSION_DENIED,
4294 "Failed to get request UID.");
4298 if (0 != caller_uid) {
4299 error = g_error_new_literal (NM_MANAGER_ERROR,
4300 NM_MANAGER_ERROR_PERMISSION_DENIED,
4301 "Permission denied");
4305 if (nm_logging_setup (level, domains, NULL, &error)) {
4306 _LOGI (LOGD_CORE, "logging: level '%s' domains '%s'",
4307 nm_logging_level_to_string (), nm_logging_domains_to_string ());
4312 g_dbus_method_invocation_take_error (context, error);
4314 g_dbus_method_invocation_return_value (context, NULL);
4318 impl_manager_get_logging (NMManager *manager,
4319 GDBusMethodInvocation *context)
4321 g_dbus_method_invocation_return_value (context,
4322 g_variant_new ("(ss)",
4323 nm_logging_level_to_string (),
4324 nm_logging_domains_to_string ()));
4328 connectivity_check_done (GObject *object,
4329 GAsyncResult *result,
4332 GDBusMethodInvocation *context = user_data;
4333 NMConnectivityState state;
4334 GError *error = NULL;
4336 state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
4338 g_dbus_method_invocation_take_error (context, error);
4340 g_dbus_method_invocation_return_value (context,
4341 g_variant_new ("(u)", state));
4347 check_connectivity_auth_done_cb (NMAuthChain *chain,
4349 GDBusMethodInvocation *context,
4352 NMManager *self = NM_MANAGER (user_data);
4353 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4354 GError *error = NULL;
4355 NMAuthCallResult result;
4357 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4359 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4362 _LOGD (LOGD_CORE, "CheckConnectivity request failed: %s", auth_error->message);
4363 error = g_error_new (NM_MANAGER_ERROR,
4364 NM_MANAGER_ERROR_PERMISSION_DENIED,
4365 "Connectivity check request failed: %s",
4366 auth_error->message);
4367 } else if (result != NM_AUTH_CALL_RESULT_YES) {
4368 error = g_error_new_literal (NM_MANAGER_ERROR,
4369 NM_MANAGER_ERROR_PERMISSION_DENIED,
4370 "Not authorized to recheck connectivity");
4373 nm_connectivity_check_async (priv->connectivity,
4374 connectivity_check_done,
4379 g_dbus_method_invocation_take_error (context, error);
4380 nm_auth_chain_unref (chain);
4384 impl_manager_check_connectivity (NMManager *self,
4385 GDBusMethodInvocation *context)
4387 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4389 GError *error = NULL;
4391 /* Validate the request */
4392 chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self);
4394 error = g_error_new_literal (NM_MANAGER_ERROR,
4395 NM_MANAGER_ERROR_PERMISSION_DENIED,
4396 "Unable to authenticate request.");
4397 g_dbus_method_invocation_take_error (context, error);
4401 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4402 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
4406 start_factory (NMDeviceFactory *factory, gpointer user_data)
4408 nm_device_factory_start (factory);
4412 nm_manager_start (NMManager *self, GError **error)
4414 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4415 GSList *iter, *connections;
4418 if (!nm_settings_start (priv->settings, error))
4421 g_signal_connect (NM_PLATFORM_GET,
4422 NM_PLATFORM_SIGNAL_LINK_CHANGED,
4423 G_CALLBACK (platform_link_cb),
4426 /* Set initial radio enabled/disabled state */
4427 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
4428 RadioState *rstate = &priv->radio_states[i];
4434 /* recheck kernel rfkill state */
4435 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
4438 _LOGI (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
4440 (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
4441 rstate->user_enabled ? "enabled" : "disabled");
4443 enabled = radio_enabled_for_rstate (rstate, TRUE);
4444 manager_update_radio_enabled (self, rstate, enabled);
4447 /* Log overall networking status - enabled/disabled */
4448 _LOGI (LOGD_CORE, "Networking is %s by state file",
4449 priv->net_enabled ? "enabled" : "disabled");
4451 system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
4452 system_hostname_changed_cb (priv->settings, NULL, self);
4454 /* Start device factories */
4455 nm_device_factory_manager_load_factories (_register_device_factory, self);
4456 nm_device_factory_manager_for_each_factory (start_factory, NULL);
4458 platform_query_devices (self);
4460 /* Load VPN plugins */
4461 priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
4463 /* Connections added before the manager is started do not emit
4464 * connection-added signals thus devices have to be created manually.
4466 _LOGD (LOGD_CORE, "creating virtual devices...");
4467 connections = nm_settings_get_connections (priv->settings);
4468 for (iter = connections; iter; iter = iter->next)
4469 connection_changed (priv->settings, NM_CONNECTION (iter->data), self);
4470 g_slist_free (connections);
4472 priv->devices_inited = TRUE;
4474 check_if_startup_complete (self);
4480 nm_manager_stop (NMManager *self)
4482 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4484 /* Remove all devices */
4485 while (priv->devices)
4486 remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
4488 _active_connection_cleanup (self);
4492 handle_firmware_changed (gpointer user_data)
4494 NMManager *self = NM_MANAGER (user_data);
4495 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4498 priv->fw_changed_id = 0;
4500 /* Try to re-enable devices with missing firmware */
4501 for (iter = priv->devices; iter; iter = iter->next) {
4502 NMDevice *candidate = NM_DEVICE (iter->data);
4503 NMDeviceState state = nm_device_get_state (candidate);
4505 if ( nm_device_get_firmware_missing (candidate)
4506 && (state == NM_DEVICE_STATE_UNAVAILABLE)) {
4507 _LOGI (LOGD_CORE, "(%s): firmware may now be available",
4508 nm_device_get_iface (candidate));
4510 /* Re-set unavailable state to try bringing the device up again */
4511 nm_device_state_changed (candidate,
4512 NM_DEVICE_STATE_UNAVAILABLE,
4513 NM_DEVICE_STATE_REASON_NONE);
4521 connectivity_changed (NMConnectivity *connectivity,
4525 NMManager *self = NM_MANAGER (user_data);
4527 _LOGD (LOGD_CORE, "connectivity checking indicates %s",
4528 nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
4530 nm_manager_update_state (self);
4531 g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
4535 firmware_dir_changed (GFileMonitor *monitor,
4538 GFileMonitorEvent event_type,
4541 NMManager *self = NM_MANAGER (user_data);
4542 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4544 switch (event_type) {
4545 case G_FILE_MONITOR_EVENT_CREATED:
4546 case G_FILE_MONITOR_EVENT_CHANGED:
4547 case G_FILE_MONITOR_EVENT_MOVED:
4548 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
4549 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
4550 if (!priv->fw_changed_id) {
4551 priv->fw_changed_id = g_timeout_add_seconds (4, handle_firmware_changed, self);
4552 _LOGI (LOGD_CORE, "kernel firmware directory '%s' changed",
4553 KERNEL_FIRMWARE_DIR);
4562 connection_metered_changed (GObject *object,
4566 nm_manager_update_metered (NM_MANAGER (user_data));
4570 policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4572 NMManager *self = NM_MANAGER (user_data);
4573 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4575 NMActiveConnection *ac;
4577 /* Note: this assumes that it's not possible for the IP4 default
4578 * route to be going over the default-ip6-device. If that changes,
4579 * we need something more complicated here.
4581 best = nm_policy_get_default_ip4_device (priv->policy);
4583 best = nm_policy_get_default_ip6_device (priv->policy);
4586 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
4590 if (ac != priv->primary_connection) {
4591 if (priv->primary_connection) {
4592 g_signal_handlers_disconnect_by_func (priv->primary_connection,
4593 G_CALLBACK (connection_metered_changed),
4595 g_clear_object (&priv->primary_connection);
4598 priv->primary_connection = ac ? g_object_ref (ac) : NULL;
4600 if (priv->primary_connection) {
4601 g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
4602 G_CALLBACK (connection_metered_changed), self);
4604 _LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4605 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
4606 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE);
4607 nm_manager_update_metered (self);
4612 policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4614 NMManager *self = NM_MANAGER (user_data);
4615 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4616 NMDevice *activating, *best;
4617 NMActiveConnection *ac;
4619 /* We only look at activating-ip6-device if activating-ip4-device
4620 * AND default-ip4-device are NULL; if default-ip4-device is
4621 * non-NULL, then activating-ip6-device is irrelevant, since while
4622 * that device might become the new default-ip6-device, it can't
4623 * become primary-connection while default-ip4-device is set to
4626 activating = nm_policy_get_activating_ip4_device (priv->policy);
4627 best = nm_policy_get_default_ip4_device (priv->policy);
4628 if (!activating && !best)
4629 activating = nm_policy_get_activating_ip6_device (priv->policy);
4632 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
4636 if (ac != priv->activating_connection) {
4637 g_clear_object (&priv->activating_connection);
4638 priv->activating_connection = ac ? g_object_ref (ac) : NULL;
4639 _LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4640 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVATING_CONNECTION);
4644 #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
4648 GDBusConnection *connection;
4649 GDBusMessage *message;
4650 NMAuthSubject *subject;
4651 const char *permission;
4652 const char *audit_op;
4653 char *audit_prop_value;
4654 GType interface_type;
4655 const char *glib_propname;
4656 } PropertyFilterData;
4659 free_property_filter_data (PropertyFilterData *pfd)
4661 g_object_unref (pfd->self);
4662 g_object_unref (pfd->connection);
4663 g_object_unref (pfd->message);
4664 g_clear_object (&pfd->subject);
4665 g_free (pfd->audit_prop_value);
4666 g_slice_free (PropertyFilterData, pfd);
4670 prop_set_auth_done_cb (NMAuthChain *chain,
4672 GDBusMethodInvocation *context, /* NULL */
4675 PropertyFilterData *pfd = user_data;
4676 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4677 NMAuthCallResult result;
4678 GDBusMessage *reply = NULL;
4679 const char *error_message;
4680 gs_unref_object NMExportedObject *object = NULL;
4681 const NMGlobalDnsConfig *global_dns;
4682 gs_unref_variant GVariant *value = NULL;
4685 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4686 result = nm_auth_chain_get_result (chain, pfd->permission);
4687 if (error || (result != NM_AUTH_CALL_RESULT_YES)) {
4688 reply = g_dbus_message_new_method_error (pfd->message,
4689 NM_PERM_DENIED_ERROR,
4690 (error_message = "Not authorized to perform this operation"));
4692 error_message = error->message;
4696 object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr,
4697 g_dbus_message_get_path (pfd->message)));
4699 reply = g_dbus_message_new_method_error (pfd->message,
4700 "org.freedesktop.DBus.Error.UnknownObject",
4701 (error_message = "Object doesn't exist."));
4705 /* do some extra type checking... */
4706 if (!nm_exported_object_get_interface_by_type (object, pfd->interface_type)) {
4707 reply = g_dbus_message_new_method_error (pfd->message,
4708 "org.freedesktop.DBus.Error.InvalidArgs",
4709 (error_message = "Object is of unexpected type."));
4713 args = g_dbus_message_get_body (pfd->message);
4714 g_variant_get (args, "(&s&sv)", NULL, NULL, &value);
4715 g_assert (pfd->glib_propname);
4717 if (!strcmp (pfd->glib_propname, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) {
4718 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{sv}")));
4719 global_dns = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config));
4721 if (global_dns && !nm_global_dns_config_is_internal (global_dns)) {
4722 reply = g_dbus_message_new_method_error (pfd->message,
4723 NM_PERM_DENIED_ERROR,
4724 (error_message = "Global DNS configuration already set via configuration file"));
4727 /* ... but set the property on the @object itself. It would be correct to set the property
4728 * on the skeleton interface, but as it is now, the result is the same. */
4729 g_object_set (object, pfd->glib_propname, value, NULL);
4731 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
4733 g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL);
4736 reply = g_dbus_message_new_method_reply (pfd->message);
4737 g_dbus_message_set_body (reply, g_variant_new_tuple (NULL, 0));
4738 error_message = NULL;
4740 nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message);
4742 g_dbus_connection_send_message (pfd->connection, reply,
4743 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4745 g_object_unref (reply);
4746 nm_auth_chain_unref (chain);
4748 free_property_filter_data (pfd);
4752 do_set_property_check (gpointer user_data)
4754 PropertyFilterData *pfd = user_data;
4755 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4756 GDBusMessage *reply = NULL;
4758 const char *error_message = NULL;
4760 pfd->subject = nm_auth_subject_new_unix_process_from_message (pfd->connection, pfd->message);
4761 if (!pfd->subject) {
4762 reply = g_dbus_message_new_method_error (pfd->message,
4763 NM_PERM_DENIED_ERROR,
4764 (error_message = "Could not determine request UID."));
4768 /* Validate the user request */
4769 chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd);
4771 reply = g_dbus_message_new_method_error (pfd->message,
4772 NM_PERM_DENIED_ERROR,
4773 (error_message = "Could not authenticate request."));
4777 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4778 nm_auth_chain_add_call (chain, pfd->permission, TRUE);
4782 nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, FALSE, pfd->subject, error_message);
4783 g_dbus_connection_send_message (pfd->connection, reply,
4784 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4786 g_object_unref (reply);
4787 free_property_filter_data (pfd);
4793 static GDBusMessage *
4794 prop_filter (GDBusConnection *connection,
4795 GDBusMessage *message,
4799 gs_unref_object NMManager *self = NULL;
4801 const char *propiface = NULL;
4802 const char *propname = NULL;
4803 const char *glib_propname = NULL, *permission = NULL;
4804 const char *audit_op = NULL;
4805 GType interface_type = G_TYPE_INVALID;
4806 PropertyFilterData *pfd;
4807 const GVariantType *expected_type = G_VARIANT_TYPE_BOOLEAN;
4808 gs_unref_variant GVariant *value = NULL;
4810 self = g_weak_ref_get (user_data);
4814 /* The sole purpose of this function is to validate property accesses on the
4815 * NMManager object since gdbus doesn't give us this functionality.
4818 /* Only filter org.freedesktop.DBus.Properties.Set calls */
4820 || g_dbus_message_get_message_type (message) != G_DBUS_MESSAGE_TYPE_METHOD_CALL
4821 || g_strcmp0 (g_dbus_message_get_interface (message), DBUS_INTERFACE_PROPERTIES) != 0
4822 || g_strcmp0 (g_dbus_message_get_member (message), "Set") != 0)
4825 args = g_dbus_message_get_body (message);
4826 if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)")))
4828 g_variant_get (args, "(&s&sv)", &propiface, &propname, &value);
4830 /* Only filter calls to filtered properties, on existing objects */
4831 if (!strcmp (propiface, NM_DBUS_INTERFACE)) {
4832 if (!strcmp (propname, "WirelessEnabled")) {
4833 glib_propname = NM_MANAGER_WIRELESS_ENABLED;
4834 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI;
4835 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4836 } else if (!strcmp (propname, "WwanEnabled")) {
4837 glib_propname = NM_MANAGER_WWAN_ENABLED;
4838 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
4839 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4840 } else if (!strcmp (propname, "WimaxEnabled")) {
4841 glib_propname = NM_MANAGER_WIMAX_ENABLED;
4842 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
4843 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4844 } else if (!strcmp (propname, "GlobalDnsConfiguration")) {
4845 glib_propname = NM_MANAGER_GLOBAL_DNS_CONFIGURATION;
4846 permission = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
4847 audit_op = NM_AUDIT_OP_NET_CONTROL;
4848 expected_type = G_VARIANT_TYPE ("a{sv}");
4851 interface_type = NMDBUS_TYPE_MANAGER_SKELETON;
4852 } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)) {
4853 if (!strcmp (propname, "Autoconnect")) {
4854 glib_propname = NM_DEVICE_AUTOCONNECT;
4855 permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4856 audit_op = NM_AUDIT_OP_DEVICE_AUTOCONNECT;
4857 } else if (!strcmp (propname, "Managed")) {
4858 glib_propname = NM_DEVICE_MANAGED;
4859 permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4860 audit_op = NM_AUDIT_OP_DEVICE_MANAGED;
4863 interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
4867 if (!g_variant_is_of_type (value, expected_type))
4870 /* This filter function is called from a gdbus worker thread which we can't
4871 * make other D-Bus calls from. In particular, we cannot call
4872 * org.freedesktop.DBus.GetConnectionUnixUser to find the remote UID.
4874 pfd = g_slice_new0 (PropertyFilterData);
4877 pfd->connection = g_object_ref (connection);
4878 pfd->message = message;
4879 pfd->permission = permission;
4880 pfd->interface_type = interface_type;
4881 pfd->glib_propname = glib_propname;
4882 pfd->audit_op = audit_op;
4883 if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
4884 pfd->audit_prop_value = g_strdup_printf ("%s:%d", pfd->glib_propname,
4885 g_variant_get_boolean (value));
4887 pfd->audit_prop_value = g_strdup (pfd->glib_propname);
4889 g_idle_add (do_set_property_check, pfd);
4894 /******************************************************************************/
4897 _set_prop_filter_free2 (gpointer user_data)
4899 g_slice_free (GWeakRef, user_data);
4900 return G_SOURCE_REMOVE;
4904 _set_prop_filter_free (gpointer user_data)
4906 g_weak_ref_clear (user_data);
4908 /* Delay the final deletion of the user_data. There is a race when
4909 * calling g_dbus_connection_remove_filter() that the callback and user_data
4910 * might have been copied and being executed after the destroy function
4911 * runs (bgo #704568).
4912 * This doesn't really fix the race, but it should work well enough. */
4913 g_timeout_add_seconds (2, _set_prop_filter_free2, user_data);
4917 _set_prop_filter (NMManager *self, GDBusConnection *connection)
4919 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4921 nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id));
4923 if (priv->prop_filter.connection == connection)
4926 if (priv->prop_filter.connection) {
4927 g_dbus_connection_remove_filter (priv->prop_filter.connection, priv->prop_filter.id);
4928 priv->prop_filter.id = 0;
4929 g_clear_object (&priv->prop_filter.connection);
4934 wptr = g_slice_new (GWeakRef);
4935 g_weak_ref_init (wptr, self);
4936 priv->prop_filter.id = g_dbus_connection_add_filter (connection, prop_filter, wptr, _set_prop_filter_free);
4937 priv->prop_filter.connection = g_object_ref (connection);
4941 /******************************************************************************/
4944 authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data)
4946 /* Let clients know they should re-check their authorization */
4947 g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
4950 #define KERN_RFKILL_OP_CHANGE_ALL 3
4951 #define KERN_RFKILL_TYPE_WLAN 1
4952 #define KERN_RFKILL_TYPE_WWAN 5
4953 struct rfkill_event {
4958 } __attribute__((packed));
4961 rfkill_change (const char *desc, RfKillType rtype, gboolean enabled)
4964 struct rfkill_event event;
4967 g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
4970 fd = open ("/dev/rfkill", O_RDWR);
4972 if (errno == EACCES)
4973 nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device", desc);
4977 if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
4978 nm_log_warn (LOGD_RFKILL, "(%s): failed to set killswitch device for "
4979 "non-blocking operation", desc);
4984 memset (&event, 0, sizeof (event));
4985 event.op = KERN_RFKILL_OP_CHANGE_ALL;
4987 case RFKILL_TYPE_WLAN:
4988 event.type = KERN_RFKILL_TYPE_WLAN;
4990 case RFKILL_TYPE_WWAN:
4991 event.type = KERN_RFKILL_TYPE_WWAN;
4994 g_assert_not_reached ();
4996 event.soft = enabled ? 0 : 1;
4998 len = write (fd, &event, sizeof (event));
5000 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
5001 desc, errno, g_strerror (errno));
5002 } else if (len == sizeof (event)) {
5003 nm_log_info (LOGD_RFKILL, "%s hardware radio set %s",
5004 desc, enabled ? "enabled" : "disabled");
5006 /* Failed to write full structure */
5007 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
5014 manager_radio_user_toggled (NMManager *self,
5018 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5019 GError *error = NULL;
5020 gboolean old_enabled, new_enabled;
5022 /* Don't touch devices if asleep/networking disabled */
5023 if (manager_sleeping (self))
5027 _LOGD (LOGD_RFKILL, "(%s): setting radio %s by user",
5029 enabled ? "enabled" : "disabled");
5032 /* Update enabled key in state file */
5033 if (priv->state_file) {
5034 if (!write_value_to_state_file (priv->state_file,
5035 "main", rstate->key,
5036 G_TYPE_BOOLEAN, (gpointer) &enabled,
5038 _LOGW (LOGD_CORE, "writing to state file %s failed: %s",
5041 g_clear_error (&error);
5045 /* When the user toggles the radio, their request should override any
5046 * daemon (like ModemManager) enabled state that can be changed. For WWAN
5047 * for example, we want the WwanEnabled property to reflect the daemon state
5048 * too so that users can toggle the modem powered, but we don't want that
5049 * daemon state to affect whether or not the user *can* turn it on, which is
5050 * what the kernel rfkill state does. So we ignore daemon enabled state
5051 * when determining what the new state should be since it shouldn't block
5052 * the user's request.
5054 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
5055 rstate->user_enabled = enabled;
5056 new_enabled = radio_enabled_for_rstate (rstate, FALSE);
5057 if (new_enabled != old_enabled) {
5058 /* Try to change the kernel rfkill state */
5059 if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN)
5060 rfkill_change (rstate->desc, rstate->rtype, new_enabled);
5062 manager_update_radio_enabled (self, rstate, new_enabled);
5067 periodic_update_active_connection_timestamps (gpointer user_data)
5069 NMManager *manager = NM_MANAGER (user_data);
5070 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5073 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
5074 NMActiveConnection *ac = iter->data;
5075 NMSettingsConnection *connection;
5077 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
5078 connection = nm_active_connection_get_settings_connection (ac);
5079 nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
5087 dbus_connection_changed_cb (NMBusManager *dbus_mgr,
5088 GDBusConnection *connection,
5091 _set_prop_filter (NM_MANAGER (user_data), connection);
5094 /**********************************************************************/
5096 NM_DEFINE_SINGLETON_REGISTER (NMManager);
5099 nm_manager_get (void)
5101 g_return_val_if_fail (singleton_instance, NULL);
5102 return singleton_instance;
5105 NMConnectionProvider *
5106 nm_connection_provider_get (void)
5108 NMConnectionProvider *p;
5110 g_return_val_if_fail (singleton_instance, NULL);
5112 p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings);
5113 g_return_val_if_fail (p, NULL);
5118 nm_manager_setup (const char *state_file,
5119 gboolean initial_net_enabled,
5120 gboolean initial_wifi_enabled,
5121 gboolean initial_wwan_enabled)
5125 g_return_val_if_fail (!singleton_instance, singleton_instance);
5127 self = g_object_new (NM_TYPE_MANAGER,
5128 NM_MANAGER_NETWORKING_ENABLED, initial_net_enabled,
5129 NM_MANAGER_WIRELESS_ENABLED, initial_wifi_enabled,
5130 NM_MANAGER_WWAN_ENABLED, initial_wwan_enabled,
5131 NM_MANAGER_STATE_FILE, state_file,
5133 nm_assert (NM_IS_MANAGER (self));
5134 singleton_instance = self;
5136 nm_singleton_instance_register ();
5137 _LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance);
5139 nm_exported_object_export ((NMExportedObject *) self);
5145 constructed (GObject *object)
5147 NMManager *self = NM_MANAGER (object);
5148 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5149 NMConfigData *config_data;
5151 G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
5153 _set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr));
5155 priv->settings = nm_settings_new ();
5156 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE,
5157 G_CALLBACK (settings_startup_complete_changed), self);
5158 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
5159 G_CALLBACK (system_unmanaged_devices_changed_cb), self);
5160 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
5161 G_CALLBACK (system_hostname_changed_cb), self);
5162 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
5163 G_CALLBACK (connection_changed), self);
5164 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
5165 G_CALLBACK (connection_changed), self);
5166 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
5167 G_CALLBACK (connection_removed), self);
5169 priv->policy = nm_policy_new (self, priv->settings);
5170 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
5171 G_CALLBACK (policy_default_device_changed), self);
5172 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
5173 G_CALLBACK (policy_default_device_changed), self);
5174 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
5175 G_CALLBACK (policy_activating_device_changed), self);
5176 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
5177 G_CALLBACK (policy_activating_device_changed), self);
5179 priv->config = g_object_ref (nm_config_get ());
5180 g_signal_connect (G_OBJECT (priv->config),
5181 NM_CONFIG_SIGNAL_CONFIG_CHANGED,
5182 G_CALLBACK (_config_changed_cb),
5185 config_data = nm_config_get_data (priv->config);
5186 priv->connectivity = nm_connectivity_new (nm_config_data_get_connectivity_uri (config_data),
5187 nm_config_data_get_connectivity_interval (config_data),
5188 nm_config_data_get_connectivity_response (config_data));
5189 g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
5190 G_CALLBACK (connectivity_changed), self);
5192 priv->rfkill_mgr = nm_rfkill_manager_new ();
5193 g_signal_connect (priv->rfkill_mgr,
5195 G_CALLBACK (rfkill_manager_rfkill_changed_cb),
5198 /* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state
5199 * in case the BIOS doesn't save rfkill state, and to be consistent with user
5200 * changes to the WirelessEnabled/WWANEnabled properties which toggle kernel
5203 rfkill_change (priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled);
5204 rfkill_change (priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, priv->radio_states[RFKILL_TYPE_WWAN].user_enabled);
5208 nm_manager_init (NMManager *self)
5210 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5214 /* Initialize rfkill structures and states */
5215 memset (priv->radio_states, 0, sizeof (priv->radio_states));
5217 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
5218 priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
5219 priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
5220 priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
5221 priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
5222 priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
5224 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
5225 priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
5226 priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
5227 priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
5228 priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
5229 priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
5231 for (i = 0; i < RFKILL_TYPE_MAX; i++)
5232 priv->radio_states[i].hw_enabled = TRUE;
5234 priv->sleeping = FALSE;
5235 priv->state = NM_STATE_DISCONNECTED;
5236 priv->startup = TRUE;
5238 priv->dbus_mgr = g_object_ref (nm_bus_manager_get ());
5239 g_signal_connect (priv->dbus_mgr,
5240 NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED,
5241 G_CALLBACK (dbus_connection_changed_cb),
5244 /* sleep/wake handling */
5245 priv->sleep_monitor = g_object_ref (nm_sleep_monitor_get ());
5246 g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING,
5247 G_CALLBACK (sleeping_cb), self);
5248 g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_RESUMING,
5249 G_CALLBACK (resuming_cb), self);
5251 /* Listen for authorization changes */
5252 g_signal_connect (nm_auth_manager_get (),
5253 NM_AUTH_MANAGER_SIGNAL_CHANGED,
5254 G_CALLBACK (authority_changed_cb),
5258 /* Monitor the firmware directory */
5259 if (strlen (KERNEL_FIRMWARE_DIR)) {
5260 file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/");
5261 priv->fw_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
5262 g_object_unref (file);
5265 if (priv->fw_monitor) {
5266 g_signal_connect (priv->fw_monitor, "changed",
5267 G_CALLBACK (firmware_dir_changed),
5269 _LOGI (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
5270 KERNEL_FIRMWARE_DIR);
5272 _LOGW (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
5273 KERNEL_FIRMWARE_DIR);
5276 /* Update timestamps in active connections */
5277 priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, self);
5279 priv->metered = NM_METERED_UNKNOWN;
5283 device_is_real (GObject *device, gpointer user_data)
5285 return nm_device_is_real (NM_DEVICE (device));
5289 get_property (GObject *object, guint prop_id,
5290 GValue *value, GParamSpec *pspec)
5292 NMManager *self = NM_MANAGER (object);
5293 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5294 NMConfigData *config_data;
5295 const NMGlobalDnsConfig *dns_config;
5300 g_value_set_string (value, VERSION);
5303 nm_manager_update_state (self);
5304 g_value_set_uint (value, priv->state);
5307 g_value_set_boolean (value, priv->startup);
5309 case PROP_NETWORKING_ENABLED:
5310 g_value_set_boolean (value, priv->net_enabled);
5312 case PROP_WIRELESS_ENABLED:
5313 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
5315 case PROP_WIRELESS_HARDWARE_ENABLED:
5316 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
5318 case PROP_WWAN_ENABLED:
5319 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
5321 case PROP_WWAN_HARDWARE_ENABLED:
5322 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
5324 case PROP_WIMAX_ENABLED:
5325 g_value_set_boolean (value, FALSE);
5327 case PROP_WIMAX_HARDWARE_ENABLED:
5328 g_value_set_boolean (value, FALSE);
5330 case PROP_ACTIVE_CONNECTIONS:
5331 nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
5333 case PROP_CONNECTIVITY:
5334 g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
5336 case PROP_PRIMARY_CONNECTION:
5337 nm_utils_g_value_set_object_path (value, priv->primary_connection);
5339 case PROP_PRIMARY_CONNECTION_TYPE:
5341 if (priv->primary_connection) {
5344 con = nm_active_connection_get_applied_connection (priv->primary_connection);
5346 type = nm_connection_get_connection_type (con);
5348 g_value_set_string (value, type ? type : "");
5350 case PROP_ACTIVATING_CONNECTION:
5351 nm_utils_g_value_set_object_path (value, priv->activating_connection);
5354 g_value_set_string (value, priv->hostname);
5357 g_value_set_boolean (value, priv->sleeping);
5360 nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
5363 g_value_set_uint (value, priv->metered);
5365 case PROP_GLOBAL_DNS_CONFIGURATION:
5366 config_data = nm_config_get_data (priv->config);
5367 dns_config = nm_config_data_get_global_dns_config (config_data);
5368 nm_global_dns_config_to_dbus (dns_config, value);
5370 case PROP_ALL_DEVICES:
5371 nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
5374 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5380 set_property (GObject *object, guint prop_id,
5381 const GValue *value, GParamSpec *pspec)
5383 NMManager *self = NM_MANAGER (object);
5384 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5385 NMGlobalDnsConfig *dns_config;
5386 GError *error = NULL;
5389 case PROP_STATE_FILE:
5390 /* construct-only */
5391 priv->state_file = g_value_dup_string (value);
5393 case PROP_NETWORKING_ENABLED:
5394 /* construct-only */
5395 priv->net_enabled = g_value_get_boolean (value);
5397 case PROP_WIRELESS_ENABLED:
5398 if (!priv->rfkill_mgr) {
5399 /* called during object construction. */
5400 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = g_value_get_boolean (value);
5402 manager_radio_user_toggled (NM_MANAGER (object),
5403 &priv->radio_states[RFKILL_TYPE_WLAN],
5404 g_value_get_boolean (value));
5407 case PROP_WWAN_ENABLED:
5408 if (!priv->rfkill_mgr) {
5409 /* called during object construction. */
5410 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = g_value_get_boolean (value);
5412 manager_radio_user_toggled (NM_MANAGER (object),
5413 &priv->radio_states[RFKILL_TYPE_WWAN],
5414 g_value_get_boolean (value));
5417 case PROP_WIMAX_ENABLED:
5418 /* WIMAX is depreacted. This does nothing. */
5420 case PROP_GLOBAL_DNS_CONFIGURATION:
5421 dns_config = nm_global_dns_config_from_dbus (value, &error);
5423 nm_config_set_global_dns (priv->config, dns_config, &error);
5425 nm_global_dns_config_free (dns_config);
5428 _LOGD (LOGD_CORE, "set global DNS failed with error: %s", error->message);
5429 g_error_free (error);
5433 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5439 _deinit_device_factory (NMDeviceFactory *factory, gpointer user_data)
5441 g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NM_MANAGER (user_data));
5445 dispose (GObject *object)
5447 NMManager *manager = NM_MANAGER (object);
5448 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5450 g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
5451 priv->auth_chains = NULL;
5453 g_signal_handlers_disconnect_by_func (nm_auth_manager_get (),
5454 G_CALLBACK (authority_changed_cb),
5457 g_assert (priv->devices == NULL);
5459 nm_clear_g_source (&priv->ac_cleanup_id);
5461 while (priv->active_connections)
5462 active_connection_remove (manager, NM_ACTIVE_CONNECTION (priv->active_connections->data));
5463 g_clear_pointer (&priv->active_connections, g_slist_free);
5464 g_clear_object (&priv->primary_connection);
5465 g_clear_object (&priv->activating_connection);
5468 g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
5469 g_clear_object (&priv->config);
5471 if (priv->connectivity) {
5472 g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
5473 g_clear_object (&priv->connectivity);
5476 g_free (priv->hostname);
5479 g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, manager);
5480 g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, manager);
5481 g_clear_object (&priv->policy);
5484 if (priv->settings) {
5485 g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, manager);
5486 g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, manager);
5487 g_signal_handlers_disconnect_by_func (priv->settings, system_hostname_changed_cb, manager);
5488 g_signal_handlers_disconnect_by_func (priv->settings, connection_changed, manager);
5489 g_signal_handlers_disconnect_by_func (priv->settings, connection_removed, manager);
5490 g_clear_object (&priv->settings);
5493 g_clear_pointer (&priv->state_file, g_free);
5494 g_clear_object (&priv->vpn_manager);
5496 /* Unregister property filter */
5497 if (priv->dbus_mgr) {
5498 g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, manager);
5499 g_clear_object (&priv->dbus_mgr);
5501 _set_prop_filter (manager, NULL);
5503 if (priv->sleep_monitor) {
5504 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, sleeping_cb, manager);
5505 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, resuming_cb, manager);
5506 g_clear_object (&priv->sleep_monitor);
5509 if (priv->fw_monitor) {
5510 g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager);
5512 nm_clear_g_source (&priv->fw_changed_id);
5514 g_file_monitor_cancel (priv->fw_monitor);
5515 g_clear_object (&priv->fw_monitor);
5518 if (priv->rfkill_mgr) {
5519 g_signal_handlers_disconnect_by_func (priv->rfkill_mgr, rfkill_manager_rfkill_changed_cb, manager);
5520 g_clear_object (&priv->rfkill_mgr);
5523 nm_device_factory_manager_for_each_factory (_deinit_device_factory, manager);
5525 nm_clear_g_source (&priv->timestamp_update_id);
5527 G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
5531 nm_manager_class_init (NMManagerClass *manager_class)
5533 GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
5534 NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
5536 g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
5538 exported_object_class->export_path = NM_DBUS_PATH;
5540 /* virtual methods */
5541 object_class->constructed = constructed;
5542 object_class->set_property = set_property;
5543 object_class->get_property = get_property;
5544 object_class->dispose = dispose;
5547 g_object_class_install_property
5548 (object_class, PROP_VERSION,
5549 g_param_spec_string (NM_MANAGER_VERSION, "", "",
5552 G_PARAM_STATIC_STRINGS));
5554 g_object_class_install_property (object_class,
5556 g_param_spec_string (NM_MANAGER_STATE_FILE, "", "",
5559 G_PARAM_CONSTRUCT_ONLY |
5560 G_PARAM_STATIC_STRINGS));
5562 g_object_class_install_property
5563 (object_class, PROP_STATE,
5564 g_param_spec_uint (NM_MANAGER_STATE, "", "",
5565 0, NM_STATE_DISCONNECTED, 0,
5567 G_PARAM_STATIC_STRINGS));
5569 g_object_class_install_property
5570 (object_class, PROP_STARTUP,
5571 g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
5574 G_PARAM_STATIC_STRINGS));
5576 g_object_class_install_property
5577 (object_class, PROP_NETWORKING_ENABLED,
5578 g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
5580 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
5581 G_PARAM_STATIC_STRINGS));
5583 g_object_class_install_property
5584 (object_class, PROP_WIRELESS_ENABLED,
5585 g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
5589 G_PARAM_STATIC_STRINGS));
5591 g_object_class_install_property
5592 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
5593 g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
5596 G_PARAM_STATIC_STRINGS));
5598 g_object_class_install_property
5599 (object_class, PROP_WWAN_ENABLED,
5600 g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
5604 G_PARAM_STATIC_STRINGS));
5606 g_object_class_install_property
5607 (object_class, PROP_WWAN_HARDWARE_ENABLED,
5608 g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
5611 G_PARAM_STATIC_STRINGS));
5613 g_object_class_install_property
5614 (object_class, PROP_WIMAX_ENABLED,
5615 g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
5618 G_PARAM_STATIC_STRINGS));
5620 g_object_class_install_property
5621 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
5622 g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
5625 G_PARAM_STATIC_STRINGS));
5627 g_object_class_install_property
5628 (object_class, PROP_ACTIVE_CONNECTIONS,
5629 g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
5632 G_PARAM_STATIC_STRINGS));
5634 g_object_class_install_property
5635 (object_class, PROP_CONNECTIVITY,
5636 g_param_spec_uint (NM_MANAGER_CONNECTIVITY, "", "",
5637 NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
5639 G_PARAM_STATIC_STRINGS));
5641 g_object_class_install_property
5642 (object_class, PROP_PRIMARY_CONNECTION,
5643 g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION, "", "",
5646 G_PARAM_STATIC_STRINGS));
5648 g_object_class_install_property
5649 (object_class, PROP_PRIMARY_CONNECTION_TYPE,
5650 g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "",
5653 G_PARAM_STATIC_STRINGS));
5656 g_object_class_install_property
5657 (object_class, PROP_ACTIVATING_CONNECTION,
5658 g_param_spec_string (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
5661 G_PARAM_STATIC_STRINGS));
5663 /* Hostname is not exported over D-Bus */
5664 g_object_class_install_property
5665 (object_class, PROP_HOSTNAME,
5666 g_param_spec_string (NM_MANAGER_HOSTNAME, "", "",
5669 G_PARAM_STATIC_STRINGS));
5671 /* Sleeping is not exported over D-Bus */
5672 g_object_class_install_property
5673 (object_class, PROP_SLEEPING,
5674 g_param_spec_boolean (NM_MANAGER_SLEEPING, "", "",
5677 G_PARAM_STATIC_STRINGS));
5679 g_object_class_install_property
5680 (object_class, PROP_DEVICES,
5681 g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
5684 G_PARAM_STATIC_STRINGS));
5687 * NMManager:metered:
5689 * Whether the connectivity is metered.
5693 g_object_class_install_property
5694 (object_class, PROP_METERED,
5695 g_param_spec_uint (NM_MANAGER_METERED, "", "",
5696 0, G_MAXUINT32, NM_METERED_UNKNOWN,
5698 G_PARAM_STATIC_STRINGS));
5701 * NMManager:global-dns-configuration:
5703 * The global DNS configuration.
5707 g_object_class_install_property
5708 (object_class, PROP_GLOBAL_DNS_CONFIGURATION,
5709 g_param_spec_variant (NM_MANAGER_GLOBAL_DNS_CONFIGURATION, "", "",
5710 G_VARIANT_TYPE ("a{sv}"),
5713 G_PARAM_STATIC_STRINGS));
5716 * NMManager:all-devices:
5718 * All devices, including those that are not realized.
5722 g_object_class_install_property
5723 (object_class, PROP_ALL_DEVICES,
5724 g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
5727 G_PARAM_STATIC_STRINGS));
5731 /* D-Bus exported; emitted only for realized devices */
5732 signals[DEVICE_ADDED] =
5733 g_signal_new ("device-added",
5734 G_OBJECT_CLASS_TYPE (object_class),
5736 G_STRUCT_OFFSET (NMManagerClass, device_added),
5738 G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5740 /* Emitted for both realized devices and placeholder devices */
5741 signals[INTERNAL_DEVICE_ADDED] =
5742 g_signal_new ("internal-device-added",
5743 G_OBJECT_CLASS_TYPE (object_class),
5744 G_SIGNAL_RUN_FIRST, 0,
5746 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5748 /* D-Bus exported; emitted only for realized devices */
5749 signals[DEVICE_REMOVED] =
5750 g_signal_new ("device-removed",
5751 G_OBJECT_CLASS_TYPE (object_class),
5753 G_STRUCT_OFFSET (NMManagerClass, device_removed),
5755 G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5757 /* Emitted for both realized devices and placeholder devices */
5758 signals[INTERNAL_DEVICE_REMOVED] =
5759 g_signal_new ("internal-device-removed",
5760 G_OBJECT_CLASS_TYPE (object_class),
5761 G_SIGNAL_RUN_FIRST, 0,
5763 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5765 signals[STATE_CHANGED] =
5766 g_signal_new (NM_MANAGER_STATE_CHANGED,
5767 G_OBJECT_CLASS_TYPE (object_class),
5769 G_STRUCT_OFFSET (NMManagerClass, state_changed),
5771 G_TYPE_NONE, 1, G_TYPE_UINT);
5773 signals[CHECK_PERMISSIONS] =
5774 g_signal_new ("check-permissions",
5775 G_OBJECT_CLASS_TYPE (object_class),
5777 0, NULL, NULL, NULL,
5780 signals[USER_PERMISSIONS_CHANGED] =
5781 g_signal_new ("user-permissions-changed",
5782 G_OBJECT_CLASS_TYPE (object_class),
5784 0, NULL, NULL, NULL,
5787 signals[ACTIVE_CONNECTION_ADDED] =
5788 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
5789 G_OBJECT_CLASS_TYPE (object_class),
5791 0, NULL, NULL, NULL,
5792 G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5794 signals[ACTIVE_CONNECTION_REMOVED] =
5795 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
5796 G_OBJECT_CLASS_TYPE (object_class),
5798 0, NULL, NULL, NULL,
5799 G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5801 signals[CONFIGURE_QUIT] =
5802 g_signal_new (NM_MANAGER_CONFIGURE_QUIT,
5803 G_OBJECT_CLASS_TYPE (object_class),
5805 0, NULL, NULL, NULL,
5808 nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class),
5809 NMDBUS_TYPE_MANAGER_SKELETON,
5810 "GetDevices", impl_manager_get_devices,
5811 "GetAllDevices", impl_manager_get_all_devices,
5812 "GetDeviceByIpIface", impl_manager_get_device_by_ip_iface,
5813 "ActivateConnection", impl_manager_activate_connection,
5814 "AddAndActivateConnection", impl_manager_add_and_activate_connection,
5815 "DeactivateConnection", impl_manager_deactivate_connection,
5816 "Sleep", impl_manager_sleep,
5817 "Enable", impl_manager_enable,
5818 "GetPermissions", impl_manager_get_permissions,
5819 "SetLogging", impl_manager_set_logging,
5820 "GetLogging", impl_manager_get_logging,
5821 "CheckConnectivity", impl_manager_check_connectivity,
5822 "state", impl_manager_get_state,