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,
230 /* Returns: whether to notify D-Bus of the removal or not */
232 active_connection_remove (NMManager *self, NMActiveConnection *active)
234 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
235 gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
238 /* FIXME: switch to a GList for faster removal */
239 found = g_slist_find (priv->active_connections, active);
241 NMSettingsConnection *connection;
243 priv->active_connections = g_slist_remove (priv->active_connections, active);
244 g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
245 g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
246 g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
248 if ( nm_active_connection_get_assumed (active)
249 && (connection = nm_active_connection_get_settings_connection (active))
250 && nm_settings_connection_get_nm_generated_assumed (connection))
251 g_object_ref (connection);
255 nm_exported_object_clear_and_unexport (&active);
258 && nm_settings_has_connection (priv->settings, connection)) {
259 _LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
260 nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
261 nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL);
262 g_object_unref (connection);
266 return found && notify;
270 _active_connection_cleanup (gpointer user_data)
272 NMManager *self = NM_MANAGER (user_data);
273 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
276 priv->ac_cleanup_id = 0;
278 g_object_freeze_notify (G_OBJECT (self));
279 iter = priv->active_connections;
281 NMActiveConnection *ac = iter->data;
284 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
285 if (active_connection_remove (self, ac))
286 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
289 g_object_thaw_notify (G_OBJECT (self));
295 active_connection_state_changed (NMActiveConnection *active,
299 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
300 NMActiveConnectionState state;
302 state = nm_active_connection_get_state (active);
303 if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
304 /* Destroy active connections from an idle handler to ensure that
305 * their last property change notifications go out, which wouldn't
306 * happen if we destroyed them immediately when their state was set
309 if (!priv->ac_cleanup_id)
310 priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
313 nm_manager_update_state (self);
317 active_connection_default_changed (NMActiveConnection *active,
321 nm_manager_update_state (self);
325 * active_connection_add():
326 * @self: the #NMManager
327 * @active: the #NMActiveConnection to manage
329 * Begins to track and manage @active. Increases the refcount of @active.
332 active_connection_add (NMManager *self, NMActiveConnection *active)
334 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
336 g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
338 priv->active_connections = g_slist_prepend (priv->active_connections,
339 g_object_ref (active));
341 g_signal_connect (active,
342 "notify::" NM_ACTIVE_CONNECTION_STATE,
343 G_CALLBACK (active_connection_state_changed),
345 g_signal_connect (active,
346 "notify::" NM_ACTIVE_CONNECTION_DEFAULT,
347 G_CALLBACK (active_connection_default_changed),
349 g_signal_connect (active,
350 "notify::" NM_ACTIVE_CONNECTION_DEFAULT6,
351 G_CALLBACK (active_connection_default_changed),
354 g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
356 /* Only notify D-Bus if the active connection is actually exported */
357 if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active)))
358 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
362 nm_manager_get_active_connections (NMManager *manager)
364 return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
367 static NMActiveConnection *
368 find_ac_for_connection (NMManager *manager, NMConnection *connection)
370 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
372 const char *uuid = NULL;
373 gboolean is_settings_connection;
375 is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
377 if (!is_settings_connection)
378 uuid = nm_connection_get_uuid (connection);
380 for (iter = priv->active_connections; iter; iter = iter->next) {
381 NMActiveConnection *ac = iter->data;
382 NMSettingsConnection *con;
384 con = nm_active_connection_get_settings_connection (ac);
386 /* depending on whether we have a NMSettingsConnection or a NMConnection,
387 * we lookup by UUID or by reference. */
388 if (is_settings_connection) {
389 if (con != (NMSettingsConnection *) connection)
392 if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
395 if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
402 /* Filter out connections that are already active.
403 * nm_settings_get_connections() returns sorted list. We need to preserve the
404 * order so that we didn't change auto-activation order (recent timestamps
406 * Caller is responsible for freeing the returned list with g_slist_free().
409 nm_manager_get_activatable_connections (NMManager *manager)
411 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
412 GSList *all_connections = nm_settings_get_connections (priv->settings);
413 GSList *connections = NULL, *iter;
414 NMSettingsConnection *connection;
416 for (iter = all_connections; iter; iter = iter->next) {
417 connection = iter->data;
419 if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
420 connections = g_slist_prepend (connections, connection);
423 g_slist_free (all_connections);
424 return g_slist_reverse (connections);
427 static NMActiveConnection *
428 active_connection_get_by_path (NMManager *manager, const char *path)
430 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
433 g_return_val_if_fail (manager != NULL, NULL);
434 g_return_val_if_fail (path != NULL, NULL);
436 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
437 NMActiveConnection *candidate = iter->data;
439 if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
445 /************************************************************************/
448 _config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
450 g_object_set (NM_MANAGER_GET_PRIVATE (self)->connectivity,
451 NM_CONNECTIVITY_URI, nm_config_data_get_connectivity_uri (config_data),
452 NM_CONNECTIVITY_INTERVAL, nm_config_data_get_connectivity_interval (config_data),
453 NM_CONNECTIVITY_RESPONSE, nm_config_data_get_connectivity_response (config_data),
456 if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG))
457 g_object_notify (G_OBJECT (self), NM_MANAGER_GLOBAL_DNS_CONFIGURATION);
460 /************************************************************************/
463 nm_manager_get_device_by_path (NMManager *manager, const char *path)
467 g_return_val_if_fail (path != NULL, NULL);
469 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
470 if (!strcmp (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)), path))
471 return NM_DEVICE (iter->data);
477 nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
481 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
482 NMDevice *device = NM_DEVICE (iter->data);
484 if (nm_device_get_ifindex (device) == ifindex)
492 find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
495 const char *device_addr;
497 g_return_val_if_fail (hwaddr != NULL, NULL);
499 if (nm_utils_hwaddr_valid (hwaddr, -1)) {
500 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
501 device_addr = nm_device_get_hw_address (NM_DEVICE (iter->data));
502 if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
503 return NM_DEVICE (iter->data);
510 find_device_by_ip_iface (NMManager *self, const gchar *iface)
514 g_return_val_if_fail (iface != NULL, NULL);
516 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
517 NMDevice *candidate = iter->data;
519 if ( nm_device_is_real (candidate)
520 && g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
527 * find_device_by_iface:
528 * @self: the #NMManager
529 * @iface: the device interface to find
530 * @connection: a connection to ensure the returned device is compatible with
531 * @slave: a slave connection to ensure a master is compatible with
533 * Finds a device by interface name, preferring realized devices. If @slave
534 * is given, this function will only return master devices and will ensure
535 * @slave, when activated, can be a slave of the returned master device. If
536 * @connection is given, this function will only consider devices that are
537 * compatible with @connection.
539 * Returns: the matching #NMDevice
542 find_device_by_iface (NMManager *self,
544 NMConnection *connection,
547 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
548 NMDevice *fallback = NULL;
551 g_return_val_if_fail (iface != NULL, NULL);
553 for (iter = priv->devices; iter; iter = iter->next) {
554 NMDevice *candidate = iter->data;
556 if (strcmp (nm_device_get_iface (candidate), iface))
558 if (connection && !nm_device_check_connection_compatible (candidate, connection))
561 if (!nm_device_is_master (candidate))
563 if (!nm_device_check_slave_connection_compatible (candidate, slave))
567 if (nm_device_is_real (candidate))
570 fallback = candidate;
576 manager_sleeping (NMManager *self)
578 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
580 if (priv->sleeping || !priv->net_enabled)
586 _nm_state_to_string (NMState state)
589 case NM_STATE_ASLEEP:
591 case NM_STATE_DISCONNECTED:
592 return "DISCONNECTED";
593 case NM_STATE_DISCONNECTING:
594 return "DISCONNECTING";
595 case NM_STATE_CONNECTING:
597 case NM_STATE_CONNECTED_LOCAL:
598 return "CONNECTED_LOCAL";
599 case NM_STATE_CONNECTED_SITE:
600 return "CONNECTED_SITE";
601 case NM_STATE_CONNECTED_GLOBAL:
602 return "CONNECTED_GLOBAL";
603 case NM_STATE_UNKNOWN:
610 set_state (NMManager *self, NMState state)
612 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
614 if (priv->state == state)
619 _LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
621 g_object_notify (G_OBJECT (self), NM_MANAGER_STATE);
622 g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state);
626 checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
628 NMManager *manager = user_data;
629 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
630 NMConnectivityState connectivity;
632 if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
633 connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
635 if (connectivity == NM_CONNECTIVITY_FULL)
636 set_state (manager, NM_STATE_CONNECTED_GLOBAL);
637 else if ( connectivity == NM_CONNECTIVITY_PORTAL
638 || connectivity == NM_CONNECTIVITY_LIMITED)
639 set_state (manager, NM_STATE_CONNECTED_SITE);
640 g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY);
643 g_object_unref (manager);
647 find_best_device_state (NMManager *manager)
649 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
650 NMState best_state = NM_STATE_DISCONNECTED;
653 for (iter = priv->active_connections; iter; iter = iter->next) {
654 NMActiveConnection *ac = NM_ACTIVE_CONNECTION (iter->data);
655 NMActiveConnectionState ac_state = nm_active_connection_get_state (ac);
658 case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
659 if ( nm_active_connection_get_default (ac)
660 || nm_active_connection_get_default6 (ac)) {
661 if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL)
662 return NM_STATE_CONNECTED_GLOBAL;
664 best_state = NM_STATE_CONNECTED_SITE;
666 if (best_state < NM_STATE_CONNECTING)
667 best_state = NM_STATE_CONNECTED_LOCAL;
670 case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
671 if (!nm_active_connection_get_assumed (ac)) {
672 if (best_state != NM_STATE_CONNECTED_GLOBAL)
673 best_state = NM_STATE_CONNECTING;
676 case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
677 if (!nm_active_connection_get_assumed (ac)) {
678 if (best_state < NM_STATE_DISCONNECTING)
679 best_state = NM_STATE_DISCONNECTING;
691 nm_manager_update_metered (NMManager *self)
693 NMManagerPrivate *priv;
695 NMMetered value = NM_METERED_UNKNOWN;
697 g_return_if_fail (NM_IS_MANAGER (self));
698 priv = NM_MANAGER_GET_PRIVATE (self);
700 if (priv->primary_connection) {
701 device = nm_active_connection_get_device (priv->primary_connection);
703 value = nm_device_get_metered (device);
706 if (value != priv->metered) {
707 priv->metered = value;
708 _LOGD (LOGD_CORE, "new metered value: %d", (int) priv->metered);
709 g_object_notify (G_OBJECT (self), NM_MANAGER_METERED);
714 nm_manager_update_state (NMManager *manager)
716 NMManagerPrivate *priv;
717 NMState new_state = NM_STATE_DISCONNECTED;
719 g_return_if_fail (NM_IS_MANAGER (manager));
721 priv = NM_MANAGER_GET_PRIVATE (manager);
723 if (manager_sleeping (manager))
724 new_state = NM_STATE_ASLEEP;
726 new_state = find_best_device_state (manager);
728 nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
730 if (new_state == NM_STATE_CONNECTED_SITE) {
731 nm_connectivity_check_async (priv->connectivity,
732 checked_connectivity,
733 g_object_ref (manager));
736 set_state (manager, new_state);
740 manager_device_state_changed (NMDevice *device,
741 NMDeviceState new_state,
742 NMDeviceState old_state,
743 NMDeviceStateReason reason,
746 NMManager *self = NM_MANAGER (user_data);
747 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
750 case NM_DEVICE_STATE_UNMANAGED:
751 case NM_DEVICE_STATE_UNAVAILABLE:
752 case NM_DEVICE_STATE_DISCONNECTED:
753 case NM_DEVICE_STATE_PREPARE:
754 case NM_DEVICE_STATE_FAILED:
755 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
761 if ( new_state == NM_DEVICE_STATE_UNAVAILABLE
762 || new_state == NM_DEVICE_STATE_DISCONNECTED)
763 nm_settings_device_added (priv->settings, device);
766 static void device_has_pending_action_changed (NMDevice *device,
771 check_if_startup_complete (NMManager *self)
773 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
779 if (!priv->devices_inited)
782 if (!nm_settings_get_startup_complete (priv->settings)) {
783 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
787 for (iter = priv->devices; iter; iter = iter->next) {
788 NMDevice *dev = iter->data;
790 if (nm_device_has_pending_action (dev)) {
791 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
792 nm_device_get_iface (dev));
797 _LOGI (LOGD_CORE, "startup complete");
799 priv->startup = FALSE;
800 g_object_notify (G_OBJECT (self), "startup");
802 /* We don't have to watch notify::has-pending-action any more. */
803 for (iter = priv->devices; iter; iter = iter->next) {
804 NMDevice *dev = iter->data;
806 g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
809 if (nm_config_get_configure_and_quit (nm_config_get ()))
810 g_signal_emit (self, signals[CONFIGURE_QUIT], 0);
814 device_has_pending_action_changed (NMDevice *device,
818 check_if_startup_complete (self);
822 settings_startup_complete_changed (NMSettings *settings,
826 check_if_startup_complete (self);
830 remove_device (NMManager *self,
833 gboolean allow_unmanage)
835 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
837 _LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)",
838 nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
840 if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
841 NMActRequest *req = nm_device_get_act_request (device);
842 gboolean unmanage = FALSE;
844 /* Leave activated interfaces up when quitting so their configuration
845 * can be taken over when NM restarts. This ensures connectivity while
846 * NM is stopped. Devices which do not support connection assumption
849 if (!quitting) /* Forced removal; device already gone */
851 else if (!nm_device_can_assume_active_connection (device))
858 nm_device_set_unmanaged_by_quitting (device);
860 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
861 } else if (quitting && nm_config_get_configure_and_quit (nm_config_get ())) {
862 nm_device_spawn_iface_helper (device);
866 g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
868 nm_settings_device_removed (priv->settings, device, quitting);
869 priv->devices = g_slist_remove (priv->devices, device);
871 if (nm_device_is_real (device)) {
872 g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
873 g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
874 nm_device_removed (device);
876 g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device);
877 g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
879 nm_exported_object_clear_and_unexport (&device);
881 check_if_startup_complete (self);
885 device_removed_cb (NMDevice *device, gpointer user_data)
887 remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
891 nm_manager_get_state (NMManager *manager)
893 g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
895 return NM_MANAGER_GET_PRIVATE (manager)->state;
898 /***************************/
901 find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
903 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
904 NMDeviceFactory *factory;
905 const char *parent_name = NULL;
906 NMSettingsConnection *parent_connection;
907 NMDevice *parent, *first_compatible = NULL;
910 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
912 if (!cached_factory) {
913 factory = nm_device_factory_manager_find_factory_for_connection (connection);
917 factory = cached_factory;
919 parent_name = nm_device_factory_get_connection_parent (factory, connection);
923 /* Try as an interface name of a parent device */
924 parent = find_device_by_iface (self, parent_name, NULL, NULL);
928 /* Maybe a hardware address */
929 parent = find_device_by_hw_addr (self, parent_name);
933 /* Maybe a connection UUID */
934 parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name);
935 if (!parent_connection)
938 /* Check if the parent connection is currently activated or is comaptible
939 * with some known device.
941 for (iter = priv->devices; iter; iter = iter->next) {
942 NMDevice *candidate = iter->data;
944 if (nm_device_get_settings_connection (candidate) == parent_connection)
947 if ( !first_compatible
948 && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
949 first_compatible = candidate;
952 return first_compatible;
956 * nm_manager_get_connection_iface:
957 * @self: the #NMManager
958 * @connection: the #NMConnection to get the interface for
959 * @out_parent: on success, the parent device if any
960 * @error: an error if determining the virtual interface name failed
962 * Given @connection, returns the interface name that the connection
963 * would need to use when activated. %NULL is returned if the name
964 * is not specified in connection or a the name for a virtual device
965 * could not be generated.
967 * Returns: the expected interface name (caller takes ownership), or %NULL
970 nm_manager_get_connection_iface (NMManager *self,
971 NMConnection *connection,
972 NMDevice **out_parent,
975 NMDeviceFactory *factory;
977 NMDevice *parent = NULL;
982 factory = nm_device_factory_manager_find_factory_for_connection (connection);
986 NM_MANAGER_ERROR_FAILED,
987 "NetworkManager plugin for '%s' unavailable",
988 nm_connection_get_connection_type (connection));
993 && !NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_iface) {
994 /* optimization. Shortcut lookup of the partent device. */
995 iface = g_strdup (nm_connection_get_interface_name (connection));
999 NM_MANAGER_ERROR_FAILED,
1000 "failed to determine interface name: error determine name for %s",
1001 nm_connection_get_connection_type (connection));
1006 parent = find_parent_device_for_connection (self, connection, factory);
1007 iface = nm_device_factory_get_connection_iface (factory,
1009 parent ? nm_device_get_ip_iface (parent) : NULL,
1015 *out_parent = parent;
1020 * system_create_virtual_device:
1021 * @self: the #NMManager
1022 * @connection: the connection which might require a virtual device
1024 * If @connection requires a virtual device and one does not yet exist for it,
1025 * creates that device.
1027 * Returns: A #NMDevice that was just realized; %NULL if none
1030 system_create_virtual_device (NMManager *self, NMConnection *connection)
1032 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1033 NMDeviceFactory *factory;
1034 gs_free_slist GSList *connections = NULL;
1036 gs_free char *iface = NULL;
1037 NMDevice *device = NULL, *parent = NULL;
1038 GError *error = NULL;
1040 g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
1041 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
1043 iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
1045 _LOGW (LOGD_DEVICE, "(%s) can't get a name of a virtual device: %s",
1046 nm_connection_get_id (connection), error->message);
1047 g_error_free (error);
1051 /* See if there's a device that is already compatible with this connection */
1052 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1053 NMDevice *candidate = iter->data;
1055 if (nm_device_check_connection_compatible (candidate, connection)) {
1056 if (nm_device_is_real (candidate)) {
1057 _LOGD (LOGD_DEVICE, "(%s) already created virtual interface name %s",
1058 nm_connection_get_id (connection), iface);
1068 /* No matching device found. Proceed creating a new one. */
1070 factory = nm_device_factory_manager_find_factory_for_connection (connection);
1072 _LOGE (LOGD_DEVICE, "(%s:%s) NetworkManager plugin for '%s' unavailable",
1073 nm_connection_get_id (connection), iface,
1074 nm_connection_get_connection_type (connection));
1078 device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, &error);
1080 _LOGW (LOGD_DEVICE, "(%s) factory can't create the device: %s",
1081 nm_connection_get_id (connection), error->message);
1082 g_error_free (error);
1086 if (!add_device (self, device, &error)) {
1087 _LOGW (LOGD_DEVICE, "(%s) can't register the device with manager: %s",
1088 nm_connection_get_id (connection), error->message);
1089 g_error_free (error);
1090 g_object_unref (device);
1094 /* Add device takes a reference that NMManager still owns, so it's
1095 * safe to unref here and still return @device.
1097 g_object_unref (device);
1100 /* Create backing resources if the device has any autoconnect connections */
1101 connections = nm_settings_get_connections (priv->settings);
1102 for (iter = connections; iter; iter = g_slist_next (iter)) {
1103 NMConnection *candidate = iter->data;
1104 NMSettingConnection *s_con;
1106 if (!nm_device_check_connection_compatible (device, candidate))
1109 s_con = nm_connection_get_setting_connection (candidate);
1111 if (!nm_setting_connection_get_autoconnect (s_con))
1114 /* Create any backing resources the device needs */
1115 if (!nm_device_create_and_realize (device, connection, parent, &error)) {
1116 _LOGW (LOGD_DEVICE, "(%s) couldn't create the device: %s",
1117 nm_connection_get_id (connection), error->message);
1118 g_error_free (error);
1119 remove_device (self, device, FALSE, TRUE);
1129 retry_connections_for_parent_device (NMManager *self, NMDevice *device)
1131 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1132 GSList *connections, *iter;
1134 g_return_if_fail (device);
1136 connections = nm_settings_get_connections (priv->settings);
1137 for (iter = connections; iter; iter = g_slist_next (iter)) {
1138 NMConnection *candidate = iter->data;
1139 gs_free_error GError *error = NULL;
1140 gs_free char *ifname = NULL;
1143 parent = find_parent_device_for_connection (self, candidate, NULL);
1144 if (parent == device) {
1145 /* Only try to activate devices that don't already exist */
1146 ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error);
1148 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
1149 connection_changed (priv->settings, candidate, self);
1154 g_slist_free (connections);
1158 connection_changed (NMSettings *settings,
1159 NMConnection *connection,
1164 if (!nm_connection_is_virtual (connection))
1167 device = system_create_virtual_device (manager, connection);
1171 /* Maybe the device that was created was needed by some other
1172 * connection's device (parent of a VLAN). Let the connections
1173 * can use the newly created device as a parent know. */
1174 retry_connections_for_parent_device (manager, device);
1178 connection_removed (NMSettings *settings,
1179 NMSettingsConnection *connection,
1183 * Do not delete existing virtual devices to keep connectivity up.
1184 * Virtual devices are reused when NetworkManager is restarted.
1189 system_unmanaged_devices_changed_cb (NMSettings *settings,
1193 NMManager *self = NM_MANAGER (user_data);
1194 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1195 const GSList *unmanaged_specs, *iter;
1197 unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
1198 for (iter = priv->devices; iter; iter = g_slist_next (iter))
1199 nm_device_set_unmanaged_by_user_config (NM_DEVICE (iter->data), unmanaged_specs);
1203 system_hostname_changed_cb (NMSettings *settings,
1207 NMManager *self = NM_MANAGER (user_data);
1208 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1211 hostname = nm_settings_get_hostname (priv->settings);
1213 /* nm_settings_get_hostname() does not return an empty hostname. */
1214 nm_assert (!hostname || *hostname);
1216 if (!hostname && !priv->hostname)
1218 if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) {
1223 /* realloc, to free possibly trailing data after NUL. */
1225 hostname = g_realloc (hostname, strlen (hostname) + 1);
1227 g_free (priv->hostname);
1228 priv->hostname = hostname;
1229 g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
1231 nm_dhcp_manager_set_default_hostname (nm_dhcp_manager_get (), priv->hostname);
1234 /*******************************************************************/
1235 /* General NMManager stuff */
1236 /*******************************************************************/
1238 /* Store value into key-file; supported types: boolean, int, string */
1240 write_value_to_state_file (const char *filename,
1250 gboolean ret = FALSE;
1252 g_return_val_if_fail (filename != NULL, FALSE);
1253 g_return_val_if_fail (group != NULL, FALSE);
1254 g_return_val_if_fail (key != NULL, FALSE);
1255 g_return_val_if_fail (value_type == G_TYPE_BOOLEAN ||
1256 value_type == G_TYPE_INT ||
1257 value_type == G_TYPE_STRING,
1260 key_file = g_key_file_new ();
1262 g_key_file_set_list_separator (key_file, ',');
1263 g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
1264 switch (value_type) {
1265 case G_TYPE_BOOLEAN:
1266 g_key_file_set_boolean (key_file, group, key, *((gboolean *) value));
1269 g_key_file_set_integer (key_file, group, key, *((gint *) value));
1272 g_key_file_set_string (key_file, group, key, *((const gchar **) value));
1276 data = g_key_file_to_data (key_file, &len, NULL);
1278 ret = g_file_set_contents (filename, data, len, error);
1281 g_key_file_free (key_file);
1287 radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
1291 enabled = rstate->user_enabled && rstate->hw_enabled;
1292 if (check_changeable)
1293 enabled &= rstate->sw_enabled;
1298 radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
1300 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1302 return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
1306 manager_update_radio_enabled (NMManager *self,
1310 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1313 /* Do nothing for radio types not yet implemented */
1317 g_object_notify (G_OBJECT (self), rstate->prop);
1319 /* Don't touch devices if asleep/networking disabled */
1320 if (manager_sleeping (self))
1323 /* enable/disable wireless devices as required */
1324 for (iter = priv->devices; iter; iter = iter->next) {
1325 NMDevice *device = NM_DEVICE (iter->data);
1327 if (nm_device_get_rfkill_type (device) == rstate->rtype) {
1328 _LOGD (LOGD_RFKILL, "(%s): setting radio %s",
1329 nm_device_get_iface (device),
1330 enabled ? "enabled" : "disabled");
1331 nm_device_set_enabled (device, enabled);
1337 update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate)
1339 switch (nm_rfkill_manager_get_rfkill_state (rfkill_mgr, rstate->rtype)) {
1340 case RFKILL_UNBLOCKED:
1341 rstate->sw_enabled = TRUE;
1342 rstate->hw_enabled = TRUE;
1344 case RFKILL_SOFT_BLOCKED:
1345 rstate->sw_enabled = FALSE;
1346 rstate->hw_enabled = TRUE;
1348 case RFKILL_HARD_BLOCKED:
1349 rstate->sw_enabled = FALSE;
1350 rstate->hw_enabled = FALSE;
1353 g_warn_if_reached ();
1359 manager_rfkill_update_one_type (NMManager *self,
1363 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1364 gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
1366 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
1367 old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1368 old_hwe = rstate->hw_enabled;
1370 /* recheck kernel rfkill state */
1371 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
1373 /* Print out all states affecting device enablement */
1375 _LOGD (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
1376 rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
1379 /* Log new killswitch state */
1380 new_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1381 if (old_rfkilled != new_rfkilled) {
1382 _LOGI (LOGD_RFKILL, "%s now %s by radio killswitch",
1384 new_rfkilled ? "enabled" : "disabled");
1387 /* Send out property changed signal for HW enabled */
1388 if (rstate->hw_enabled != old_hwe) {
1389 if (rstate->hw_prop)
1390 g_object_notify (G_OBJECT (self), rstate->hw_prop);
1393 /* And finally update the actual device radio state itself; respect the
1394 * daemon state here because this is never called from user-triggered
1395 * radio changes and we only want to ignore the daemon enabled state when
1396 * handling user radio change requests.
1398 new_enabled = radio_enabled_for_rstate (rstate, TRUE);
1399 if (new_enabled != old_enabled)
1400 manager_update_radio_enabled (self, rstate, new_enabled);
1404 nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
1406 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1409 if (rtype != RFKILL_TYPE_UNKNOWN)
1410 manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
1412 /* Otherwise sync all radio types */
1413 for (i = 0; i < RFKILL_TYPE_MAX; i++)
1414 manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
1419 device_auth_done_cb (NMAuthChain *chain,
1421 GDBusMethodInvocation *context,
1424 NMManager *self = NM_MANAGER (user_data);
1425 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1426 GError *error = NULL;
1427 NMAuthCallResult result;
1429 const char *permission;
1430 NMDeviceAuthRequestFunc callback;
1431 NMAuthSubject *subject;
1435 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
1437 permission = nm_auth_chain_get_data (chain, "requested-permission");
1438 g_assert (permission);
1439 callback = nm_auth_chain_get_data (chain, "callback");
1440 g_assert (callback);
1441 device = nm_auth_chain_get_data (chain, "device");
1444 result = nm_auth_chain_get_result (chain, permission);
1445 subject = nm_auth_chain_get_subject (chain);
1448 /* translate the auth error into a manager permission denied error */
1449 _LOGD (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
1450 error = g_error_new (NM_MANAGER_ERROR,
1451 NM_MANAGER_ERROR_PERMISSION_DENIED,
1452 "%s request failed: %s",
1453 permission, auth_error->message);
1454 } else if (result != NM_AUTH_CALL_RESULT_YES) {
1455 _LOGD (LOGD_CORE, "%s request failed: not authorized", permission);
1456 error = g_error_new (NM_MANAGER_ERROR,
1457 NM_MANAGER_ERROR_PERMISSION_DENIED,
1458 "%s request failed: not authorized",
1462 g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
1468 nm_auth_chain_get_data (chain, "user-data"));
1470 g_clear_error (&error);
1471 nm_auth_chain_unref (chain);
1475 device_auth_request_cb (NMDevice *device,
1476 GDBusMethodInvocation *context,
1477 NMConnection *connection,
1478 const char *permission,
1479 gboolean allow_interaction,
1480 NMDeviceAuthRequestFunc callback,
1484 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1485 GError *error = NULL;
1486 NMAuthSubject *subject = NULL;
1487 char *error_desc = NULL;
1490 /* Validate the caller */
1491 subject = nm_auth_subject_new_unix_process_from_context (context);
1493 error = g_error_new_literal (NM_MANAGER_ERROR,
1494 NM_MANAGER_ERROR_PERMISSION_DENIED,
1495 "Failed to get request UID.");
1499 /* Ensure the subject has permissions for this connection */
1500 if (connection && !nm_auth_is_subject_in_acl (connection,
1503 error = g_error_new_literal (NM_MANAGER_ERROR,
1504 NM_MANAGER_ERROR_PERMISSION_DENIED,
1506 g_free (error_desc);
1510 /* Validate the request */
1511 chain = nm_auth_chain_new_subject (subject, context, device_auth_done_cb, self);
1513 error = g_error_new_literal (NM_MANAGER_ERROR,
1514 NM_MANAGER_ERROR_PERMISSION_DENIED,
1515 "Unable to authenticate request.");
1519 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
1520 nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
1521 nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
1522 nm_auth_chain_set_data (chain, "callback", callback, NULL);
1523 nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
1524 nm_auth_chain_add_call (chain, permission, allow_interaction);
1528 callback (device, context, subject, error, user_data);
1530 g_clear_object (&subject);
1531 g_clear_error (&error);
1535 match_connection_filter (NMConnection *connection, gpointer user_data)
1537 if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
1540 return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
1544 * get_existing_connection:
1545 * @manager: #NMManager instance
1546 * @device: #NMDevice instance
1547 * @out_generated: (allow-none): return TRUE, if the connection was generated.
1549 * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
1550 * the device does not support assuming existing connections.
1552 static NMSettingsConnection *
1553 get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
1555 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1556 gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self);
1557 NMConnection *connection = NULL;
1558 NMSettingsConnection *matched;
1559 NMSettingsConnection *added = NULL;
1560 GError *error = NULL;
1561 NMDevice *master = NULL;
1562 int ifindex = nm_device_get_ifindex (device);
1565 *out_generated = FALSE;
1567 nm_device_capture_initial_config (device);
1570 int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex);
1572 if (master_ifindex) {
1573 master = nm_manager_get_device_by_ifindex (self, master_ifindex);
1575 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)",
1576 nm_device_get_iface (device), nm_platform_link_get_name (NM_PLATFORM_GET, master_ifindex), master_ifindex);
1579 if (!nm_device_get_act_request (master)) {
1580 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates",
1581 nm_device_get_iface (device), nm_device_get_iface (master));
1587 /* The core of the API is nm_device_generate_connection() function and
1588 * update_connection() virtual method and the convenient connection_type
1589 * class attribute. Subclasses supporting the new API must have
1590 * update_connection() implemented, otherwise nm_device_generate_connection()
1593 connection = nm_device_generate_connection (device, master);
1597 /* Now we need to compare the generated connection to each configured
1598 * connection. The comparison function is the heart of the connection
1599 * assumption implementation and it must compare the connections very
1600 * carefully to sort out various corner cases. Also, the comparison is
1601 * not entirely symmetric.
1603 * When no configured connection matches the generated connection, we keep
1604 * the generated connection instead.
1606 connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections));
1607 matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
1609 nm_device_has_carrier (device),
1610 nm_device_get_ip4_route_metric (device),
1611 nm_device_get_ip6_route_metric (device),
1612 match_connection_filter,
1615 _LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
1616 nm_device_get_iface (device),
1617 nm_settings_connection_get_id (matched));
1618 g_object_unref (connection);
1622 _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
1623 nm_device_get_iface (device),
1624 nm_connection_get_id (connection));
1626 added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
1628 nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
1629 NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
1630 NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
1633 *out_generated = TRUE;
1635 _LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
1636 nm_device_get_iface (device),
1637 nm_connection_get_id (connection),
1639 g_clear_error (&error);
1641 g_object_unref (connection);
1643 return added ? added : NULL;
1647 assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
1649 NMActiveConnection *active, *master_ac;
1650 NMAuthSubject *subject;
1651 GError *error = NULL;
1653 _LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
1654 nm_device_get_iface (device));
1656 /* Move device to DISCONNECTED to activate the connection */
1657 if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
1658 nm_device_state_changed (device,
1659 NM_DEVICE_STATE_DISCONNECTED,
1660 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1662 g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1664 subject = nm_auth_subject_new_internal ();
1665 active = _new_active_connection (self, NM_CONNECTION (connection), NULL, device, subject, &error);
1666 g_object_unref (subject);
1669 _LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
1670 nm_connection_get_path (NM_CONNECTION (connection)),
1672 g_error_free (error);
1676 /* If the device is a slave or VLAN, find the master ActiveConnection */
1678 if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
1679 nm_active_connection_set_master (active, master_ac);
1681 nm_active_connection_set_assumed (active, TRUE);
1682 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
1683 active_connection_add (self, active);
1684 nm_device_queue_activation (device, NM_ACT_REQUEST (active));
1685 g_object_unref (active);
1691 recheck_assume_connection (NMManager *self, NMDevice *device)
1693 NMSettingsConnection *connection;
1694 gboolean was_unmanaged = FALSE, success, generated = FALSE;
1695 NMDeviceState state;
1697 g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
1698 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1700 if (nm_device_get_is_nm_owned (device))
1703 if (!nm_device_get_managed (device, FALSE))
1706 state = nm_device_get_state (device);
1707 if (state > NM_DEVICE_STATE_DISCONNECTED)
1710 connection = get_existing_connection (self, device, &generated);
1712 _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
1713 nm_device_get_iface (device));
1717 if (state == NM_DEVICE_STATE_UNMANAGED) {
1718 was_unmanaged = TRUE;
1719 nm_device_state_changed (device,
1720 NM_DEVICE_STATE_UNAVAILABLE,
1721 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1724 success = assume_connection (self, device, connection);
1726 if (was_unmanaged) {
1727 nm_device_state_changed (device,
1728 NM_DEVICE_STATE_UNAVAILABLE,
1729 NM_DEVICE_STATE_REASON_CONFIG_FAILED);
1733 _LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
1734 nm_device_get_iface (device));
1736 nm_settings_connection_delete (connection, NULL, NULL);
1744 recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
1746 recheck_assume_connection (user_data, device);
1750 device_ip_iface_changed (NMDevice *device,
1754 const char *ip_iface = nm_device_get_ip_iface (device);
1757 /* Remove NMDevice objects that are actually child devices of others,
1758 * when the other device finally knows its IP interface name. For example,
1759 * remove the PPP interface that's a child of a WWAN device, since it's
1760 * not really a standalone NMDevice.
1762 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
1763 NMDevice *candidate = NM_DEVICE (iter->data);
1765 if ( candidate != device
1766 && g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
1767 && nm_device_is_real (candidate)) {
1768 remove_device (self, candidate, FALSE, FALSE);
1775 device_iface_changed (NMDevice *device,
1779 /* Virtual connections may refer to the new device name as
1780 * parent device, retry to activate them.
1782 retry_connections_for_parent_device (self, device);
1787 device_realized (NMDevice *device,
1791 /* Emit D-Bus signals */
1792 g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
1793 g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
1797 _device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
1799 g_return_if_fail (NM_IS_MANAGER (self));
1800 g_return_if_fail (NM_IS_DEVICE (device));
1802 nm_device_realize_finish (device, plink);
1804 if (!nm_device_get_managed (device, FALSE))
1807 if (recheck_assume_connection (self, device))
1810 /* if we failed to assume a connection for the managed device, but the device
1811 * is still unavailable. Set UNAVAILABLE state again, this time with NOW_MANAGED. */
1812 nm_device_state_changed (device,
1813 NM_DEVICE_STATE_UNAVAILABLE,
1814 NM_DEVICE_STATE_REASON_NOW_MANAGED);
1815 nm_device_emit_recheck_auto_activate (device);
1820 * @self: the #NMManager
1821 * @device: the #NMDevice to add
1822 * @error: (out): the #GError
1824 * If successful, this function will increase the references count of @device.
1825 * Callers should decrease the reference count.
1828 add_device (NMManager *self, NMDevice *device, GError **error)
1830 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1831 const char *iface, *type_desc;
1833 GSList *iter, *remove = NULL;
1835 const char *dbus_path;
1838 ifindex = nm_device_get_ifindex (device);
1839 if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) {
1840 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
1841 "A device with ifindex %d already exists", ifindex);
1845 /* Remove existing devices owned by the new device; eg remove ethernet
1846 * ports that are owned by a WWAN modem, since udev may announce them
1847 * before the modem is fully discovered.
1849 * FIXME: use parent/child device relationships instead of removing
1850 * the child NMDevice entirely
1852 for (iter = priv->devices; iter; iter = iter->next) {
1853 NMDevice *candidate = iter->data;
1855 iface = nm_device_get_ip_iface (candidate);
1856 if (nm_device_is_real (candidate) && nm_device_owns_iface (device, iface))
1857 remove = g_slist_prepend (remove, candidate);
1859 for (iter = remove; iter; iter = iter->next)
1860 remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
1861 g_slist_free (remove);
1863 priv->devices = g_slist_append (priv->devices, g_object_ref (device));
1865 g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
1866 G_CALLBACK (manager_device_state_changed),
1869 g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
1870 G_CALLBACK (device_auth_request_cb),
1873 g_signal_connect (device, NM_DEVICE_REMOVED,
1874 G_CALLBACK (device_removed_cb),
1877 g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
1878 G_CALLBACK (recheck_assume_connection_cb),
1881 g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
1882 G_CALLBACK (device_ip_iface_changed),
1885 g_signal_connect (device, "notify::" NM_DEVICE_IFACE,
1886 G_CALLBACK (device_iface_changed),
1889 g_signal_connect (device, "notify::" NM_DEVICE_REAL,
1890 G_CALLBACK (device_realized),
1893 if (priv->startup) {
1894 g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
1895 G_CALLBACK (device_has_pending_action_changed),
1899 /* Update global rfkill state for this device type with the device's
1900 * rfkill state, and then set this device's rfkill state based on the
1903 rtype = nm_device_get_rfkill_type (device);
1904 if (rtype != RFKILL_TYPE_UNKNOWN) {
1905 nm_manager_rfkill_update (self, rtype);
1906 nm_device_set_enabled (device, radio_enabled_for_type (self, rtype, TRUE));
1909 iface = nm_device_get_iface (device);
1911 type_desc = nm_device_get_type_desc (device);
1912 g_assert (type_desc);
1914 nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings));
1916 nm_device_set_unmanaged_flags (device,
1917 NM_UNMANAGED_SLEEPING,
1918 manager_sleeping (self));
1920 dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
1921 _LOGI (LOGD_DEVICE, "(%s): new %s device (%s)", iface, type_desc, dbus_path);
1923 nm_settings_device_added (priv->settings, device);
1924 g_signal_emit (self, signals[INTERNAL_DEVICE_ADDED], 0, device);
1925 g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
1927 for (iter = priv->devices; iter; iter = iter->next) {
1928 NMDevice *d = iter->data;
1931 nm_device_notify_new_device_added (d, device);
1934 /* Virtual connections may refer to the new device as
1935 * parent device, retry to activate them.
1937 retry_connections_for_parent_device (self, device);
1942 /*******************************************************************/
1945 factory_device_added_cb (NMDeviceFactory *factory,
1949 NMManager *self = user_data;
1950 GError *error = NULL;
1952 g_return_if_fail (NM_IS_MANAGER (self));
1954 if (nm_device_realize_start (device, NULL, NULL, &error)) {
1955 add_device (self, device, NULL);
1956 _device_realize_finish (self, device, NULL);
1958 _LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
1959 nm_device_get_iface (device), error->message);
1960 g_error_free (error);
1965 factory_component_added_cb (NMDeviceFactory *factory,
1971 g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE);
1973 for (iter = NM_MANAGER_GET_PRIVATE (user_data)->devices; iter; iter = iter->next) {
1974 if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
1981 _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
1983 NMManager *self = NM_MANAGER (user_data);
1985 g_signal_connect (factory,
1986 NM_DEVICE_FACTORY_DEVICE_ADDED,
1987 G_CALLBACK (factory_device_added_cb),
1989 g_signal_connect (factory,
1990 NM_DEVICE_FACTORY_COMPONENT_ADDED,
1991 G_CALLBACK (factory_component_added_cb),
1995 /*******************************************************************/
1998 platform_link_added (NMManager *self,
2000 const NMPlatformLink *plink)
2002 NMDeviceFactory *factory;
2003 NMDevice *device = NULL;
2004 GError *error = NULL;
2005 gboolean nm_plugin_missing = FALSE;
2008 g_return_if_fail (ifindex > 0);
2010 if (nm_manager_get_device_by_ifindex (self, ifindex))
2013 /* Let unrealized devices try to realize themselves with the link */
2014 for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
2015 NMDevice *candidate = iter->data;
2016 gboolean compatible = TRUE;
2018 if (strcmp (nm_device_get_iface (candidate), plink->name))
2021 if (nm_device_is_real (candidate)) {
2022 /* Ignore the link added event since there's already a realized
2023 * device with the link's name.
2026 } else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
2028 _device_realize_finish (self, candidate, plink);
2032 _LOGD (LOGD_DEVICE, "(%s): failed to realize from plink: '%s'",
2033 plink->name, error->message);
2034 g_clear_error (&error);
2036 /* Try next unrealized device */
2039 /* Try registered device factories */
2040 factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
2042 gboolean ignore = FALSE;
2044 device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
2047 _LOGW (LOGD_HW, "%s: factory failed to create device: %s",
2048 plink->name, error->message);
2049 g_clear_error (&error);
2055 if (device == NULL) {
2056 switch (plink->type) {
2057 case NM_LINK_TYPE_WWAN_ETHERNET:
2058 case NM_LINK_TYPE_BNEP:
2059 case NM_LINK_TYPE_OLPC_MESH:
2060 case NM_LINK_TYPE_TEAM:
2061 case NM_LINK_TYPE_WIFI:
2062 _LOGI (LOGD_HW, "(%s): '%s' plugin not available; creating generic device",
2063 plink->name, nm_link_type_to_string (plink->type));
2064 nm_plugin_missing = TRUE;
2067 device = nm_device_generic_new (plink);
2073 if (nm_plugin_missing)
2074 nm_device_set_nm_plugin_missing (device, TRUE);
2075 if (nm_device_realize_start (device, plink, NULL, &error)) {
2076 add_device (self, device, NULL);
2077 _device_realize_finish (self, device, plink);
2079 _LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
2080 plink->name, error->message);
2081 g_clear_error (&error);
2083 g_object_unref (device);
2090 } PlatformLinkCbData;
2093 _platform_link_cb_idle (PlatformLinkCbData *data)
2095 NMManager *self = data->self;
2096 const NMPlatformLink *l;
2101 g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
2103 l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
2105 NMPlatformLink pllink;
2107 pllink = *l; /* make a copy of the link instance */
2108 platform_link_added (self, data->ifindex, &pllink);
2111 GError *error = NULL;
2113 device = nm_manager_get_device_by_ifindex (self, data->ifindex);
2115 if (nm_device_is_software (device)) {
2116 /* Our software devices stick around until their connection is removed */
2117 if (!nm_device_unrealize (device, FALSE, &error)) {
2118 _LOGW (LOGD_DEVICE, "(%s): failed to unrealize: %s",
2119 nm_device_get_iface (device),
2121 g_clear_error (&error);
2122 remove_device (self, device, FALSE, TRUE);
2125 /* Hardware and external devices always get removed when their kernel link is gone */
2126 remove_device (self, device, FALSE, TRUE);
2132 g_slice_free (PlatformLinkCbData, data);
2133 return G_SOURCE_REMOVE;
2137 platform_link_cb (NMPlatform *platform,
2138 NMPObjectType obj_type,
2140 NMPlatformLink *plink,
2141 NMPlatformSignalChangeType change_type,
2144 PlatformLinkCbData *data;
2146 switch (change_type) {
2147 case NM_PLATFORM_SIGNAL_ADDED:
2148 case NM_PLATFORM_SIGNAL_REMOVED:
2149 data = g_slice_new (PlatformLinkCbData);
2150 data->self = NM_MANAGER (user_data);
2151 data->ifindex = ifindex;
2152 g_object_add_weak_pointer (G_OBJECT (data->self), (gpointer *) &data->self);
2153 g_idle_add ((GSourceFunc) _platform_link_cb_idle, data);
2161 platform_query_devices (NMManager *self)
2163 GArray *links_array;
2164 NMPlatformLink *links;
2167 links_array = nm_platform_link_get_all (NM_PLATFORM_GET);
2168 links = (NMPlatformLink *) links_array->data;
2169 for (i = 0; i < links_array->len; i++)
2170 platform_link_added (self, links[i].ifindex, &links[i]);
2172 g_array_unref (links_array);
2176 rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
2178 RfKillState udev_state,
2181 nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
2185 nm_manager_get_devices (NMManager *manager)
2187 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2189 return NM_MANAGER_GET_PRIVATE (manager)->devices;
2193 nm_manager_get_connection_device (NMManager *self,
2194 NMConnection *connection)
2196 NMActiveConnection *ac = find_ac_for_connection (self, connection);
2200 return nm_active_connection_get_device (ac);
2204 nm_manager_get_best_device_for_connection (NMManager *self,
2205 NMConnection *connection,
2206 gboolean for_user_request)
2208 const GSList *devices, *iter;
2209 NMDevice *act_device = nm_manager_get_connection_device (self, connection);
2210 NMDeviceCheckConAvailableFlags flags;
2215 flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
2217 /* Pick the first device that's compatible with the connection. */
2218 devices = nm_manager_get_devices (self);
2219 for (iter = devices; iter; iter = g_slist_next (iter)) {
2220 NMDevice *device = NM_DEVICE (iter->data);
2222 if (nm_device_check_connection_available (device, connection, flags, NULL))
2231 _get_devices (NMManager *self,
2232 GDBusMethodInvocation *context,
2233 gboolean all_devices)
2235 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2236 gs_free const char **paths = NULL;
2240 paths = g_new (const char *, g_slist_length (priv->devices) + 1);
2242 for (i = 0, iter = priv->devices; iter; iter = iter->next) {
2245 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
2247 && (all_devices || nm_device_is_real (iter->data)))
2252 g_dbus_method_invocation_return_value (context,
2253 g_variant_new ("(^ao)", (char **) paths));
2257 impl_manager_get_devices (NMManager *self,
2258 GDBusMethodInvocation *context)
2260 _get_devices (self, context, FALSE);
2264 impl_manager_get_all_devices (NMManager *self,
2265 GDBusMethodInvocation *context)
2267 _get_devices (self, context, TRUE);
2271 impl_manager_get_device_by_ip_iface (NMManager *self,
2272 GDBusMethodInvocation *context,
2276 const char *path = NULL;
2278 device = find_device_by_ip_iface (self, iface);
2280 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
2283 g_dbus_method_invocation_return_error (context,
2285 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2286 "No device found for the requested iface.");
2288 g_dbus_method_invocation_return_value (context,
2289 g_variant_new ("(o)", path));
2294 is_compatible_with_slave (NMConnection *master, NMConnection *slave)
2296 NMSettingConnection *s_con;
2298 g_return_val_if_fail (master, FALSE);
2299 g_return_val_if_fail (slave, FALSE);
2301 s_con = nm_connection_get_setting_connection (slave);
2304 return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
2309 * @self: #NMManager object
2310 * @connection: the #NMConnection to find the master connection and device for
2311 * @device: the #NMDevice, if any, which will activate @connection
2312 * @out_master_connection: on success, the master connection of @connection if
2313 * that master connection was found
2314 * @out_master_device: on success, the master device of @connection if that
2315 * master device was found
2316 * @out_master_ac: on success, the master ActiveConnection of @connection if
2317 * there already is one
2318 * @error: the error, if an error occurred
2320 * Given an #NMConnection, attempts to find its master. If @connection has
2321 * no master, this will return %TRUE and @out_master_connection and
2322 * @out_master_device will be untouched.
2324 * If @connection does have a master, then the outputs depend on what is in its
2325 * #NMSettingConnection:master property:
2327 * If "master" is the ifname of an existing #NMDevice, and that device has a
2328 * compatible master connection activated or activating on it, then
2329 * @out_master_device, @out_master_connection, and @out_master_ac will all be
2330 * set. If the device exists and is idle, only @out_master_device will be set.
2331 * If the device exists and has an incompatible connection on it, an error
2334 * If "master" is the ifname of a non-existent device, then @out_master_device
2335 * will be %NULL, and @out_master_connection will be a connection whose
2336 * activation would cause the creation of that device. @out_master_ac MAY be
2337 * set in this case as well (if the connection has started activating, but has
2338 * not yet created its device).
2340 * If "master" is the UUID of a compatible master connection, then
2341 * @out_master_connection will be the identified connection, and @out_master_device
2342 * and/or @out_master_ac will be set if the connection is currently activating.
2343 * (@out_master_device will not be set if the device exists but does not have
2344 * @out_master_connection active/activating on it.)
2346 * Returns: %TRUE if the master device and/or connection could be found or if
2347 * the connection did not require a master, %FALSE otherwise
2350 find_master (NMManager *self,
2351 NMConnection *connection,
2353 NMSettingsConnection **out_master_connection,
2354 NMDevice **out_master_device,
2355 NMActiveConnection **out_master_ac,
2358 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2359 NMSettingConnection *s_con;
2361 NMDevice *master_device = NULL;
2362 NMSettingsConnection *master_connection = NULL;
2365 s_con = nm_connection_get_setting_connection (connection);
2367 master = nm_setting_connection_get_master (s_con);
2370 return TRUE; /* success, but no master */
2372 /* Try as an interface name first */
2373 master_device = find_device_by_iface (self, master, NULL, connection);
2374 if (master_device) {
2375 if (master_device == device) {
2376 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2377 "Device cannot be its own master");
2381 master_connection = nm_device_get_settings_connection (master_device);
2382 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) {
2383 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2384 "The active connection on %s is not a valid master for '%s'",
2385 nm_device_get_iface (master_device),
2386 nm_connection_get_id (connection));
2390 /* Try master as a connection UUID */
2391 master_connection = nm_settings_get_connection_by_uuid (priv->settings, master);
2392 if (master_connection) {
2393 /* Check if the master connection is activated on some device already */
2394 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2395 NMDevice *candidate = NM_DEVICE (iter->data);
2397 if (candidate == device)
2400 if (nm_device_get_settings_connection (candidate) == master_connection) {
2401 master_device = candidate;
2408 if (out_master_connection)
2409 *out_master_connection = master_connection;
2410 if (out_master_device)
2411 *out_master_device = master_device;
2412 if (out_master_ac && master_connection)
2413 *out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection));
2415 if (master_device || master_connection)
2418 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2419 "Master connection not found or invalid");
2425 * ensure_master_active_connection:
2426 * @self: the #NMManager
2427 * @subject: the #NMAuthSubject representing the requestor of this activation
2428 * @connection: the connection that should depend on @master_connection
2429 * @device: the #NMDevice, if any, which will activate @connection
2430 * @master_connection: the master connection, or %NULL
2431 * @master_device: the master device, or %NULL
2432 * @error: the error, if an error occurred
2434 * Determines whether a given #NMConnection depends on another connection to
2435 * be activated, and if so, finds that master connection or creates it.
2437 * If @master_device and @master_connection are both set then @master_connection
2438 * MUST already be activated or activating on @master_device, and the function will
2439 * return the existing #NMActiveConnection.
2441 * If only @master_device is set, and it has an #NMActiveConnection, then the
2442 * function will return it if it is a compatible master, or an error if not. If it
2443 * doesn't have an AC, then the function will create one if a compatible master
2444 * connection exists, or return an error if not.
2446 * If only @master_connection is set, then this will try to find or create a compatible
2447 * #NMDevice, and either activate @master_connection on that device or return an error.
2449 * Returns: the master #NMActiveConnection that the caller should depend on, or
2450 * %NULL if an error occurred
2452 static NMActiveConnection *
2453 ensure_master_active_connection (NMManager *self,
2454 NMAuthSubject *subject,
2455 NMConnection *connection,
2457 NMSettingsConnection *master_connection,
2458 NMDevice *master_device,
2461 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2462 NMActiveConnection *master_ac = NULL;
2463 NMDeviceState master_state;
2466 g_assert (connection);
2467 g_assert (master_connection || master_device);
2469 /* If the master device isn't activated then we need to activate it using
2470 * compatible connection. If it's already activating we can just proceed.
2472 if (master_device) {
2473 NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device);
2475 /* If we're passed a connection and a device, we require that connection
2476 * be already activated on the device, eg returned from find_master().
2478 g_assert (!master_connection || master_connection == device_connection);
2479 if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) {
2480 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2481 "The active connection on %s is not a valid master for '%s'",
2482 nm_device_get_iface (master_device),
2483 nm_connection_get_id (connection));
2487 master_state = nm_device_get_state (master_device);
2488 if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
2489 || nm_device_is_activating (master_device)) {
2490 /* Device already using master_connection */
2491 g_assert (device_connection);
2492 return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
2495 /* If the device is disconnected, find a compatible connection and
2496 * activate it on the device.
2498 if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
2499 GSList *connections;
2501 g_assert (master_connection == NULL);
2503 /* Find a compatible connection and activate this device using it */
2504 connections = nm_manager_get_activatable_connections (self);
2505 for (iter = connections; iter; iter = g_slist_next (iter)) {
2506 NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
2508 /* Ensure eg bond/team slave and the candidate master is a
2511 if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
2514 if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2515 master_ac = nm_manager_activate_connection (self,
2522 g_prefix_error (error, "%s", "Master device activation failed: ");
2523 g_slist_free (connections);
2527 g_slist_free (connections);
2531 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2532 "No compatible connection found for master device %s.",
2533 nm_device_get_iface (master_device));
2537 /* Otherwise, the device is unmanaged, unavailable, or disconnecting */
2540 NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2541 "Master device %s unmanaged or not available for activation",
2542 nm_device_get_iface (master_device));
2543 } else if (master_connection) {
2544 gboolean found_device = FALSE;
2546 /* Find a compatible device and activate it using this connection */
2547 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2548 NMDevice *candidate = NM_DEVICE (iter->data);
2550 if (candidate == device) {
2551 /* A device obviously can't be its own master */
2555 if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
2558 found_device = TRUE;
2559 if (!nm_device_is_software (candidate)) {
2560 master_state = nm_device_get_state (candidate);
2561 if (nm_device_is_real (candidate) && master_state != NM_DEVICE_STATE_DISCONNECTED)
2565 master_ac = nm_manager_activate_connection (self,
2572 g_prefix_error (error, "%s", "Master device activation failed: ");
2578 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2579 "No compatible disconnected device found for master connection %s.",
2580 nm_settings_connection_get_uuid (master_connection));
2582 g_assert_not_reached ();
2589 * @manager: #NMManager object
2590 * @connection: the master #NMSettingsConnection to find slave connections for
2591 * @device: the master #NMDevice for the @connection
2593 * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
2594 * master, or has not any slaves, this will return %NULL.
2596 * Returns: list of slave connections for given master @connection, or %NULL
2599 find_slaves (NMManager *manager,
2600 NMSettingsConnection *connection,
2603 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
2604 GSList *all_connections, *iter;
2605 GSList *slaves = NULL;
2606 NMSettingConnection *s_con;
2609 s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
2611 master = nm_setting_connection_get_master (s_con);
2614 return NULL; /* connection is not master */
2616 /* Search through all connections, not only inactive ones, because
2617 * even if a slave was already active, it might be deactivated during
2618 * master reactivation.
2620 all_connections = nm_settings_get_connections (priv->settings);
2621 for (iter = all_connections; iter; iter = iter->next) {
2622 NMSettingsConnection *master_connection = NULL;
2623 NMDevice *master_device = NULL;
2624 NMConnection *candidate = iter->data;
2626 find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL);
2627 if ( (master_connection && master_connection == connection)
2628 || (master_device && master_device == device)) {
2629 slaves = g_slist_prepend (slaves, candidate);
2632 g_slist_free (all_connections);
2634 return g_slist_reverse (slaves);
2638 should_connect_slaves (NMConnection *connection, NMDevice *device)
2640 NMSettingConnection *s_con;
2641 NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
2642 gs_free char *value = NULL;
2644 s_con = nm_connection_get_setting_connection (connection);
2647 /* Check autoconnect-slaves property */
2648 autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con);
2649 if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT)
2652 /* Check configuration default for autoconnect-slaves property */
2653 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
2654 "connection.autoconnect-slaves", device);
2656 autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
2659 if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
2661 if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
2667 autoconnect_slaves (NMManager *self,
2668 NMSettingsConnection *master_connection,
2669 NMDevice *master_device,
2670 NMAuthSubject *subject)
2672 GError *local_err = NULL;
2673 gboolean ret = FALSE;
2675 if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
2676 GSList *slaves, *iter;
2678 iter = slaves = find_slaves (self, master_connection, master_device);
2679 ret = slaves != NULL;
2682 NMSettingsConnection *slave_connection = iter->data;
2685 _LOGD (LOGD_CORE, "will activate slave connection '%s' (%s) as a dependency for master '%s' (%s)",
2686 nm_settings_connection_get_id (slave_connection),
2687 nm_settings_connection_get_uuid (slave_connection),
2688 nm_settings_connection_get_id (master_connection),
2689 nm_settings_connection_get_uuid (master_connection));
2691 /* Schedule slave activation */
2692 nm_manager_activate_connection (self,
2695 nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
2699 _LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
2700 g_error_free (local_err);
2703 g_slist_free (slaves);
2709 _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **error)
2713 g_assert (NM_IS_VPN_CONNECTION (active));
2715 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2716 success = nm_vpn_manager_activate_connection (NM_MANAGER_GET_PRIVATE (self)->vpn_manager,
2717 NM_VPN_CONNECTION (active),
2720 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2722 nm_exported_object_unexport (NM_EXPORTED_OBJECT (active));
2727 _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
2729 NMDevice *device, *existing, *master_device = NULL;
2730 NMConnection *applied;
2731 NMSettingsConnection *connection;
2732 NMSettingsConnection *master_connection = NULL;
2733 NMConnection *existing_connection = NULL;
2734 NMActiveConnection *master_ac = NULL;
2735 NMAuthSubject *subject;
2736 char *error_desc = NULL;
2738 g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
2739 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
2740 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2742 g_assert (NM_IS_VPN_CONNECTION (active) == FALSE);
2744 connection = nm_active_connection_get_settings_connection (active);
2745 g_assert (connection);
2747 applied = nm_active_connection_get_applied_connection (active);
2749 device = nm_active_connection_get_device (active);
2750 g_return_val_if_fail (device != NULL, FALSE);
2752 /* If the device is active and its connection is not visible to the
2753 * user that's requesting this new activation, fail, since other users
2754 * should not be allowed to implicitly deactivate private connections
2755 * by activating a connection of their own.
2757 existing_connection = nm_device_get_applied_connection (device);
2758 subject = nm_active_connection_get_subject (active);
2759 if (existing_connection &&
2760 !nm_auth_is_subject_in_acl (existing_connection,
2765 NM_MANAGER_ERROR_PERMISSION_DENIED,
2766 "Private connection already active on the device: %s",
2768 g_free (error_desc);
2772 /* Final connection must be available on device */
2773 if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2774 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2775 "Connection '%s' is not available on the device %s at this time.",
2776 nm_settings_connection_get_id (connection), nm_device_get_iface (device));
2780 /* Create any backing resources the device needs */
2781 if (!nm_device_is_real (device)) {
2784 parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
2785 if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
2786 g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
2791 /* Try to find the master connection/device if the connection has a dependency */
2792 if (!find_master (self, applied, device,
2793 &master_connection, &master_device, &master_ac,
2797 /* Ensure there's a master active connection the new connection we're
2798 * activating can depend on.
2800 if (master_connection || master_device) {
2801 if (master_connection) {
2802 _LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
2803 nm_settings_connection_get_id (connection),
2804 nm_settings_connection_get_id (master_connection));
2806 if (master_device) {
2807 _LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'",
2808 nm_settings_connection_get_id (connection),
2809 nm_device_get_ip_iface (master_device));
2812 /* Ensure eg bond slave and the candidate master is a bond master */
2813 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) {
2814 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2815 "The master connection was not compatible");
2820 master_ac = ensure_master_active_connection (self,
2821 nm_active_connection_get_subject (active),
2834 nm_active_connection_set_master (active, master_ac);
2835 _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
2836 nm_settings_connection_get_id (connection),
2838 nm_exported_object_get_path (NM_EXPORTED_OBJECT (master_ac)) ?: "");
2841 /* Check slaves for master connection and possibly activate them */
2842 autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
2844 /* Disconnect the connection if connected or queued on another device */
2845 existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
2847 nm_device_steal_connection (existing, connection);
2849 /* when creating the software device, it can happen that the device is
2850 * still unmanaged by NM_UNMANAGED_PLATFORM_INIT because we didn't yet
2851 * get the udev event. At this point, we can no longer delay the activation
2852 * and force the device to be managed. */
2853 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2855 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_USER_EXPLICIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2857 g_return_val_if_fail (nm_device_get_managed (device, FALSE), FALSE);
2859 if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
2860 nm_device_state_changed (device,
2861 NM_DEVICE_STATE_UNAVAILABLE,
2862 NM_DEVICE_STATE_REASON_USER_REQUESTED);
2865 if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)
2866 && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
2867 nm_device_state_changed (device,
2868 NM_DEVICE_STATE_DISCONNECTED,
2869 NM_DEVICE_STATE_REASON_USER_REQUESTED);
2872 /* Export the new ActiveConnection to clients and start it on the device */
2873 nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2874 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2875 nm_device_queue_activation (device, NM_ACT_REQUEST (active));
2880 _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError **error)
2882 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2883 gboolean success = FALSE;
2885 /* Ensure activation request is still valid, eg that its device hasn't gone
2886 * away or that some other dependency has not failed.
2888 if (nm_active_connection_get_state (active) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
2889 g_set_error_literal (error,
2891 NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2892 "Activation failed because dependencies failed.");
2896 if (NM_IS_VPN_CONNECTION (active))
2897 success = _internal_activate_vpn (self, active, error);
2899 success = _internal_activate_device (self, active, error);
2902 /* Force an update of the Manager's activating-connection property.
2903 * The device changes state before the AC gets exported, which causes
2904 * the manager's 'activating-connection' property to be NULL since the
2905 * AC only gets a D-Bus path when it's exported. So now that the AC
2906 * is exported, make sure the manager's activating-connection property
2909 active_connection_add (self, active);
2910 policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
2916 static NMActiveConnection *
2917 _new_vpn_active_connection (NMManager *self,
2918 NMSettingsConnection *settings_connection,
2919 const char *specific_object,
2920 NMAuthSubject *subject,
2923 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2924 NMActiveConnection *parent = NULL;
2925 NMDevice *device = NULL;
2927 g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
2929 if (specific_object) {
2930 /* Find the specific connection the client requested we use */
2931 parent = active_connection_get_by_path (self, specific_object);
2933 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
2934 "Base connection for VPN connection not active.");
2938 parent = priv->primary_connection;
2941 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2942 "Could not find source connection.");
2946 device = nm_active_connection_get_device (parent);
2948 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2949 "Source connection had no active device.");
2953 return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
2955 nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)),
2959 static NMActiveConnection *
2960 _new_active_connection (NMManager *self,
2961 NMConnection *connection,
2962 const char *specific_object,
2964 NMAuthSubject *subject,
2967 NMSettingsConnection *settings_connection = NULL;
2968 NMActiveConnection *existing_ac;
2971 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
2972 g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
2974 /* Can't create new AC for already-active connection */
2975 existing_ac = find_ac_for_connection (self, connection);
2976 if (NM_IS_VPN_CONNECTION (existing_ac)) {
2977 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
2978 "Connection '%s' is already active",
2979 nm_connection_get_id (connection));
2983 /* Normalize the specific object */
2984 if (specific_object && g_strcmp0 (specific_object, "/") == 0)
2985 specific_object = NULL;
2987 is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME);
2989 if (NM_IS_SETTINGS_CONNECTION (connection))
2990 settings_connection = (NMSettingsConnection *) connection;
2993 return _new_vpn_active_connection (self,
2994 settings_connection,
3000 return (NMActiveConnection *) nm_act_request_new (settings_connection,
3007 _internal_activation_failed (NMManager *self,
3008 NMActiveConnection *active,
3009 const char *error_desc)
3011 _LOGD (LOGD_CORE, "Failed to activate '%s': %s",
3012 nm_active_connection_get_settings_connection_id (active),
3015 if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
3016 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
3017 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
3022 _internal_activation_auth_done (NMActiveConnection *active,
3024 const char *error_desc,
3025 gpointer user_data1,
3026 gpointer user_data2)
3028 NMManager *self = user_data1;
3029 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3030 GError *error = NULL;
3032 priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
3035 if (_internal_activate_generic (self, active, &error)) {
3036 g_object_unref (active);
3041 g_assert (error_desc || error);
3042 _internal_activation_failed (self, active, error_desc ? error_desc : error->message);
3043 g_object_unref (active);
3044 g_clear_error (&error);
3048 * nm_manager_activate_connection():
3049 * @self: the #NMManager
3050 * @connection: the #NMSettingsConnection to activate on @device
3051 * @specific_object: the specific object path, if any, for the activation
3052 * @device: the #NMDevice to activate @connection on
3053 * @subject: the subject which requested activation
3054 * @error: return location for an error
3056 * Begins a new internally-initiated activation of @connection on @device.
3057 * @subject should be the subject of the activation that triggered this
3058 * one, or if this is an autoconnect request, a new internal subject.
3059 * The returned #NMActiveConnection is owned by the Manager and should be
3060 * referenced by the caller if the caller continues to use it.
3062 * Returns: (transfer none): the new #NMActiveConnection that tracks
3063 * activation of @connection on @device
3065 NMActiveConnection *
3066 nm_manager_activate_connection (NMManager *self,
3067 NMSettingsConnection *connection,
3068 const char *specific_object,
3070 NMAuthSubject *subject,
3073 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3074 NMActiveConnection *active;
3075 char *error_desc = NULL;
3078 g_return_val_if_fail (self != NULL, NULL);
3079 g_return_val_if_fail (connection != NULL, NULL);
3080 g_return_val_if_fail (error != NULL, NULL);
3081 g_return_val_if_fail (*error == NULL, NULL);
3083 /* Ensure the subject has permissions for this connection */
3084 if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3087 g_set_error_literal (error,
3089 NM_MANAGER_ERROR_PERMISSION_DENIED,
3091 g_free (error_desc);
3095 /* Look for a active connection that's equivalent and is already pending authorization
3096 * and eventual activation. This is used to de-duplicate concurrent activations which would
3097 * otherwise race and cause the device to disconnect and reconnect repeatedly.
3098 * In particular, this allows the master and multiple slaves to concurrently auto-activate
3099 * while all the slaves would use the same active-connection. */
3100 for (iter = priv->authorizing_connections; iter; iter = g_slist_next (iter)) {
3101 active = iter->data;
3103 if ( connection == nm_active_connection_get_settings_connection (active)
3104 && g_strcmp0 (nm_active_connection_get_specific_object (active), specific_object) == 0
3105 && nm_active_connection_get_device (active) == device
3106 && nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
3107 && nm_auth_subject_is_internal (subject))
3111 active = _new_active_connection (self,
3112 NM_CONNECTION (connection),
3118 priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
3119 nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL);
3125 * validate_activation_request:
3126 * @self: the #NMManager
3127 * @context: the D-Bus context of the requestor
3128 * @connection: the partial or complete #NMConnection to be activated
3129 * @device_path: the object path of the device to be activated, or "/"
3130 * @out_device: on successful reutrn, the #NMDevice to be activated with @connection
3131 * @out_vpn: on successful return, %TRUE if @connection is a VPN connection
3132 * @error: location to store an error on failure
3134 * Performs basic validation on an activation request, including ensuring that
3135 * the requestor is a valid Unix process, is not disallowed in @connection
3136 * permissions, and that a device exists that can activate @connection.
3138 * Returns: on success, the #NMAuthSubject representing the requestor, or
3141 static NMAuthSubject *
3142 validate_activation_request (NMManager *self,
3143 GDBusMethodInvocation *context,
3144 NMConnection *connection,
3145 const char *device_path,
3146 NMDevice **out_device,
3150 NMDevice *device = NULL;
3151 gboolean vpn = FALSE;
3152 NMAuthSubject *subject = NULL;
3153 char *error_desc = NULL;
3155 g_assert (connection);
3156 g_assert (out_device);
3159 /* Validate the caller */
3160 subject = nm_auth_subject_new_unix_process_from_context (context);
3162 g_set_error_literal (error,
3164 NM_MANAGER_ERROR_PERMISSION_DENIED,
3165 "Failed to get request UID.");
3169 /* Ensure the subject has permissions for this connection */
3170 if (!nm_auth_is_subject_in_acl (connection,
3173 g_set_error_literal (error,
3175 NM_MANAGER_ERROR_PERMISSION_DENIED,
3177 g_free (error_desc);
3181 /* Not implemented yet, we want to fail early */
3182 if ( nm_connection_get_setting_connection (connection)
3183 && nm_connection_get_setting_ip6_config (connection)
3184 && !strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG),
3185 NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
3186 g_set_error_literal (error,
3188 NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
3189 "Sharing IPv6 connections is not supported yet.");
3193 /* Check whether it's a VPN or not */
3194 if ( nm_connection_get_setting_vpn (connection)
3195 || nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME))
3198 /* Normalize device path */
3199 if (device_path && g_strcmp0 (device_path, "/") == 0)
3202 /* And validate it */
3204 device = nm_manager_get_device_by_path (self, device_path);
3206 g_set_error_literal (error,
3208 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3209 "Device not found");
3213 device = nm_manager_get_best_device_for_connection (self, connection, TRUE);
3215 if (!device && !vpn) {
3216 gboolean is_software = nm_connection_is_virtual (connection);
3218 /* VPN and software-device connections don't need a device yet */
3220 g_set_error_literal (error,
3222 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3223 "No suitable device found for this connection.");
3230 /* Look for an existing device with the connection's interface name */
3231 iface = nm_manager_get_connection_iface (self, connection, NULL, error);
3235 device = find_device_by_iface (self, iface, connection, NULL);
3240 if ((!vpn || device_path) && !device) {
3241 g_set_error_literal (error,
3243 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3244 "Failed to find a compatible device for this connection");
3248 *out_device = device;
3253 g_object_unref (subject);
3257 /***********************************************************************/
3260 _activation_auth_done (NMActiveConnection *active,
3262 const char *error_desc,
3263 gpointer user_data1,
3264 gpointer user_data2)
3266 NMManager *self = user_data1;
3267 GDBusMethodInvocation *context = user_data2;
3268 GError *error = NULL;
3269 NMAuthSubject *subject;
3270 NMSettingsConnection *connection;
3272 subject = nm_active_connection_get_subject (active);
3273 connection = nm_active_connection_get_settings_connection (active);
3276 if (_internal_activate_generic (self, active, &error)) {
3277 g_dbus_method_invocation_return_value (context,
3278 g_variant_new ("(o)",
3279 nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3280 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE,
3282 g_object_unref (active);
3286 error = g_error_new_literal (NM_MANAGER_ERROR,
3287 NM_MANAGER_ERROR_PERMISSION_DENIED,
3292 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3293 subject, error->message);
3294 _internal_activation_failed (self, active, error->message);
3296 g_object_unref (active);
3297 g_dbus_method_invocation_take_error (context, error);
3301 impl_manager_activate_connection (NMManager *self,
3302 GDBusMethodInvocation *context,
3303 const char *connection_path,
3304 const char *device_path,
3305 const char *specific_object_path)
3307 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3308 NMActiveConnection *active = NULL;
3309 NMAuthSubject *subject = NULL;
3310 NMSettingsConnection *connection = NULL;
3311 NMDevice *device = NULL;
3312 gboolean is_vpn = FALSE;
3313 GError *error = NULL;
3315 /* Normalize object paths */
3316 if (g_strcmp0 (connection_path, "/") == 0)
3317 connection_path = NULL;
3318 if (g_strcmp0 (specific_object_path, "/") == 0)
3319 specific_object_path = NULL;
3320 if (g_strcmp0 (device_path, "/") == 0)
3323 /* If the connection path is given and valid, that connection is activated.
3324 * Otherwise the "best" connection for the device is chosen and activated,
3325 * regardless of whether that connection is autoconnect-enabled or not
3326 * (since this is an explicit request, not an auto-activation request).
3328 if (!connection_path) {
3329 GPtrArray *available;
3330 guint64 best_timestamp = 0;
3333 /* If no connection is given, find a suitable connection for the given device path */
3335 error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3336 "Only devices may be activated without a specifying a connection");
3339 device = nm_manager_get_device_by_path (self, device_path);
3341 error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3342 "Cannot activate unknown device %s", device_path);
3346 available = nm_device_get_available_connections (device, specific_object_path);
3347 for (i = 0; available && i < available->len; i++) {
3348 NMSettingsConnection *candidate = g_ptr_array_index (available, i);
3349 guint64 candidate_timestamp = 0;
3351 nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
3352 if (!connection_path || (candidate_timestamp > best_timestamp)) {
3353 connection_path = nm_connection_get_path (NM_CONNECTION (candidate));
3354 best_timestamp = candidate_timestamp;
3359 g_ptr_array_free (available, TRUE);
3361 if (!connection_path) {
3362 error = g_error_new_literal (NM_MANAGER_ERROR,
3363 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3364 "The device has no connections available.");
3369 g_assert (connection_path);
3370 connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
3372 error = g_error_new_literal (NM_MANAGER_ERROR,
3373 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3374 "Connection could not be found.");
3378 subject = validate_activation_request (self,
3380 NM_CONNECTION (connection),
3388 active = _new_active_connection (self,
3389 NM_CONNECTION (connection),
3390 specific_object_path,
3397 nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context);
3398 g_clear_object (&subject);
3403 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3404 subject, error->message);
3406 g_clear_object (&active);
3407 g_clear_object (&subject);
3410 g_dbus_method_invocation_take_error (context, error);
3413 /***********************************************************************/
3417 NMActiveConnection *active;
3418 } AddAndActivateInfo;
3421 activation_add_done (NMSettings *settings,
3422 NMSettingsConnection *new_connection,
3424 GDBusMethodInvocation *context,
3425 NMAuthSubject *subject,
3428 AddAndActivateInfo *info = user_data;
3430 gs_unref_object NMActiveConnection *active = NULL;
3431 GError *local = NULL;
3433 self = info->manager;
3434 active = info->active;
3435 g_slice_free (AddAndActivateInfo, info);
3438 nm_active_connection_set_settings_connection (active, new_connection);
3440 if (_internal_activate_generic (self, active, &local)) {
3441 nm_settings_connection_commit_changes (new_connection,
3442 NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
3444 g_dbus_method_invocation_return_value (
3446 g_variant_new ("(oo)",
3447 nm_connection_get_path (NM_CONNECTION (new_connection)),
3448 nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3449 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3450 nm_active_connection_get_settings_connection (active),
3452 nm_active_connection_get_subject (active),
3460 _internal_activation_failed (self, active, error->message);
3461 nm_settings_connection_delete (new_connection, NULL, NULL);
3462 g_dbus_method_invocation_return_gerror (context, error);
3463 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3466 nm_active_connection_get_subject (active),
3468 g_clear_error (&local);
3472 _add_and_activate_auth_done (NMActiveConnection *active,
3474 const char *error_desc,
3475 gpointer user_data1,
3476 gpointer user_data2)
3478 NMManager *self = user_data1;
3479 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3480 GDBusMethodInvocation *context = user_data2;
3481 AddAndActivateInfo *info;
3482 GError *error = NULL;
3485 NMConnection *connection;
3487 connection = g_object_steal_data (G_OBJECT (active),
3488 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE);
3490 info = g_slice_new (AddAndActivateInfo);
3491 info->manager = self;
3492 info->active = g_object_ref (active);
3494 /* Basic sender auth checks performed; try to add the connection */
3495 nm_settings_add_connection_dbus (priv->settings,
3499 activation_add_done,
3501 g_object_unref (connection);
3503 g_assert (error_desc);
3504 error = g_error_new_literal (NM_MANAGER_ERROR,
3505 NM_MANAGER_ERROR_PERMISSION_DENIED,
3507 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3510 nm_active_connection_get_subject (active),
3512 g_dbus_method_invocation_take_error (context, error);
3515 g_object_unref (active);
3519 impl_manager_add_and_activate_connection (NMManager *self,
3520 GDBusMethodInvocation *context,
3522 const char *device_path,
3523 const char *specific_object_path)
3525 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3526 NMConnection *connection = NULL;
3527 GSList *all_connections = NULL;
3528 NMActiveConnection *active = NULL;
3529 NMAuthSubject *subject = NULL;
3530 GError *error = NULL;
3531 NMDevice *device = NULL;
3532 gboolean vpn = FALSE;
3534 /* Normalize object paths */
3535 if (g_strcmp0 (specific_object_path, "/") == 0)
3536 specific_object_path = NULL;
3537 if (g_strcmp0 (device_path, "/") == 0)
3540 /* Try to create a new connection with the given settings.
3541 * We allow empty settings for AddAndActivateConnection(). In that case,
3542 * the connection will be completed in nm_utils_complete_generic() or
3543 * nm_device_complete_connection() below. Just make sure we don't expect
3544 * specific data being in the connection till then (especially in
3545 * validate_activation_request()).
3547 connection = nm_simple_connection_new ();
3548 if (settings && g_variant_n_children (settings))
3549 nm_connection_replace_settings (connection, settings, NULL);
3551 subject = validate_activation_request (self,
3561 all_connections = nm_settings_get_connections (priv->settings);
3563 /* Try to fill the VPN's connection setting and name at least */
3564 if (!nm_connection_get_setting_vpn (connection)) {
3565 error = g_error_new_literal (NM_CONNECTION_ERROR,
3566 NM_CONNECTION_ERROR_MISSING_SETTING,
3567 "VPN connections require a 'vpn' setting");
3568 g_prefix_error (&error, "%s: ", NM_SETTING_VPN_SETTING_NAME);
3572 nm_utils_complete_generic (NM_PLATFORM_GET,
3574 NM_SETTING_VPN_SETTING_NAME,
3577 _("VPN connection"),
3579 FALSE); /* No IPv6 by default for now */
3581 /* Let each device subclass complete the connection */
3582 if (!nm_device_complete_connection (device,
3584 specific_object_path,
3589 g_slist_free (all_connections);
3590 all_connections = NULL;
3592 active = _new_active_connection (self,
3594 specific_object_path,
3601 g_object_set_data_full (G_OBJECT (active),
3602 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE,
3606 nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context);
3607 g_object_unref (subject);
3611 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, subject, error->message);
3612 g_clear_object (&connection);
3613 g_slist_free (all_connections);
3614 g_clear_object (&subject);
3615 g_clear_object (&active);
3618 g_dbus_method_invocation_take_error (context, error);
3621 /***********************************************************************/
3624 nm_manager_deactivate_connection (NMManager *manager,
3625 const char *connection_path,
3626 NMDeviceStateReason reason,
3629 NMActiveConnection *active;
3630 gboolean success = FALSE;
3632 active = active_connection_get_by_path (manager, connection_path);
3634 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3635 "The connection was not active.");
3639 if (NM_IS_VPN_CONNECTION (active)) {
3640 NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
3642 if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
3643 vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
3644 if (nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE))
3647 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3648 "The VPN connection was not active.");
3650 g_assert (NM_IS_ACT_REQUEST (active));
3651 nm_device_state_changed (nm_active_connection_get_device (active),
3652 NM_DEVICE_STATE_DEACTIVATING,
3658 g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
3664 deactivate_net_auth_done_cb (NMAuthChain *chain,
3666 GDBusMethodInvocation *context,
3669 NMManager *self = NM_MANAGER (user_data);
3670 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3671 GError *error = NULL;
3672 NMAuthCallResult result;
3673 NMActiveConnection *active;
3678 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3680 path = nm_auth_chain_get_data (chain, "path");
3681 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3684 _LOGD (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
3685 error = g_error_new (NM_MANAGER_ERROR,
3686 NM_MANAGER_ERROR_PERMISSION_DENIED,
3687 "Deactivate request failed: %s",
3688 auth_error->message);
3689 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3690 error = g_error_new_literal (NM_MANAGER_ERROR,
3691 NM_MANAGER_ERROR_PERMISSION_DENIED,
3692 "Not authorized to deactivate connections");
3694 /* success; deactivation allowed */
3695 if (!nm_manager_deactivate_connection (self,
3697 NM_DEVICE_STATE_REASON_USER_REQUESTED,
3702 active = active_connection_get_by_path (self, path);
3704 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
3705 nm_active_connection_get_settings_connection (active),
3707 nm_auth_chain_get_subject (chain),
3708 error ? error->message : NULL);
3712 g_dbus_method_invocation_take_error (context, error);
3714 g_dbus_method_invocation_return_value (context, NULL);
3716 nm_auth_chain_unref (chain);
3720 impl_manager_deactivate_connection (NMManager *self,
3721 GDBusMethodInvocation *context,
3722 const char *active_path)
3724 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3725 NMActiveConnection *ac;
3726 NMSettingsConnection *connection = NULL;
3727 GError *error = NULL;
3728 NMAuthSubject *subject = NULL;
3730 char *error_desc = NULL;
3732 /* Find the connection by its object path */
3733 ac = active_connection_get_by_path (self, active_path);
3735 connection = nm_active_connection_get_settings_connection (ac);
3738 error = g_error_new_literal (NM_MANAGER_ERROR,
3739 NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3740 "The connection was not active.");
3744 /* Validate the caller */
3745 subject = nm_auth_subject_new_unix_process_from_context (context);
3747 error = g_error_new_literal (NM_MANAGER_ERROR,
3748 NM_MANAGER_ERROR_PERMISSION_DENIED,
3749 "Failed to get request UID.");
3753 /* Ensure the subject has permissions for this connection */
3754 if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3757 error = g_error_new_literal (NM_MANAGER_ERROR,
3758 NM_MANAGER_ERROR_PERMISSION_DENIED,
3760 g_free (error_desc);
3764 /* Validate the user request */
3765 chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self);
3767 error = g_error_new_literal (NM_MANAGER_ERROR,
3768 NM_MANAGER_ERROR_PERMISSION_DENIED,
3769 "Unable to authenticate request.");
3773 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3774 nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
3775 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
3780 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE,
3781 subject, error->message);
3783 g_dbus_method_invocation_take_error (context, error);
3785 g_clear_object (&subject);
3789 device_is_wake_on_lan (NMDevice *device)
3791 return nm_platform_link_get_wake_on_lan (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device));
3795 do_sleep_wake (NMManager *self, gboolean sleeping_changed)
3797 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3798 gboolean suspending, waking_from_suspend;
3801 suspending = sleeping_changed && priv->sleeping;
3802 waking_from_suspend = sleeping_changed && !priv->sleeping;
3804 if (manager_sleeping (self)) {
3805 _LOGI (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling");
3807 /* FIXME: are there still hardware devices that need to be disabled around
3810 for (iter = priv->devices; iter; iter = iter->next) {
3811 NMDevice *device = iter->data;
3813 /* FIXME: shouldn't we be unmanaging software devices if !suspending? */
3814 if (nm_device_is_software (device))
3816 /* Wake-on-LAN devices will be taken down post-suspend rather than pre- */
3817 if (suspending && device_is_wake_on_lan (device))
3820 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3823 _LOGI (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling");
3825 if (waking_from_suspend) {
3826 /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this
3827 * but for now it's the only way to make sure we re-check their connectivity.
3829 for (iter = priv->devices; iter; iter = iter->next) {
3830 NMDevice *device = iter->data;
3832 if (nm_device_is_software (device))
3834 if (device_is_wake_on_lan (device))
3835 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3839 /* Ensure rfkill state is up-to-date since we don't respond to state
3840 * changes during sleep.
3842 nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
3844 /* Re-manage managed devices */
3845 for (iter = priv->devices; iter; iter = iter->next) {
3846 NMDevice *device = NM_DEVICE (iter->data);
3849 if (nm_device_is_software (device))
3852 /* enable/disable wireless devices since that we don't respond
3853 * to killswitch changes during sleep.
3855 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
3856 RadioState *rstate = &priv->radio_states[i];
3857 gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
3860 _LOGD (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)",
3861 enabled ? "enabling" : "disabling",
3862 rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled);
3865 if (nm_device_get_rfkill_type (device) == rstate->rtype)
3866 nm_device_set_enabled (device, enabled);
3869 nm_device_set_autoconnect (device, TRUE);
3871 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
3875 nm_manager_update_state (self);
3879 _internal_sleep (NMManager *self, gboolean do_sleep)
3881 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3883 if (priv->sleeping == do_sleep)
3886 _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
3887 do_sleep ? "sleep" : "wake",
3888 priv->sleeping ? "yes" : "no",
3889 priv->net_enabled ? "yes" : "no");
3891 priv->sleeping = do_sleep;
3893 do_sleep_wake (self, TRUE);
3895 g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
3900 sleep_auth_done_cb (NMAuthChain *chain,
3902 GDBusMethodInvocation *context,
3905 NMManager *self = NM_MANAGER (user_data);
3906 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3908 NMAuthCallResult result;
3911 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3913 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
3915 _LOGD (LOGD_SUSPEND, "Sleep/wake request failed: %s", error->message);
3916 ret_error = g_error_new (NM_MANAGER_ERROR,
3917 NM_MANAGER_ERROR_PERMISSION_DENIED,
3918 "Sleep/wake request failed: %s",
3920 g_dbus_method_invocation_take_error (context, ret_error);
3921 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3922 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
3923 NM_MANAGER_ERROR_PERMISSION_DENIED,
3924 "Not authorized to sleep/wake");
3925 g_dbus_method_invocation_take_error (context, ret_error);
3928 do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
3929 _internal_sleep (self, do_sleep);
3930 g_dbus_method_invocation_return_value (context, NULL);
3933 nm_auth_chain_unref (chain);
3938 impl_manager_sleep (NMManager *self,
3939 GDBusMethodInvocation *context,
3942 NMManagerPrivate *priv;
3943 GError *error = NULL;
3944 gs_unref_object NMAuthSubject *subject = NULL;
3947 const char *error_desc = NULL;
3950 g_return_if_fail (NM_IS_MANAGER (self));
3952 priv = NM_MANAGER_GET_PRIVATE (self);
3953 subject = nm_auth_subject_new_unix_process_from_context (context);
3955 if (priv->sleeping == do_sleep) {
3956 error = g_error_new (NM_MANAGER_ERROR,
3957 NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
3958 "Already %s", do_sleep ? "asleep" : "awake");
3959 nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", FALSE, subject,
3961 g_dbus_method_invocation_take_error (context, error);
3965 /* Unconditionally allow the request. Previously it was polkit protected
3966 * but unfortunately that doesn't work for short-lived processes like
3967 * pm-utils. It uses dbus-send without --print-reply, which quits
3968 * immediately after sending the request, and NM is unable to obtain the
3969 * sender's UID as dbus-send has already dropped off the bus. Thus NM
3970 * fails the request. Instead, don't validate the request, but rely on
3971 * D-Bus permissions to restrict the call to root.
3973 _internal_sleep (self, do_sleep);
3974 nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", TRUE, subject, NULL);
3975 g_dbus_method_invocation_return_value (context, NULL);
3979 chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
3981 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3982 nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
3983 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
3985 error = g_error_new_literal (NM_MANAGER_ERROR,
3986 NM_MANAGER_ERROR_PERMISSION_DENIED,
3988 g_dbus_method_invocation_take_error (context, error);
3994 sleeping_cb (NMSleepMonitor *monitor, gpointer user_data)
3996 nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
3997 _internal_sleep (NM_MANAGER (user_data), TRUE);
4001 resuming_cb (NMSleepMonitor *monitor, gpointer user_data)
4003 nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
4004 _internal_sleep (NM_MANAGER (user_data), FALSE);
4008 _internal_enable (NMManager *self, gboolean enable)
4010 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4013 /* Update "NetworkingEnabled" key in state file */
4014 if (priv->state_file) {
4015 if (!write_value_to_state_file (priv->state_file,
4016 "main", "NetworkingEnabled",
4017 G_TYPE_BOOLEAN, (gpointer) &enable,
4019 /* Not a hard error */
4020 _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s",
4026 _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
4027 enable ? "enable" : "disable",
4028 priv->sleeping ? "yes" : "no",
4029 priv->net_enabled ? "yes" : "no");
4031 priv->net_enabled = enable;
4033 do_sleep_wake (self, FALSE);
4035 g_object_notify (G_OBJECT (self), NM_MANAGER_NETWORKING_ENABLED);
4039 enable_net_done_cb (NMAuthChain *chain,
4041 GDBusMethodInvocation *context,
4044 NMManager *self = NM_MANAGER (user_data);
4045 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4046 GError *ret_error = NULL;
4047 NMAuthCallResult result;
4049 NMAuthSubject *subject;
4053 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4054 enable = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enable"));
4055 subject = nm_auth_chain_get_subject (chain);
4057 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4059 _LOGD (LOGD_CORE, "Enable request failed: %s", error->message);
4060 ret_error = g_error_new (NM_MANAGER_ERROR,
4061 NM_MANAGER_ERROR_PERMISSION_DENIED,
4062 "Enable request failed: %s",
4064 } else if (result != NM_AUTH_CALL_RESULT_YES) {
4065 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
4066 NM_MANAGER_ERROR_PERMISSION_DENIED,
4067 "Not authorized to enable/disable networking");
4070 _internal_enable (self, enable);
4071 g_dbus_method_invocation_return_value (context, NULL);
4072 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", TRUE,
4077 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", FALSE,
4078 subject, ret_error->message);
4079 g_dbus_method_invocation_take_error (context, ret_error);
4082 nm_auth_chain_unref (chain);
4086 impl_manager_enable (NMManager *self,
4087 GDBusMethodInvocation *context,
4090 NMManagerPrivate *priv;
4092 GError *error = NULL;
4094 g_return_if_fail (NM_IS_MANAGER (self));
4096 priv = NM_MANAGER_GET_PRIVATE (self);
4098 if (priv->net_enabled == enable) {
4099 error = g_error_new (NM_MANAGER_ERROR,
4100 NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
4101 "Already %s", enable ? "enabled" : "disabled");
4105 chain = nm_auth_chain_new_context (context, enable_net_done_cb, self);
4107 error = g_error_new_literal (NM_MANAGER_ERROR,
4108 NM_MANAGER_ERROR_PERMISSION_DENIED,
4109 "Unable to authenticate request.");
4113 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4114 nm_auth_chain_set_data (chain, "enable", GUINT_TO_POINTER (enable), NULL);
4115 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, TRUE);
4119 g_dbus_method_invocation_take_error (context, error);
4125 get_perm_add_result (NMAuthChain *chain, GVariantBuilder *results, const char *permission)
4127 NMAuthCallResult result;
4129 result = nm_auth_chain_get_result (chain, permission);
4130 if (result == NM_AUTH_CALL_RESULT_YES)
4131 g_variant_builder_add (results, "{ss}", permission, "yes");
4132 else if (result == NM_AUTH_CALL_RESULT_NO)
4133 g_variant_builder_add (results, "{ss}", permission, "no");
4134 else if (result == NM_AUTH_CALL_RESULT_AUTH)
4135 g_variant_builder_add (results, "{ss}", permission, "auth");
4137 nm_log_dbg (LOGD_CORE, "unknown auth chain result %d", result);
4142 get_permissions_done_cb (NMAuthChain *chain,
4144 GDBusMethodInvocation *context,
4147 NMManager *self = NM_MANAGER (user_data);
4148 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4150 GVariantBuilder results;
4154 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4156 _LOGD (LOGD_CORE, "Permissions request failed: %s", error->message);
4157 ret_error = g_error_new (NM_MANAGER_ERROR,
4158 NM_MANAGER_ERROR_PERMISSION_DENIED,
4159 "Permissions request failed: %s",
4161 g_dbus_method_invocation_take_error (context, ret_error);
4163 g_variant_builder_init (&results, G_VARIANT_TYPE ("a{ss}"));
4165 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4166 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SLEEP_WAKE);
4167 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
4168 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
4169 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
4170 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4171 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
4172 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
4173 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
4174 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
4175 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
4177 g_dbus_method_invocation_return_value (context,
4178 g_variant_new ("(a{ss})", &results));
4181 nm_auth_chain_unref (chain);
4185 impl_manager_get_permissions (NMManager *self,
4186 GDBusMethodInvocation *context)
4188 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4190 GError *error = NULL;
4192 chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self);
4194 error = g_error_new_literal (NM_MANAGER_ERROR,
4195 NM_MANAGER_ERROR_PERMISSION_DENIED,
4196 "Unable to authenticate request.");
4197 g_dbus_method_invocation_take_error (context, error);
4201 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4202 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
4203 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
4204 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
4205 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
4206 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
4207 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
4208 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
4209 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
4210 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
4211 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
4212 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
4216 impl_manager_get_state (NMManager *self,
4217 GDBusMethodInvocation *context)
4219 nm_manager_update_state (self);
4220 g_dbus_method_invocation_return_value (context,
4221 g_variant_new ("(u)", NM_MANAGER_GET_PRIVATE (self)->state));
4225 impl_manager_set_logging (NMManager *self,
4226 GDBusMethodInvocation *context,
4228 const char *domains)
4230 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4231 GError *error = NULL;
4232 gulong caller_uid = G_MAXULONG;
4234 if (!nm_bus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) {
4235 error = g_error_new_literal (NM_MANAGER_ERROR,
4236 NM_MANAGER_ERROR_PERMISSION_DENIED,
4237 "Failed to get request UID.");
4241 if (0 != caller_uid) {
4242 error = g_error_new_literal (NM_MANAGER_ERROR,
4243 NM_MANAGER_ERROR_PERMISSION_DENIED,
4244 "Permission denied");
4248 if (nm_logging_setup (level, domains, NULL, &error)) {
4249 _LOGI (LOGD_CORE, "logging: level '%s' domains '%s'",
4250 nm_logging_level_to_string (), nm_logging_domains_to_string ());
4255 g_dbus_method_invocation_take_error (context, error);
4257 g_dbus_method_invocation_return_value (context, NULL);
4261 impl_manager_get_logging (NMManager *manager,
4262 GDBusMethodInvocation *context)
4264 g_dbus_method_invocation_return_value (context,
4265 g_variant_new ("(ss)",
4266 nm_logging_level_to_string (),
4267 nm_logging_domains_to_string ()));
4271 connectivity_check_done (GObject *object,
4272 GAsyncResult *result,
4275 GDBusMethodInvocation *context = user_data;
4276 NMConnectivityState state;
4277 GError *error = NULL;
4279 state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
4281 g_dbus_method_invocation_take_error (context, error);
4283 g_dbus_method_invocation_return_value (context,
4284 g_variant_new ("(u)", state));
4290 check_connectivity_auth_done_cb (NMAuthChain *chain,
4292 GDBusMethodInvocation *context,
4295 NMManager *self = NM_MANAGER (user_data);
4296 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4297 GError *error = NULL;
4298 NMAuthCallResult result;
4300 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4302 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4305 _LOGD (LOGD_CORE, "CheckConnectivity request failed: %s", auth_error->message);
4306 error = g_error_new (NM_MANAGER_ERROR,
4307 NM_MANAGER_ERROR_PERMISSION_DENIED,
4308 "Connectivity check request failed: %s",
4309 auth_error->message);
4310 } else if (result != NM_AUTH_CALL_RESULT_YES) {
4311 error = g_error_new_literal (NM_MANAGER_ERROR,
4312 NM_MANAGER_ERROR_PERMISSION_DENIED,
4313 "Not authorized to recheck connectivity");
4316 nm_connectivity_check_async (priv->connectivity,
4317 connectivity_check_done,
4322 g_dbus_method_invocation_take_error (context, error);
4323 nm_auth_chain_unref (chain);
4327 impl_manager_check_connectivity (NMManager *self,
4328 GDBusMethodInvocation *context)
4330 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4332 GError *error = NULL;
4334 /* Validate the request */
4335 chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self);
4337 error = g_error_new_literal (NM_MANAGER_ERROR,
4338 NM_MANAGER_ERROR_PERMISSION_DENIED,
4339 "Unable to authenticate request.");
4340 g_dbus_method_invocation_take_error (context, error);
4344 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4345 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
4349 start_factory (NMDeviceFactory *factory, gpointer user_data)
4351 nm_device_factory_start (factory);
4355 nm_manager_start (NMManager *self, GError **error)
4357 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4358 GSList *iter, *connections;
4361 if (!nm_settings_start (priv->settings, error))
4364 g_signal_connect (NM_PLATFORM_GET,
4365 NM_PLATFORM_SIGNAL_LINK_CHANGED,
4366 G_CALLBACK (platform_link_cb),
4369 /* Set initial radio enabled/disabled state */
4370 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
4371 RadioState *rstate = &priv->radio_states[i];
4377 /* recheck kernel rfkill state */
4378 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
4381 _LOGI (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
4383 (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
4384 rstate->user_enabled ? "enabled" : "disabled");
4386 enabled = radio_enabled_for_rstate (rstate, TRUE);
4387 manager_update_radio_enabled (self, rstate, enabled);
4390 /* Log overall networking status - enabled/disabled */
4391 _LOGI (LOGD_CORE, "Networking is %s by state file",
4392 priv->net_enabled ? "enabled" : "disabled");
4394 system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
4395 system_hostname_changed_cb (priv->settings, NULL, self);
4397 /* Start device factories */
4398 nm_device_factory_manager_load_factories (_register_device_factory, self);
4399 nm_device_factory_manager_for_each_factory (start_factory, NULL);
4401 platform_query_devices (self);
4403 /* Load VPN plugins */
4404 priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
4406 /* Connections added before the manager is started do not emit
4407 * connection-added signals thus devices have to be created manually.
4409 _LOGD (LOGD_CORE, "creating virtual devices...");
4410 connections = nm_settings_get_connections (priv->settings);
4411 for (iter = connections; iter; iter = iter->next)
4412 connection_changed (priv->settings, NM_CONNECTION (iter->data), self);
4413 g_slist_free (connections);
4415 priv->devices_inited = TRUE;
4417 check_if_startup_complete (self);
4423 nm_manager_stop (NMManager *self)
4425 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4427 /* Remove all devices */
4428 while (priv->devices)
4429 remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
4431 _active_connection_cleanup (self);
4435 handle_firmware_changed (gpointer user_data)
4437 NMManager *self = NM_MANAGER (user_data);
4438 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4441 priv->fw_changed_id = 0;
4443 /* Try to re-enable devices with missing firmware */
4444 for (iter = priv->devices; iter; iter = iter->next) {
4445 NMDevice *candidate = NM_DEVICE (iter->data);
4446 NMDeviceState state = nm_device_get_state (candidate);
4448 if ( nm_device_get_firmware_missing (candidate)
4449 && (state == NM_DEVICE_STATE_UNAVAILABLE)) {
4450 _LOGI (LOGD_CORE, "(%s): firmware may now be available",
4451 nm_device_get_iface (candidate));
4453 /* Re-set unavailable state to try bringing the device up again */
4454 nm_device_state_changed (candidate,
4455 NM_DEVICE_STATE_UNAVAILABLE,
4456 NM_DEVICE_STATE_REASON_NONE);
4464 connectivity_changed (NMConnectivity *connectivity,
4468 NMManager *self = NM_MANAGER (user_data);
4470 _LOGD (LOGD_CORE, "connectivity checking indicates %s",
4471 nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
4473 nm_manager_update_state (self);
4474 g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
4478 firmware_dir_changed (GFileMonitor *monitor,
4481 GFileMonitorEvent event_type,
4484 NMManager *self = NM_MANAGER (user_data);
4485 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4487 switch (event_type) {
4488 case G_FILE_MONITOR_EVENT_CREATED:
4489 case G_FILE_MONITOR_EVENT_CHANGED:
4490 case G_FILE_MONITOR_EVENT_MOVED:
4491 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
4492 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
4493 if (!priv->fw_changed_id) {
4494 priv->fw_changed_id = g_timeout_add_seconds (4, handle_firmware_changed, self);
4495 _LOGI (LOGD_CORE, "kernel firmware directory '%s' changed",
4496 KERNEL_FIRMWARE_DIR);
4505 connection_metered_changed (GObject *object,
4509 nm_manager_update_metered (NM_MANAGER (user_data));
4513 policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4515 NMManager *self = NM_MANAGER (user_data);
4516 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4518 NMActiveConnection *ac;
4520 /* Note: this assumes that it's not possible for the IP4 default
4521 * route to be going over the default-ip6-device. If that changes,
4522 * we need something more complicated here.
4524 best = nm_policy_get_default_ip4_device (priv->policy);
4526 best = nm_policy_get_default_ip6_device (priv->policy);
4529 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
4533 if (ac != priv->primary_connection) {
4534 if (priv->primary_connection) {
4535 g_signal_handlers_disconnect_by_func (priv->primary_connection,
4536 G_CALLBACK (connection_metered_changed),
4538 g_clear_object (&priv->primary_connection);
4541 priv->primary_connection = ac ? g_object_ref (ac) : NULL;
4543 if (priv->primary_connection) {
4544 g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
4545 G_CALLBACK (connection_metered_changed), self);
4547 _LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4548 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
4549 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE);
4550 nm_manager_update_metered (self);
4555 policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4557 NMManager *self = NM_MANAGER (user_data);
4558 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4559 NMDevice *activating, *best;
4560 NMActiveConnection *ac;
4562 /* We only look at activating-ip6-device if activating-ip4-device
4563 * AND default-ip4-device are NULL; if default-ip4-device is
4564 * non-NULL, then activating-ip6-device is irrelevant, since while
4565 * that device might become the new default-ip6-device, it can't
4566 * become primary-connection while default-ip4-device is set to
4569 activating = nm_policy_get_activating_ip4_device (priv->policy);
4570 best = nm_policy_get_default_ip4_device (priv->policy);
4571 if (!activating && !best)
4572 activating = nm_policy_get_activating_ip6_device (priv->policy);
4575 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
4579 if (ac != priv->activating_connection) {
4580 g_clear_object (&priv->activating_connection);
4581 priv->activating_connection = ac ? g_object_ref (ac) : NULL;
4582 _LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4583 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVATING_CONNECTION);
4587 #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
4591 GDBusConnection *connection;
4592 GDBusMessage *message;
4593 NMAuthSubject *subject;
4594 const char *permission;
4595 const char *audit_op;
4596 char *audit_prop_value;
4597 GType interface_type;
4598 const char *glib_propname;
4599 } PropertyFilterData;
4602 free_property_filter_data (PropertyFilterData *pfd)
4604 g_object_unref (pfd->self);
4605 g_object_unref (pfd->connection);
4606 g_object_unref (pfd->message);
4607 g_clear_object (&pfd->subject);
4608 g_free (pfd->audit_prop_value);
4609 g_slice_free (PropertyFilterData, pfd);
4613 prop_set_auth_done_cb (NMAuthChain *chain,
4615 GDBusMethodInvocation *context, /* NULL */
4618 PropertyFilterData *pfd = user_data;
4619 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4620 NMAuthCallResult result;
4621 GDBusMessage *reply = NULL;
4622 const char *error_message;
4623 gs_unref_object NMExportedObject *object = NULL;
4624 const NMGlobalDnsConfig *global_dns;
4625 gs_unref_variant GVariant *value = NULL;
4628 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4629 result = nm_auth_chain_get_result (chain, pfd->permission);
4630 if (error || (result != NM_AUTH_CALL_RESULT_YES)) {
4631 reply = g_dbus_message_new_method_error (pfd->message,
4632 NM_PERM_DENIED_ERROR,
4633 (error_message = "Not authorized to perform this operation"));
4635 error_message = error->message;
4639 object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr,
4640 g_dbus_message_get_path (pfd->message)));
4642 reply = g_dbus_message_new_method_error (pfd->message,
4643 "org.freedesktop.DBus.Error.UnknownObject",
4644 (error_message = "Object doesn't exist."));
4648 /* do some extra type checking... */
4649 if (!nm_exported_object_get_interface_by_type (object, pfd->interface_type)) {
4650 reply = g_dbus_message_new_method_error (pfd->message,
4651 "org.freedesktop.DBus.Error.InvalidArgs",
4652 (error_message = "Object is of unexpected type."));
4656 args = g_dbus_message_get_body (pfd->message);
4657 g_variant_get (args, "(&s&sv)", NULL, NULL, &value);
4658 g_assert (pfd->glib_propname);
4660 if (!strcmp (pfd->glib_propname, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) {
4661 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{sv}")));
4662 global_dns = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config));
4664 if (global_dns && !nm_global_dns_config_is_internal (global_dns)) {
4665 reply = g_dbus_message_new_method_error (pfd->message,
4666 NM_PERM_DENIED_ERROR,
4667 (error_message = "Global DNS configuration already set via configuration file"));
4670 /* ... but set the property on the @object itself. It would be correct to set the property
4671 * on the skeleton interface, but as it is now, the result is the same. */
4672 g_object_set (object, pfd->glib_propname, value, NULL);
4674 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
4676 g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL);
4679 reply = g_dbus_message_new_method_reply (pfd->message);
4680 g_dbus_message_set_body (reply, g_variant_new_tuple (NULL, 0));
4681 error_message = NULL;
4683 nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message);
4685 g_dbus_connection_send_message (pfd->connection, reply,
4686 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4688 g_object_unref (reply);
4689 nm_auth_chain_unref (chain);
4691 free_property_filter_data (pfd);
4695 do_set_property_check (gpointer user_data)
4697 PropertyFilterData *pfd = user_data;
4698 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4699 GDBusMessage *reply = NULL;
4701 const char *error_message = NULL;
4703 pfd->subject = nm_auth_subject_new_unix_process_from_message (pfd->connection, pfd->message);
4704 if (!pfd->subject) {
4705 reply = g_dbus_message_new_method_error (pfd->message,
4706 NM_PERM_DENIED_ERROR,
4707 (error_message = "Could not determine request UID."));
4711 /* Validate the user request */
4712 chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd);
4714 reply = g_dbus_message_new_method_error (pfd->message,
4715 NM_PERM_DENIED_ERROR,
4716 (error_message = "Could not authenticate request."));
4720 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4721 nm_auth_chain_add_call (chain, pfd->permission, TRUE);
4725 nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, FALSE, pfd->subject, error_message);
4726 g_dbus_connection_send_message (pfd->connection, reply,
4727 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4729 g_object_unref (reply);
4730 free_property_filter_data (pfd);
4736 static GDBusMessage *
4737 prop_filter (GDBusConnection *connection,
4738 GDBusMessage *message,
4742 gs_unref_object NMManager *self = NULL;
4744 const char *propiface = NULL;
4745 const char *propname = NULL;
4746 const char *glib_propname = NULL, *permission = NULL;
4747 const char *audit_op = NULL;
4748 GType interface_type = G_TYPE_INVALID;
4749 PropertyFilterData *pfd;
4750 const GVariantType *expected_type = G_VARIANT_TYPE_BOOLEAN;
4751 gs_unref_variant GVariant *value = NULL;
4753 self = g_weak_ref_get (user_data);
4757 /* The sole purpose of this function is to validate property accesses on the
4758 * NMManager object since gdbus doesn't give us this functionality.
4761 /* Only filter org.freedesktop.DBus.Properties.Set calls */
4763 || g_dbus_message_get_message_type (message) != G_DBUS_MESSAGE_TYPE_METHOD_CALL
4764 || g_strcmp0 (g_dbus_message_get_interface (message), DBUS_INTERFACE_PROPERTIES) != 0
4765 || g_strcmp0 (g_dbus_message_get_member (message), "Set") != 0)
4768 args = g_dbus_message_get_body (message);
4769 if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)")))
4771 g_variant_get (args, "(&s&sv)", &propiface, &propname, &value);
4773 /* Only filter calls to filtered properties, on existing objects */
4774 if (!strcmp (propiface, NM_DBUS_INTERFACE)) {
4775 if (!strcmp (propname, "WirelessEnabled")) {
4776 glib_propname = NM_MANAGER_WIRELESS_ENABLED;
4777 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI;
4778 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4779 } else if (!strcmp (propname, "WwanEnabled")) {
4780 glib_propname = NM_MANAGER_WWAN_ENABLED;
4781 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
4782 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4783 } else if (!strcmp (propname, "WimaxEnabled")) {
4784 glib_propname = NM_MANAGER_WIMAX_ENABLED;
4785 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
4786 audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4787 } else if (!strcmp (propname, "GlobalDnsConfiguration")) {
4788 glib_propname = NM_MANAGER_GLOBAL_DNS_CONFIGURATION;
4789 permission = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
4790 audit_op = NM_AUDIT_OP_NET_CONTROL;
4791 expected_type = G_VARIANT_TYPE ("a{sv}");
4794 interface_type = NMDBUS_TYPE_MANAGER_SKELETON;
4795 } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)) {
4796 if (!strcmp (propname, "Autoconnect")) {
4797 glib_propname = NM_DEVICE_AUTOCONNECT;
4798 permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4799 audit_op = NM_AUDIT_OP_DEVICE_AUTOCONNECT;
4800 } else if (!strcmp (propname, "Managed")) {
4801 glib_propname = NM_DEVICE_MANAGED;
4802 permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4803 audit_op = NM_AUDIT_OP_DEVICE_MANAGED;
4806 interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
4810 if (!g_variant_is_of_type (value, expected_type))
4813 /* This filter function is called from a gdbus worker thread which we can't
4814 * make other D-Bus calls from. In particular, we cannot call
4815 * org.freedesktop.DBus.GetConnectionUnixUser to find the remote UID.
4817 pfd = g_slice_new0 (PropertyFilterData);
4820 pfd->connection = g_object_ref (connection);
4821 pfd->message = message;
4822 pfd->permission = permission;
4823 pfd->interface_type = interface_type;
4824 pfd->glib_propname = glib_propname;
4825 pfd->audit_op = audit_op;
4826 if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
4827 pfd->audit_prop_value = g_strdup_printf ("%s:%d", pfd->glib_propname,
4828 g_variant_get_boolean (value));
4830 pfd->audit_prop_value = g_strdup (pfd->glib_propname);
4832 g_idle_add (do_set_property_check, pfd);
4837 /******************************************************************************/
4840 _set_prop_filter_free2 (gpointer user_data)
4842 g_slice_free (GWeakRef, user_data);
4843 return G_SOURCE_REMOVE;
4847 _set_prop_filter_free (gpointer user_data)
4849 g_weak_ref_clear (user_data);
4851 /* Delay the final deletion of the user_data. There is a race when
4852 * calling g_dbus_connection_remove_filter() that the callback and user_data
4853 * might have been copied and being executed after the destroy function
4854 * runs (bgo #704568).
4855 * This doesn't really fix the race, but it should work well enough. */
4856 g_timeout_add_seconds (2, _set_prop_filter_free2, user_data);
4860 _set_prop_filter (NMManager *self, GDBusConnection *connection)
4862 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4864 nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id));
4866 if (priv->prop_filter.connection == connection)
4869 if (priv->prop_filter.connection) {
4870 g_dbus_connection_remove_filter (priv->prop_filter.connection, priv->prop_filter.id);
4871 priv->prop_filter.id = 0;
4872 g_clear_object (&priv->prop_filter.connection);
4877 wptr = g_slice_new (GWeakRef);
4878 g_weak_ref_init (wptr, self);
4879 priv->prop_filter.id = g_dbus_connection_add_filter (connection, prop_filter, wptr, _set_prop_filter_free);
4880 priv->prop_filter.connection = g_object_ref (connection);
4884 /******************************************************************************/
4887 authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data)
4889 /* Let clients know they should re-check their authorization */
4890 g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
4893 #define KERN_RFKILL_OP_CHANGE_ALL 3
4894 #define KERN_RFKILL_TYPE_WLAN 1
4895 #define KERN_RFKILL_TYPE_WWAN 5
4896 struct rfkill_event {
4901 } __attribute__((packed));
4904 rfkill_change (const char *desc, RfKillType rtype, gboolean enabled)
4907 struct rfkill_event event;
4910 g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
4913 fd = open ("/dev/rfkill", O_RDWR);
4915 if (errno == EACCES)
4916 nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device", desc);
4920 if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
4921 nm_log_warn (LOGD_RFKILL, "(%s): failed to set killswitch device for "
4922 "non-blocking operation", desc);
4927 memset (&event, 0, sizeof (event));
4928 event.op = KERN_RFKILL_OP_CHANGE_ALL;
4930 case RFKILL_TYPE_WLAN:
4931 event.type = KERN_RFKILL_TYPE_WLAN;
4933 case RFKILL_TYPE_WWAN:
4934 event.type = KERN_RFKILL_TYPE_WWAN;
4937 g_assert_not_reached ();
4939 event.soft = enabled ? 0 : 1;
4941 len = write (fd, &event, sizeof (event));
4943 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
4944 desc, errno, g_strerror (errno));
4945 } else if (len == sizeof (event)) {
4946 nm_log_info (LOGD_RFKILL, "%s hardware radio set %s",
4947 desc, enabled ? "enabled" : "disabled");
4949 /* Failed to write full structure */
4950 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
4957 manager_radio_user_toggled (NMManager *self,
4961 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4962 GError *error = NULL;
4963 gboolean old_enabled, new_enabled;
4965 /* Don't touch devices if asleep/networking disabled */
4966 if (manager_sleeping (self))
4970 _LOGD (LOGD_RFKILL, "(%s): setting radio %s by user",
4972 enabled ? "enabled" : "disabled");
4975 /* Update enabled key in state file */
4976 if (priv->state_file) {
4977 if (!write_value_to_state_file (priv->state_file,
4978 "main", rstate->key,
4979 G_TYPE_BOOLEAN, (gpointer) &enabled,
4981 _LOGW (LOGD_CORE, "writing to state file %s failed: %s",
4984 g_clear_error (&error);
4988 /* When the user toggles the radio, their request should override any
4989 * daemon (like ModemManager) enabled state that can be changed. For WWAN
4990 * for example, we want the WwanEnabled property to reflect the daemon state
4991 * too so that users can toggle the modem powered, but we don't want that
4992 * daemon state to affect whether or not the user *can* turn it on, which is
4993 * what the kernel rfkill state does. So we ignore daemon enabled state
4994 * when determining what the new state should be since it shouldn't block
4995 * the user's request.
4997 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
4998 rstate->user_enabled = enabled;
4999 new_enabled = radio_enabled_for_rstate (rstate, FALSE);
5000 if (new_enabled != old_enabled) {
5001 /* Try to change the kernel rfkill state */
5002 if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN)
5003 rfkill_change (rstate->desc, rstate->rtype, new_enabled);
5005 manager_update_radio_enabled (self, rstate, new_enabled);
5010 periodic_update_active_connection_timestamps (gpointer user_data)
5012 NMManager *manager = NM_MANAGER (user_data);
5013 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5016 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
5017 NMActiveConnection *ac = iter->data;
5018 NMSettingsConnection *connection;
5020 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
5021 connection = nm_active_connection_get_settings_connection (ac);
5022 nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
5030 dbus_connection_changed_cb (NMBusManager *dbus_mgr,
5031 GDBusConnection *connection,
5034 _set_prop_filter (NM_MANAGER (user_data), connection);
5037 /**********************************************************************/
5039 NM_DEFINE_SINGLETON_REGISTER (NMManager);
5042 nm_manager_get (void)
5044 g_return_val_if_fail (singleton_instance, NULL);
5045 return singleton_instance;
5048 NMConnectionProvider *
5049 nm_connection_provider_get (void)
5051 NMConnectionProvider *p;
5053 g_return_val_if_fail (singleton_instance, NULL);
5055 p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings);
5056 g_return_val_if_fail (p, NULL);
5061 nm_manager_setup (const char *state_file,
5062 gboolean initial_net_enabled,
5063 gboolean initial_wifi_enabled,
5064 gboolean initial_wwan_enabled)
5068 g_return_val_if_fail (!singleton_instance, singleton_instance);
5070 self = g_object_new (NM_TYPE_MANAGER,
5071 NM_MANAGER_NETWORKING_ENABLED, initial_net_enabled,
5072 NM_MANAGER_WIRELESS_ENABLED, initial_wifi_enabled,
5073 NM_MANAGER_WWAN_ENABLED, initial_wwan_enabled,
5074 NM_MANAGER_STATE_FILE, state_file,
5076 nm_assert (NM_IS_MANAGER (self));
5077 singleton_instance = self;
5079 nm_singleton_instance_register ();
5080 _LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance);
5082 nm_exported_object_export ((NMExportedObject *) self);
5088 constructed (GObject *object)
5090 NMManager *self = NM_MANAGER (object);
5091 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5092 NMConfigData *config_data;
5094 G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
5096 _set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr));
5098 priv->settings = nm_settings_new ();
5099 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE,
5100 G_CALLBACK (settings_startup_complete_changed), self);
5101 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
5102 G_CALLBACK (system_unmanaged_devices_changed_cb), self);
5103 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
5104 G_CALLBACK (system_hostname_changed_cb), self);
5105 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
5106 G_CALLBACK (connection_changed), self);
5107 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
5108 G_CALLBACK (connection_changed), self);
5109 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
5110 G_CALLBACK (connection_removed), self);
5112 priv->policy = nm_policy_new (self, priv->settings);
5113 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
5114 G_CALLBACK (policy_default_device_changed), self);
5115 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
5116 G_CALLBACK (policy_default_device_changed), self);
5117 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
5118 G_CALLBACK (policy_activating_device_changed), self);
5119 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
5120 G_CALLBACK (policy_activating_device_changed), self);
5122 priv->config = g_object_ref (nm_config_get ());
5123 g_signal_connect (G_OBJECT (priv->config),
5124 NM_CONFIG_SIGNAL_CONFIG_CHANGED,
5125 G_CALLBACK (_config_changed_cb),
5128 config_data = nm_config_get_data (priv->config);
5129 priv->connectivity = nm_connectivity_new (nm_config_data_get_connectivity_uri (config_data),
5130 nm_config_data_get_connectivity_interval (config_data),
5131 nm_config_data_get_connectivity_response (config_data));
5132 g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
5133 G_CALLBACK (connectivity_changed), self);
5135 priv->rfkill_mgr = nm_rfkill_manager_new ();
5136 g_signal_connect (priv->rfkill_mgr,
5138 G_CALLBACK (rfkill_manager_rfkill_changed_cb),
5141 /* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state
5142 * in case the BIOS doesn't save rfkill state, and to be consistent with user
5143 * changes to the WirelessEnabled/WWANEnabled properties which toggle kernel
5146 rfkill_change (priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled);
5147 rfkill_change (priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, priv->radio_states[RFKILL_TYPE_WWAN].user_enabled);
5151 nm_manager_init (NMManager *self)
5153 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5157 /* Initialize rfkill structures and states */
5158 memset (priv->radio_states, 0, sizeof (priv->radio_states));
5160 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
5161 priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
5162 priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
5163 priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
5164 priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
5165 priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
5167 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
5168 priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
5169 priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
5170 priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
5171 priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
5172 priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
5174 for (i = 0; i < RFKILL_TYPE_MAX; i++)
5175 priv->radio_states[i].hw_enabled = TRUE;
5177 priv->sleeping = FALSE;
5178 priv->state = NM_STATE_DISCONNECTED;
5179 priv->startup = TRUE;
5181 priv->dbus_mgr = g_object_ref (nm_bus_manager_get ());
5182 g_signal_connect (priv->dbus_mgr,
5183 NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED,
5184 G_CALLBACK (dbus_connection_changed_cb),
5187 /* sleep/wake handling */
5188 priv->sleep_monitor = g_object_ref (nm_sleep_monitor_get ());
5189 g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING,
5190 G_CALLBACK (sleeping_cb), self);
5191 g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_RESUMING,
5192 G_CALLBACK (resuming_cb), self);
5194 /* Listen for authorization changes */
5195 g_signal_connect (nm_auth_manager_get (),
5196 NM_AUTH_MANAGER_SIGNAL_CHANGED,
5197 G_CALLBACK (authority_changed_cb),
5201 /* Monitor the firmware directory */
5202 if (strlen (KERNEL_FIRMWARE_DIR)) {
5203 file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/");
5204 priv->fw_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
5205 g_object_unref (file);
5208 if (priv->fw_monitor) {
5209 g_signal_connect (priv->fw_monitor, "changed",
5210 G_CALLBACK (firmware_dir_changed),
5212 _LOGI (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
5213 KERNEL_FIRMWARE_DIR);
5215 _LOGW (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
5216 KERNEL_FIRMWARE_DIR);
5219 /* Update timestamps in active connections */
5220 priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, self);
5222 priv->metered = NM_METERED_UNKNOWN;
5226 device_is_real (GObject *device, gpointer user_data)
5228 return nm_device_is_real (NM_DEVICE (device));
5232 get_property (GObject *object, guint prop_id,
5233 GValue *value, GParamSpec *pspec)
5235 NMManager *self = NM_MANAGER (object);
5236 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5237 NMConfigData *config_data;
5238 const NMGlobalDnsConfig *dns_config;
5243 g_value_set_string (value, VERSION);
5246 nm_manager_update_state (self);
5247 g_value_set_uint (value, priv->state);
5250 g_value_set_boolean (value, priv->startup);
5252 case PROP_NETWORKING_ENABLED:
5253 g_value_set_boolean (value, priv->net_enabled);
5255 case PROP_WIRELESS_ENABLED:
5256 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
5258 case PROP_WIRELESS_HARDWARE_ENABLED:
5259 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
5261 case PROP_WWAN_ENABLED:
5262 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
5264 case PROP_WWAN_HARDWARE_ENABLED:
5265 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
5267 case PROP_WIMAX_ENABLED:
5268 g_value_set_boolean (value, FALSE);
5270 case PROP_WIMAX_HARDWARE_ENABLED:
5271 g_value_set_boolean (value, FALSE);
5273 case PROP_ACTIVE_CONNECTIONS:
5274 nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
5276 case PROP_CONNECTIVITY:
5277 g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
5279 case PROP_PRIMARY_CONNECTION:
5280 nm_utils_g_value_set_object_path (value, priv->primary_connection);
5282 case PROP_PRIMARY_CONNECTION_TYPE:
5284 if (priv->primary_connection) {
5287 con = nm_active_connection_get_applied_connection (priv->primary_connection);
5289 type = nm_connection_get_connection_type (con);
5291 g_value_set_string (value, type ? type : "");
5293 case PROP_ACTIVATING_CONNECTION:
5294 nm_utils_g_value_set_object_path (value, priv->activating_connection);
5297 g_value_set_string (value, priv->hostname);
5300 g_value_set_boolean (value, priv->sleeping);
5303 nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
5306 g_value_set_uint (value, priv->metered);
5308 case PROP_GLOBAL_DNS_CONFIGURATION:
5309 config_data = nm_config_get_data (priv->config);
5310 dns_config = nm_config_data_get_global_dns_config (config_data);
5311 nm_global_dns_config_to_dbus (dns_config, value);
5313 case PROP_ALL_DEVICES:
5314 nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
5317 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5323 set_property (GObject *object, guint prop_id,
5324 const GValue *value, GParamSpec *pspec)
5326 NMManager *self = NM_MANAGER (object);
5327 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5328 NMGlobalDnsConfig *dns_config;
5329 GError *error = NULL;
5332 case PROP_STATE_FILE:
5333 /* construct-only */
5334 priv->state_file = g_value_dup_string (value);
5336 case PROP_NETWORKING_ENABLED:
5337 /* construct-only */
5338 priv->net_enabled = g_value_get_boolean (value);
5340 case PROP_WIRELESS_ENABLED:
5341 if (!priv->rfkill_mgr) {
5342 /* called during object construction. */
5343 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = g_value_get_boolean (value);
5345 manager_radio_user_toggled (NM_MANAGER (object),
5346 &priv->radio_states[RFKILL_TYPE_WLAN],
5347 g_value_get_boolean (value));
5350 case PROP_WWAN_ENABLED:
5351 if (!priv->rfkill_mgr) {
5352 /* called during object construction. */
5353 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = g_value_get_boolean (value);
5355 manager_radio_user_toggled (NM_MANAGER (object),
5356 &priv->radio_states[RFKILL_TYPE_WWAN],
5357 g_value_get_boolean (value));
5360 case PROP_WIMAX_ENABLED:
5361 /* WIMAX is depreacted. This does nothing. */
5363 case PROP_GLOBAL_DNS_CONFIGURATION:
5364 dns_config = nm_global_dns_config_from_dbus (value, &error);
5366 nm_config_set_global_dns (priv->config, dns_config, &error);
5368 nm_global_dns_config_free (dns_config);
5371 _LOGD (LOGD_CORE, "set global DNS failed with error: %s", error->message);
5372 g_error_free (error);
5376 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5382 _deinit_device_factory (NMDeviceFactory *factory, gpointer user_data)
5384 g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NM_MANAGER (user_data));
5388 dispose (GObject *object)
5390 NMManager *manager = NM_MANAGER (object);
5391 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5393 g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
5394 priv->auth_chains = NULL;
5396 g_signal_handlers_disconnect_by_func (nm_auth_manager_get (),
5397 G_CALLBACK (authority_changed_cb),
5400 g_assert (priv->devices == NULL);
5402 nm_clear_g_source (&priv->ac_cleanup_id);
5404 while (priv->active_connections)
5405 active_connection_remove (manager, NM_ACTIVE_CONNECTION (priv->active_connections->data));
5406 g_clear_pointer (&priv->active_connections, g_slist_free);
5407 g_clear_object (&priv->primary_connection);
5408 g_clear_object (&priv->activating_connection);
5411 g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
5412 g_clear_object (&priv->config);
5414 if (priv->connectivity) {
5415 g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
5416 g_clear_object (&priv->connectivity);
5419 g_free (priv->hostname);
5422 g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, manager);
5423 g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, manager);
5424 g_clear_object (&priv->policy);
5427 if (priv->settings) {
5428 g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, manager);
5429 g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, manager);
5430 g_signal_handlers_disconnect_by_func (priv->settings, system_hostname_changed_cb, manager);
5431 g_signal_handlers_disconnect_by_func (priv->settings, connection_changed, manager);
5432 g_signal_handlers_disconnect_by_func (priv->settings, connection_removed, manager);
5433 g_clear_object (&priv->settings);
5436 g_clear_pointer (&priv->state_file, g_free);
5437 g_clear_object (&priv->vpn_manager);
5439 /* Unregister property filter */
5440 if (priv->dbus_mgr) {
5441 g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, manager);
5442 g_clear_object (&priv->dbus_mgr);
5444 _set_prop_filter (manager, NULL);
5446 if (priv->sleep_monitor) {
5447 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, sleeping_cb, manager);
5448 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, resuming_cb, manager);
5449 g_clear_object (&priv->sleep_monitor);
5452 if (priv->fw_monitor) {
5453 g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager);
5455 nm_clear_g_source (&priv->fw_changed_id);
5457 g_file_monitor_cancel (priv->fw_monitor);
5458 g_clear_object (&priv->fw_monitor);
5461 if (priv->rfkill_mgr) {
5462 g_signal_handlers_disconnect_by_func (priv->rfkill_mgr, rfkill_manager_rfkill_changed_cb, manager);
5463 g_clear_object (&priv->rfkill_mgr);
5466 nm_device_factory_manager_for_each_factory (_deinit_device_factory, manager);
5468 nm_clear_g_source (&priv->timestamp_update_id);
5470 G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
5474 nm_manager_class_init (NMManagerClass *manager_class)
5476 GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
5477 NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
5479 g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
5481 exported_object_class->export_path = NM_DBUS_PATH;
5483 /* virtual methods */
5484 object_class->constructed = constructed;
5485 object_class->set_property = set_property;
5486 object_class->get_property = get_property;
5487 object_class->dispose = dispose;
5490 g_object_class_install_property
5491 (object_class, PROP_VERSION,
5492 g_param_spec_string (NM_MANAGER_VERSION, "", "",
5495 G_PARAM_STATIC_STRINGS));
5497 g_object_class_install_property (object_class,
5499 g_param_spec_string (NM_MANAGER_STATE_FILE, "", "",
5502 G_PARAM_CONSTRUCT_ONLY |
5503 G_PARAM_STATIC_STRINGS));
5505 g_object_class_install_property
5506 (object_class, PROP_STATE,
5507 g_param_spec_uint (NM_MANAGER_STATE, "", "",
5508 0, NM_STATE_DISCONNECTED, 0,
5510 G_PARAM_STATIC_STRINGS));
5512 g_object_class_install_property
5513 (object_class, PROP_STARTUP,
5514 g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
5517 G_PARAM_STATIC_STRINGS));
5519 g_object_class_install_property
5520 (object_class, PROP_NETWORKING_ENABLED,
5521 g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
5523 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
5524 G_PARAM_STATIC_STRINGS));
5526 g_object_class_install_property
5527 (object_class, PROP_WIRELESS_ENABLED,
5528 g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
5532 G_PARAM_STATIC_STRINGS));
5534 g_object_class_install_property
5535 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
5536 g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
5539 G_PARAM_STATIC_STRINGS));
5541 g_object_class_install_property
5542 (object_class, PROP_WWAN_ENABLED,
5543 g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
5547 G_PARAM_STATIC_STRINGS));
5549 g_object_class_install_property
5550 (object_class, PROP_WWAN_HARDWARE_ENABLED,
5551 g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
5554 G_PARAM_STATIC_STRINGS));
5556 g_object_class_install_property
5557 (object_class, PROP_WIMAX_ENABLED,
5558 g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
5561 G_PARAM_STATIC_STRINGS));
5563 g_object_class_install_property
5564 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
5565 g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
5568 G_PARAM_STATIC_STRINGS));
5570 g_object_class_install_property
5571 (object_class, PROP_ACTIVE_CONNECTIONS,
5572 g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
5575 G_PARAM_STATIC_STRINGS));
5577 g_object_class_install_property
5578 (object_class, PROP_CONNECTIVITY,
5579 g_param_spec_uint (NM_MANAGER_CONNECTIVITY, "", "",
5580 NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
5582 G_PARAM_STATIC_STRINGS));
5584 g_object_class_install_property
5585 (object_class, PROP_PRIMARY_CONNECTION,
5586 g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION, "", "",
5589 G_PARAM_STATIC_STRINGS));
5591 g_object_class_install_property
5592 (object_class, PROP_PRIMARY_CONNECTION_TYPE,
5593 g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "",
5596 G_PARAM_STATIC_STRINGS));
5599 g_object_class_install_property
5600 (object_class, PROP_ACTIVATING_CONNECTION,
5601 g_param_spec_string (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
5604 G_PARAM_STATIC_STRINGS));
5606 /* Hostname is not exported over D-Bus */
5607 g_object_class_install_property
5608 (object_class, PROP_HOSTNAME,
5609 g_param_spec_string (NM_MANAGER_HOSTNAME, "", "",
5612 G_PARAM_STATIC_STRINGS));
5614 /* Sleeping is not exported over D-Bus */
5615 g_object_class_install_property
5616 (object_class, PROP_SLEEPING,
5617 g_param_spec_boolean (NM_MANAGER_SLEEPING, "", "",
5620 G_PARAM_STATIC_STRINGS));
5622 g_object_class_install_property
5623 (object_class, PROP_DEVICES,
5624 g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
5627 G_PARAM_STATIC_STRINGS));
5630 * NMManager:metered:
5632 * Whether the connectivity is metered.
5636 g_object_class_install_property
5637 (object_class, PROP_METERED,
5638 g_param_spec_uint (NM_MANAGER_METERED, "", "",
5639 0, G_MAXUINT32, NM_METERED_UNKNOWN,
5641 G_PARAM_STATIC_STRINGS));
5644 * NMManager:global-dns-configuration:
5646 * The global DNS configuration.
5650 g_object_class_install_property
5651 (object_class, PROP_GLOBAL_DNS_CONFIGURATION,
5652 g_param_spec_variant (NM_MANAGER_GLOBAL_DNS_CONFIGURATION, "", "",
5653 G_VARIANT_TYPE ("a{sv}"),
5656 G_PARAM_STATIC_STRINGS));
5659 * NMManager:all-devices:
5661 * All devices, including those that are not realized.
5665 g_object_class_install_property
5666 (object_class, PROP_ALL_DEVICES,
5667 g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
5670 G_PARAM_STATIC_STRINGS));
5674 /* D-Bus exported; emitted only for realized devices */
5675 signals[DEVICE_ADDED] =
5676 g_signal_new ("device-added",
5677 G_OBJECT_CLASS_TYPE (object_class),
5679 G_STRUCT_OFFSET (NMManagerClass, device_added),
5681 G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5683 /* Emitted for both realized devices and placeholder devices */
5684 signals[INTERNAL_DEVICE_ADDED] =
5685 g_signal_new ("internal-device-added",
5686 G_OBJECT_CLASS_TYPE (object_class),
5687 G_SIGNAL_RUN_FIRST, 0,
5689 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5691 /* D-Bus exported; emitted only for realized devices */
5692 signals[DEVICE_REMOVED] =
5693 g_signal_new ("device-removed",
5694 G_OBJECT_CLASS_TYPE (object_class),
5696 G_STRUCT_OFFSET (NMManagerClass, device_removed),
5698 G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5700 /* Emitted for both realized devices and placeholder devices */
5701 signals[INTERNAL_DEVICE_REMOVED] =
5702 g_signal_new ("internal-device-removed",
5703 G_OBJECT_CLASS_TYPE (object_class),
5704 G_SIGNAL_RUN_FIRST, 0,
5706 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5708 signals[STATE_CHANGED] =
5709 g_signal_new (NM_MANAGER_STATE_CHANGED,
5710 G_OBJECT_CLASS_TYPE (object_class),
5712 G_STRUCT_OFFSET (NMManagerClass, state_changed),
5714 G_TYPE_NONE, 1, G_TYPE_UINT);
5716 signals[CHECK_PERMISSIONS] =
5717 g_signal_new ("check-permissions",
5718 G_OBJECT_CLASS_TYPE (object_class),
5720 0, NULL, NULL, NULL,
5723 signals[USER_PERMISSIONS_CHANGED] =
5724 g_signal_new ("user-permissions-changed",
5725 G_OBJECT_CLASS_TYPE (object_class),
5727 0, NULL, NULL, NULL,
5730 signals[ACTIVE_CONNECTION_ADDED] =
5731 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
5732 G_OBJECT_CLASS_TYPE (object_class),
5734 0, NULL, NULL, NULL,
5735 G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5737 signals[ACTIVE_CONNECTION_REMOVED] =
5738 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
5739 G_OBJECT_CLASS_TYPE (object_class),
5741 0, NULL, NULL, NULL,
5742 G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5744 signals[CONFIGURE_QUIT] =
5745 g_signal_new (NM_MANAGER_CONFIGURE_QUIT,
5746 G_OBJECT_CLASS_TYPE (object_class),
5748 0, NULL, NULL, NULL,
5751 nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class),
5752 NMDBUS_TYPE_MANAGER_SKELETON,
5753 "GetDevices", impl_manager_get_devices,
5754 "GetAllDevices", impl_manager_get_all_devices,
5755 "GetDeviceByIpIface", impl_manager_get_device_by_ip_iface,
5756 "ActivateConnection", impl_manager_activate_connection,
5757 "AddAndActivateConnection", impl_manager_add_and_activate_connection,
5758 "DeactivateConnection", impl_manager_deactivate_connection,
5759 "Sleep", impl_manager_sleep,
5760 "Enable", impl_manager_enable,
5761 "GetPermissions", impl_manager_get_permissions,
5762 "SetLogging", impl_manager_set_logging,
5763 "GetLogging", impl_manager_get_logging,
5764 "CheckConnectivity", impl_manager_check_connectivity,
5765 "state", impl_manager_get_state,