0ccb987a1b4d28ccedab4526d45ab88c5437f25e
[NetworkManager.git] / src / nm-manager.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Copyright (C) 2007 - 2009 Novell, Inc.
19  * Copyright (C) 2007 - 2012 Red Hat, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <unistd.h>
29
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"
56
57 #include "nmdbus-manager.h"
58 #include "nmdbus-device.h"
59
60 static gboolean add_device (NMManager *self, NMDevice *device, GError **error);
61
62 static NMActiveConnection *_new_active_connection (NMManager *self,
63                                                    NMConnection *connection,
64                                                    const char *specific_object,
65                                                    NMDevice *device,
66                                                    NMAuthSubject *subject,
67                                                    GError **error);
68
69 static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
70
71 static void rfkill_change (const char *desc, RfKillType rtype, gboolean enabled);
72
73 static gboolean find_master (NMManager *self,
74                              NMConnection *connection,
75                              NMDevice *device,
76                              NMSettingsConnection **out_master_connection,
77                              NMDevice **out_master_device,
78                              NMActiveConnection **out_master_ac,
79                              GError **error);
80
81 static void nm_manager_update_state (NMManager *manager);
82
83 static void connection_changed (NMSettings *settings, NMConnection *connection,
84                                 NMManager *manager);
85
86 #define TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE "act-con-add-and-activate"
87
88 typedef struct {
89         gboolean user_enabled;
90         gboolean sw_enabled;
91         gboolean hw_enabled;
92         RfKillType rtype;
93         const char *desc;
94         const char *key;
95         const char *prop;
96         const char *hw_prop;
97 } RadioState;
98
99 typedef struct {
100         char *state_file;
101
102         GSList *active_connections;
103         GSList *authorizing_connections;
104         guint ac_cleanup_id;
105         NMActiveConnection *primary_connection;
106         NMActiveConnection *activating_connection;
107         NMMetered metered;
108
109         GSList *devices;
110         NMState state;
111         NMConfig *config;
112         NMConnectivity *connectivity;
113
114         NMPolicy *policy;
115
116         NMBusManager  *dbus_mgr;
117         struct {
118                 GDBusConnection *connection;
119                 guint            id;
120         } prop_filter;
121         NMRfkillManager *rfkill_mgr;
122
123         NMSettings *settings;
124         char *hostname;
125
126         RadioState radio_states[RFKILL_TYPE_MAX];
127         gboolean sleeping;
128         gboolean net_enabled;
129
130         NMVpnManager *vpn_manager;
131
132         NMSleepMonitor *sleep_monitor;
133
134         GSList *auth_chains;
135
136         /* Firmware dir monitor */
137         GFileMonitor *fw_monitor;
138         guint fw_changed_id;
139
140         guint timestamp_update_id;
141
142         gboolean startup;
143         gboolean devices_inited;
144 } NMManagerPrivate;
145
146 #define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
147
148 G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
149
150 enum {
151         DEVICE_ADDED,
152         INTERNAL_DEVICE_ADDED,
153         DEVICE_REMOVED,
154         INTERNAL_DEVICE_REMOVED,
155         STATE_CHANGED,
156         CHECK_PERMISSIONS,
157         USER_PERMISSIONS_CHANGED,
158         ACTIVE_CONNECTION_ADDED,
159         ACTIVE_CONNECTION_REMOVED,
160         CONFIGURE_QUIT,
161
162         LAST_SIGNAL
163 };
164
165 static guint signals[LAST_SIGNAL] = { 0 };
166
167 enum {
168         PROP_0,
169         PROP_VERSION,
170         PROP_STATE,
171         PROP_STATE_FILE,
172         PROP_STARTUP,
173         PROP_NETWORKING_ENABLED,
174         PROP_WIRELESS_ENABLED,
175         PROP_WIRELESS_HARDWARE_ENABLED,
176         PROP_WWAN_ENABLED,
177         PROP_WWAN_HARDWARE_ENABLED,
178         PROP_WIMAX_ENABLED,
179         PROP_WIMAX_HARDWARE_ENABLED,
180         PROP_ACTIVE_CONNECTIONS,
181         PROP_CONNECTIVITY,
182         PROP_PRIMARY_CONNECTION,
183         PROP_PRIMARY_CONNECTION_TYPE,
184         PROP_ACTIVATING_CONNECTION,
185         PROP_DEVICES,
186         PROP_METERED,
187         PROP_GLOBAL_DNS_CONFIGURATION,
188         PROP_ALL_DEVICES,
189
190         /* Not exported */
191         PROP_HOSTNAME,
192         PROP_SLEEPING,
193
194         LAST_PROP
195 };
196
197 NM_DEFINE_SINGLETON_INSTANCE (NMManager);
198
199 /************************************************************************/
200
201 #define _NMLOG_PREFIX_NAME      "manager"
202 #define _NMLOG(level, domain, ...) \
203     G_STMT_START { \
204         const NMLogLevel __level = (level); \
205         const NMLogDomain __domain = (domain); \
206         \
207         if (nm_logging_enabled (__level, __domain)) { \
208             const NMManager *const __self = (self); \
209             char __sbuf[32]; \
210             \
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) \
216                          : "" \
217                      _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
218         } \
219     } G_STMT_END
220
221 /************************************************************************/
222
223 static void active_connection_state_changed (NMActiveConnection *active,
224                                              GParamSpec *pspec,
225                                              NMManager *self);
226 static void active_connection_default_changed (NMActiveConnection *active,
227                                                GParamSpec *pspec,
228                                                NMManager *self);
229
230 /* Returns: whether to notify D-Bus of the removal or not */
231 static gboolean
232 active_connection_remove (NMManager *self, NMActiveConnection *active)
233 {
234         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
235         gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
236         GSList *found;
237
238         /* FIXME: switch to a GList for faster removal */
239         found = g_slist_find (priv->active_connections, active);
240         if (found) {
241                 NMSettingsConnection *connection;
242
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);
247
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);
252                 else
253                         connection = NULL;
254
255                 nm_exported_object_clear_and_unexport (&active);
256
257                 if (   connection
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);
263                 }
264         }
265
266         return found && notify;
267 }
268
269 static gboolean
270 _active_connection_cleanup (gpointer user_data)
271 {
272         NMManager *self = NM_MANAGER (user_data);
273         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
274         GSList *iter;
275
276         priv->ac_cleanup_id = 0;
277
278         g_object_freeze_notify (G_OBJECT (self));
279         iter = priv->active_connections;
280         while (iter) {
281                 NMActiveConnection *ac = iter->data;
282
283                 iter = iter->next;
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);
287                 }
288         }
289         g_object_thaw_notify (G_OBJECT (self));
290
291         return FALSE;
292 }
293
294 static void
295 active_connection_state_changed (NMActiveConnection *active,
296                                  GParamSpec *pspec,
297                                  NMManager *self)
298 {
299         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
300         NMActiveConnectionState state;
301
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
307                  * to DEACTIVATED.
308                  */
309                 if (!priv->ac_cleanup_id)
310                         priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
311         }
312
313         nm_manager_update_state (self);
314 }
315
316 static void
317 active_connection_default_changed (NMActiveConnection *active,
318                                    GParamSpec *pspec,
319                                    NMManager *self)
320 {
321         nm_manager_update_state (self);
322 }
323
324 /**
325  * active_connection_add():
326  * @self: the #NMManager
327  * @active: the #NMActiveConnection to manage
328  *
329  * Begins to track and manage @active.  Increases the refcount of @active.
330  */
331 static void
332 active_connection_add (NMManager *self, NMActiveConnection *active)
333 {
334         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
335
336         g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
337
338         priv->active_connections = g_slist_prepend (priv->active_connections,
339                                                     g_object_ref (active));
340
341         g_signal_connect (active,
342                           "notify::" NM_ACTIVE_CONNECTION_STATE,
343                           G_CALLBACK (active_connection_state_changed),
344                           self);
345         g_signal_connect (active,
346                           "notify::" NM_ACTIVE_CONNECTION_DEFAULT,
347                           G_CALLBACK (active_connection_default_changed),
348                           self);
349         g_signal_connect (active,
350                           "notify::" NM_ACTIVE_CONNECTION_DEFAULT6,
351                           G_CALLBACK (active_connection_default_changed),
352                           self);
353
354         g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
355
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);
359 }
360
361 const GSList *
362 nm_manager_get_active_connections (NMManager *manager)
363 {
364         return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
365 }
366
367 static NMActiveConnection *
368 find_ac_for_connection (NMManager *manager, NMConnection *connection)
369 {
370         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
371         GSList *iter;
372         const char *uuid = NULL;
373         gboolean is_settings_connection;
374
375         is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
376
377         if (!is_settings_connection)
378                 uuid = nm_connection_get_uuid (connection);
379
380         for (iter = priv->active_connections; iter; iter = iter->next) {
381                 NMActiveConnection *ac = iter->data;
382                 NMSettingsConnection *con;
383
384                 con = nm_active_connection_get_settings_connection (ac);
385
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)
390                                 continue;
391                 } else {
392                         if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
393                                 continue;
394                 }
395                 if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
396                         return ac;
397         }
398
399         return NULL;
400 }
401
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
405  * are first).
406  * Caller is responsible for freeing the returned list with g_slist_free().
407  */
408 GSList *
409 nm_manager_get_activatable_connections (NMManager *manager)
410 {
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;
415
416         for (iter = all_connections; iter; iter = iter->next) {
417                 connection = iter->data;
418
419                 if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
420                         connections = g_slist_prepend (connections, connection);
421         }
422
423         g_slist_free (all_connections);
424         return g_slist_reverse (connections);
425 }
426
427 static NMActiveConnection *
428 active_connection_get_by_path (NMManager *manager, const char *path)
429 {
430         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
431         GSList *iter;
432
433         g_return_val_if_fail (manager != NULL, NULL);
434         g_return_val_if_fail (path != NULL, NULL);
435
436         for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
437                 NMActiveConnection *candidate = iter->data;
438
439                 if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
440                         return candidate;
441         }
442         return NULL;
443 }
444
445 /************************************************************************/
446
447 static void
448 _config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
449 {
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),
454                       NULL);
455
456         if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG))
457                 g_object_notify (G_OBJECT (self), NM_MANAGER_GLOBAL_DNS_CONFIGURATION);
458 }
459
460 /************************************************************************/
461
462 static NMDevice *
463 nm_manager_get_device_by_path (NMManager *manager, const char *path)
464 {
465         GSList *iter;
466
467         g_return_val_if_fail (path != NULL, NULL);
468
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);
472         }
473         return NULL;
474 }
475
476 NMDevice *
477 nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
478 {
479         GSList *iter;
480
481         for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
482                 NMDevice *device = NM_DEVICE (iter->data);
483
484                 if (nm_device_get_ifindex (device) == ifindex)
485                         return device;
486         }
487
488         return NULL;
489 }
490
491 static NMDevice *
492 find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
493 {
494         GSList *iter;
495         const char *device_addr;
496
497         g_return_val_if_fail (hwaddr != NULL, NULL);
498
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);
504                 }
505         }
506         return NULL;
507 }
508
509 static NMDevice *
510 find_device_by_ip_iface (NMManager *self, const gchar *iface)
511 {
512         GSList *iter;
513
514         g_return_val_if_fail (iface != NULL, NULL);
515
516         for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
517                 NMDevice *candidate = iter->data;
518
519                 if (   nm_device_is_real (candidate)
520                     && g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
521                         return candidate;
522         }
523         return NULL;
524 }
525
526 /**
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
532  *
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.
538  *
539  * Returns: the matching #NMDevice
540  */
541 static NMDevice *
542 find_device_by_iface (NMManager *self,
543                       const char *iface,
544                       NMConnection *connection,
545                       NMConnection *slave)
546 {
547         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
548         NMDevice *fallback = NULL;
549         GSList *iter;
550
551         g_return_val_if_fail (iface != NULL, NULL);
552
553         for (iter = priv->devices; iter; iter = iter->next) {
554                 NMDevice *candidate = iter->data;
555
556                 if (strcmp (nm_device_get_iface (candidate), iface))
557                         continue;
558                 if (connection && !nm_device_check_connection_compatible (candidate, connection))
559                         continue;
560                 if (slave) {
561                         if (!nm_device_is_master (candidate))
562                                 continue;
563                         if (!nm_device_check_slave_connection_compatible (candidate, slave))
564                                 continue;
565                 }
566
567                 if (nm_device_is_real (candidate))
568                         return candidate;
569                 else if (!fallback)
570                         fallback = candidate;
571         }
572         return fallback;
573 }
574
575 static gboolean
576 manager_sleeping (NMManager *self)
577 {
578         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
579
580         if (priv->sleeping || !priv->net_enabled)
581                 return TRUE;
582         return FALSE;
583 }
584
585 static const char *
586 _nm_state_to_string (NMState state)
587 {
588         switch (state) {
589         case NM_STATE_ASLEEP:
590                 return "ASLEEP";
591         case NM_STATE_DISCONNECTED:
592                 return "DISCONNECTED";
593         case NM_STATE_DISCONNECTING:
594                 return "DISCONNECTING";
595         case NM_STATE_CONNECTING:
596                 return "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:
604         default:
605                 return "UNKNOWN";
606         }
607 }
608
609 static void
610 set_state (NMManager *self, NMState state)
611 {
612         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
613
614         if (priv->state == state)
615                 return;
616
617         priv->state = state;
618
619         _LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
620
621         g_object_notify (G_OBJECT (self), NM_MANAGER_STATE);
622         g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state);
623 }
624
625 static void
626 checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
627 {
628         NMManager *manager = user_data;
629         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
630         NMConnectivityState connectivity;
631
632         if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
633                 connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
634
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);
641         }
642
643         g_object_unref (manager);
644 }
645
646 static NMState
647 find_best_device_state (NMManager *manager)
648 {
649         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
650         NMState best_state = NM_STATE_DISCONNECTED;
651         GSList *iter;
652
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);
656
657                 switch (ac_state) {
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;
663
664                                 best_state = NM_STATE_CONNECTED_SITE;
665                         } else {
666                                 if (best_state < NM_STATE_CONNECTING)
667                                         best_state = NM_STATE_CONNECTED_LOCAL;
668                         }
669                         break;
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;
674                         }
675                         break;
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;
680                         }
681                         break;
682                 default:
683                         break;
684                 }
685         }
686
687         return best_state;
688 }
689
690 static void
691 nm_manager_update_metered (NMManager *self)
692 {
693         NMManagerPrivate *priv;
694         NMDevice *device;
695         NMMetered value = NM_METERED_UNKNOWN;
696
697         g_return_if_fail (NM_IS_MANAGER (self));
698         priv = NM_MANAGER_GET_PRIVATE (self);
699
700         if (priv->primary_connection) {
701                 device =  nm_active_connection_get_device (priv->primary_connection);
702                 if (device)
703                         value = nm_device_get_metered (device);
704         }
705
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);
710         }
711 }
712
713 static void
714 nm_manager_update_state (NMManager *manager)
715 {
716         NMManagerPrivate *priv;
717         NMState new_state = NM_STATE_DISCONNECTED;
718
719         g_return_if_fail (NM_IS_MANAGER (manager));
720
721         priv = NM_MANAGER_GET_PRIVATE (manager);
722
723         if (manager_sleeping (manager))
724                 new_state = NM_STATE_ASLEEP;
725         else
726                 new_state = find_best_device_state (manager);
727
728         nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
729
730         if (new_state == NM_STATE_CONNECTED_SITE) {
731                 nm_connectivity_check_async (priv->connectivity,
732                                              checked_connectivity,
733                                              g_object_ref (manager));
734         }
735
736         set_state (manager, new_state);
737 }
738
739 static void
740 manager_device_state_changed (NMDevice *device,
741                               NMDeviceState new_state,
742                               NMDeviceState old_state,
743                               NMDeviceStateReason reason,
744                               gpointer user_data)
745 {
746         NMManager *self = NM_MANAGER (user_data);
747         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
748
749         switch (new_state) {
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);
756                 break;
757         default:
758                 break;
759         }
760
761         if (   new_state == NM_DEVICE_STATE_UNAVAILABLE
762             || new_state == NM_DEVICE_STATE_DISCONNECTED)
763                 nm_settings_device_added (priv->settings, device);
764 }
765
766 static void device_has_pending_action_changed (NMDevice *device,
767                                                GParamSpec *pspec,
768                                                NMManager *self);
769
770 static void
771 check_if_startup_complete (NMManager *self)
772 {
773         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
774         GSList *iter;
775
776         if (!priv->startup)
777                 return;
778
779         if (!priv->devices_inited)
780                 return;
781
782         if (!nm_settings_get_startup_complete (priv->settings)) {
783                 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
784                 return;
785         }
786
787         for (iter = priv->devices; iter; iter = iter->next) {
788                 NMDevice *dev = iter->data;
789
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));
793                         return;
794                 }
795         }
796
797         _LOGI (LOGD_CORE, "startup complete");
798
799         priv->startup = FALSE;
800         g_object_notify (G_OBJECT (self), "startup");
801
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;
805
806                 g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
807         }
808
809         if (nm_config_get_configure_and_quit (nm_config_get ()))
810                 g_signal_emit (self, signals[CONFIGURE_QUIT], 0);
811 }
812
813 static void
814 device_has_pending_action_changed (NMDevice *device,
815                                    GParamSpec *pspec,
816                                    NMManager *self)
817 {
818         check_if_startup_complete (self);
819 }
820
821 static void
822 settings_startup_complete_changed (NMSettings *settings,
823                                    GParamSpec *pspec,
824                                    NMManager *self)
825 {
826         check_if_startup_complete (self);
827 }
828
829 static void
830 remove_device (NMManager *self,
831                NMDevice *device,
832                gboolean quitting,
833                gboolean allow_unmanage)
834 {
835         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
836
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));
839
840         if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
841                 NMActRequest *req = nm_device_get_act_request (device);
842                 gboolean unmanage = FALSE;
843
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
847                  * cannot be left up.
848                  */
849                 if (!quitting)  /* Forced removal; device already gone */
850                         unmanage = TRUE;
851                 else if (!nm_device_can_assume_active_connection (device))
852                         unmanage = TRUE;
853                 else if (!req)
854                         unmanage = TRUE;
855
856                 if (unmanage) {
857                         if (quitting)
858                                 nm_device_set_unmanaged_by_quitting (device);
859                         else
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);
863                 }
864         }
865
866         g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
867
868         nm_settings_device_removed (priv->settings, device, quitting);
869         priv->devices = g_slist_remove (priv->devices, device);
870
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);
875         }
876         g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device);
877         g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
878
879         nm_exported_object_clear_and_unexport (&device);
880
881         check_if_startup_complete (self);
882 }
883
884 static void
885 device_removed_cb (NMDevice *device, gpointer user_data)
886 {
887         remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
888 }
889
890 NMState
891 nm_manager_get_state (NMManager *manager)
892 {
893         g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
894
895         return NM_MANAGER_GET_PRIVATE (manager)->state;
896 }
897
898 /***************************/
899
900 static NMDevice *
901 find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
902 {
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;
908         GSList *iter;
909
910         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
911
912         if (!cached_factory) {
913                 factory = nm_device_factory_manager_find_factory_for_connection (connection);
914                 if (!factory)
915                         return NULL;
916         } else
917                 factory = cached_factory;
918
919         parent_name = nm_device_factory_get_connection_parent (factory, connection);
920         if (!parent_name)
921                 return NULL;
922
923         /* Try as an interface name of a parent device */
924         parent = find_device_by_iface (self, parent_name, NULL, NULL);
925         if (parent)
926                 return parent;
927
928         /* Maybe a hardware address */
929         parent = find_device_by_hw_addr (self, parent_name);
930         if (parent)
931                 return parent;
932
933         /* Maybe a connection UUID */
934         parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name);
935         if (!parent_connection)
936                 return NULL;
937
938         /* Check if the parent connection is currently activated or is comaptible
939          * with some known device.
940          */
941         for (iter = priv->devices; iter; iter = iter->next) {
942                 NMDevice *candidate = iter->data;
943
944                 if (nm_device_get_settings_connection (candidate) == parent_connection)
945                         return candidate;
946
947                 if (   !first_compatible
948                     && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
949                         first_compatible = candidate;
950         }
951
952         return first_compatible;
953 }
954
955 /**
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
961  *
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.
966  *
967  * Returns: the expected interface name (caller takes ownership), or %NULL
968  */
969 char *
970 nm_manager_get_connection_iface (NMManager *self,
971                                  NMConnection *connection,
972                                  NMDevice **out_parent,
973                                  GError **error)
974 {
975         NMDeviceFactory *factory;
976         char *iface = NULL;
977         NMDevice *parent = NULL;
978
979         if (out_parent)
980                 *out_parent = NULL;
981
982         factory = nm_device_factory_manager_find_factory_for_connection (connection);
983         if (!factory) {
984                 g_set_error (error,
985                              NM_MANAGER_ERROR,
986                              NM_MANAGER_ERROR_FAILED,
987                              "NetworkManager plugin for '%s' unavailable",
988                              nm_connection_get_connection_type (connection));
989                 return NULL;
990         }
991
992         if (   !out_parent
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));
996                 if (!iface) {
997                         g_set_error (error,
998                                      NM_MANAGER_ERROR,
999                                      NM_MANAGER_ERROR_FAILED,
1000                                      "failed to determine interface name: error determine name for %s",
1001                                      nm_connection_get_connection_type (connection));
1002                 }
1003                 return iface;
1004         }
1005
1006         parent = find_parent_device_for_connection (self, connection, factory);
1007         iface = nm_device_factory_get_connection_iface (factory,
1008                                                         connection,
1009                                                         parent ? nm_device_get_ip_iface (parent) : NULL,
1010                                                         error);
1011         if (!iface)
1012                 return NULL;
1013
1014         if (out_parent)
1015                 *out_parent = parent;
1016         return iface;
1017 }
1018
1019 /**
1020  * system_create_virtual_device:
1021  * @self: the #NMManager
1022  * @connection: the connection which might require a virtual device
1023  *
1024  * If @connection requires a virtual device and one does not yet exist for it,
1025  * creates that device.
1026  *
1027  * Returns: A #NMDevice that was just realized; %NULL if none
1028  */
1029 static NMDevice *
1030 system_create_virtual_device (NMManager *self, NMConnection *connection)
1031 {
1032         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1033         NMDeviceFactory *factory;
1034         gs_free_slist GSList *connections = NULL;
1035         GSList *iter;
1036         gs_free char *iface = NULL;
1037         NMDevice *device = NULL, *parent = NULL;
1038         GError *error = NULL;
1039
1040         g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
1041         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
1042
1043         iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
1044         if (!iface) {
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);
1048                 return NULL;
1049         }
1050
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;
1054
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);
1059                                 return NULL;
1060                         }
1061
1062                         device = candidate;
1063                         break;
1064                 }
1065         }
1066
1067         if (!device) {
1068                 /* No matching device found. Proceed creating a new one. */
1069
1070                 factory = nm_device_factory_manager_find_factory_for_connection (connection);
1071                 if (!factory) {
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));
1075                         return NULL;
1076                 }
1077
1078                 device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, &error);
1079                 if (!device) {
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);
1083                         return NULL;
1084                 }
1085
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);
1091                         return NULL;
1092                 }
1093
1094                 /* Add device takes a reference that NMManager still owns, so it's
1095                  * safe to unref here and still return @device.
1096                  */
1097                 g_object_unref (device);
1098         }
1099
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;
1105
1106                 if (!nm_device_check_connection_compatible (device, candidate))
1107                         continue;
1108
1109                 s_con = nm_connection_get_setting_connection (candidate);
1110                 g_assert (s_con);
1111                 if (!nm_setting_connection_get_autoconnect (s_con))
1112                         continue;
1113
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);
1120                         return NULL;
1121                 }
1122                 break;
1123         }
1124
1125         return device;
1126 }
1127
1128 static void
1129 retry_connections_for_parent_device (NMManager *self, NMDevice *device)
1130 {
1131         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1132         GSList *connections, *iter;
1133
1134         g_return_if_fail (device);
1135
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;
1141                 NMDevice *parent;
1142
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);
1147                         if (ifname) {
1148                                 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
1149                                         connection_changed (priv->settings, candidate, self);
1150                         }
1151                 }
1152         }
1153
1154         g_slist_free (connections);
1155 }
1156
1157 static void
1158 connection_changed (NMSettings *settings,
1159                     NMConnection *connection,
1160                     NMManager *manager)
1161 {
1162         NMDevice *device;
1163
1164         if (!nm_connection_is_virtual (connection))
1165                 return;
1166
1167         device = system_create_virtual_device (manager, connection);
1168         if (!device)
1169                 return;
1170
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);
1175 }
1176
1177 static void
1178 connection_removed (NMSettings *settings,
1179                     NMSettingsConnection *connection,
1180                     NMManager *manager)
1181 {
1182         /*
1183          * Do not delete existing virtual devices to keep connectivity up.
1184          * Virtual devices are reused when NetworkManager is restarted.
1185          */
1186 }
1187
1188 static void
1189 system_unmanaged_devices_changed_cb (NMSettings *settings,
1190                                      GParamSpec *pspec,
1191                                      gpointer user_data)
1192 {
1193         NMManager *self = NM_MANAGER (user_data);
1194         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1195         const GSList *unmanaged_specs, *iter;
1196
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);
1200 }
1201
1202 static void
1203 system_hostname_changed_cb (NMSettings *settings,
1204                             GParamSpec *pspec,
1205                             gpointer user_data)
1206 {
1207         NMManager *self = NM_MANAGER (user_data);
1208         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1209         char *hostname;
1210
1211         hostname = nm_settings_get_hostname (priv->settings);
1212
1213         /* nm_settings_get_hostname() does not return an empty hostname. */
1214         nm_assert (!hostname || *hostname);
1215
1216         if (!hostname && !priv->hostname)
1217                 return;
1218         if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) {
1219                 g_free (hostname);
1220                 return;
1221         }
1222
1223         /* realloc, to free possibly trailing data after NUL. */
1224         if (hostname)
1225                 hostname = g_realloc (hostname, strlen (hostname) + 1);
1226
1227         g_free (priv->hostname);
1228         priv->hostname = hostname;
1229         g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
1230
1231         nm_dhcp_manager_set_default_hostname (nm_dhcp_manager_get (), priv->hostname);
1232 }
1233
1234 /*******************************************************************/
1235 /* General NMManager stuff                                         */
1236 /*******************************************************************/
1237
1238 /* Store value into key-file; supported types: boolean, int, string */
1239 static gboolean
1240 write_value_to_state_file (const char *filename,
1241                            const char *group,
1242                            const char *key,
1243                            GType value_type,
1244                            gpointer value,
1245                            GError **error)
1246 {
1247         GKeyFile *key_file;
1248         char *data;
1249         gsize len = 0;
1250         gboolean ret = FALSE;
1251
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,
1258                               FALSE);
1259
1260         key_file = g_key_file_new ();
1261
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));
1267                 break;
1268         case G_TYPE_INT:
1269                 g_key_file_set_integer (key_file, group, key, *((gint *) value));
1270                 break;
1271         case G_TYPE_STRING:
1272                 g_key_file_set_string (key_file, group, key, *((const gchar **) value));
1273                 break;
1274         }
1275
1276         data = g_key_file_to_data (key_file, &len, NULL);
1277         if (data) {
1278                 ret = g_file_set_contents (filename, data, len, error);
1279                 g_free (data);
1280         }
1281         g_key_file_free (key_file);
1282
1283         return ret;
1284 }
1285
1286 static gboolean
1287 radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
1288 {
1289         gboolean enabled;
1290
1291         enabled = rstate->user_enabled && rstate->hw_enabled;
1292         if (check_changeable)
1293                 enabled &= rstate->sw_enabled;
1294         return enabled;
1295 }
1296
1297 static gboolean
1298 radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
1299 {
1300         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1301
1302         return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
1303 }
1304
1305 static void
1306 manager_update_radio_enabled (NMManager *self,
1307                               RadioState *rstate,
1308                               gboolean enabled)
1309 {
1310         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1311         GSList *iter;
1312
1313         /* Do nothing for radio types not yet implemented */
1314         if (!rstate->prop)
1315                 return;
1316
1317         g_object_notify (G_OBJECT (self), rstate->prop);
1318
1319         /* Don't touch devices if asleep/networking disabled */
1320         if (manager_sleeping (self))
1321                 return;
1322
1323         /* enable/disable wireless devices as required */
1324         for (iter = priv->devices; iter; iter = iter->next) {
1325                 NMDevice *device = NM_DEVICE (iter->data);
1326
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);
1332                 }
1333         }
1334 }
1335
1336 static void
1337 update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate)
1338 {
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;
1343                 break;
1344         case RFKILL_SOFT_BLOCKED:
1345                 rstate->sw_enabled = FALSE;
1346                 rstate->hw_enabled = TRUE;
1347                 break;
1348         case RFKILL_HARD_BLOCKED:
1349                 rstate->sw_enabled = FALSE;
1350                 rstate->hw_enabled = FALSE;
1351                 break;
1352         default:
1353                 g_warn_if_reached ();
1354                 break;
1355         }
1356 }
1357
1358 static void
1359 manager_rfkill_update_one_type (NMManager *self,
1360                                 RadioState *rstate,
1361                                 RfKillType rtype)
1362 {
1363         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1364         gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
1365
1366         old_enabled = radio_enabled_for_rstate (rstate, TRUE);
1367         old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1368         old_hwe = rstate->hw_enabled;
1369
1370         /* recheck kernel rfkill state */
1371         update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
1372
1373         /* Print out all states affecting device enablement */
1374         if (rstate->desc) {
1375                 _LOGD (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
1376                        rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
1377         }
1378
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",
1383                        rstate->desc,
1384                        new_rfkilled ? "enabled" : "disabled");
1385         }
1386
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);
1391         }
1392
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.
1397          */
1398         new_enabled = radio_enabled_for_rstate (rstate, TRUE);
1399         if (new_enabled != old_enabled)
1400                 manager_update_radio_enabled (self, rstate, new_enabled);
1401 }
1402
1403 static void
1404 nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
1405 {
1406         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1407         guint i;
1408
1409         if (rtype != RFKILL_TYPE_UNKNOWN)
1410                 manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
1411         else {
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);
1415         }
1416 }
1417
1418 static void
1419 device_auth_done_cb (NMAuthChain *chain,
1420                      GError *auth_error,
1421                      GDBusMethodInvocation *context,
1422                      gpointer user_data)
1423 {
1424         NMManager *self = NM_MANAGER (user_data);
1425         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1426         GError *error = NULL;
1427         NMAuthCallResult result;
1428         NMDevice *device;
1429         const char *permission;
1430         NMDeviceAuthRequestFunc callback;
1431         NMAuthSubject *subject;
1432
1433         g_assert (context);
1434
1435         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
1436
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");
1442         g_assert (device);
1443
1444         result = nm_auth_chain_get_result (chain, permission);
1445         subject = nm_auth_chain_get_subject (chain);
1446
1447         if (auth_error) {
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",
1459                                      permission);
1460         }
1461
1462         g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
1463
1464         callback (device,
1465                   context,
1466                   subject,
1467                   error,
1468                   nm_auth_chain_get_data (chain, "user-data"));
1469
1470         g_clear_error (&error);
1471         nm_auth_chain_unref (chain);
1472 }
1473
1474 static void
1475 device_auth_request_cb (NMDevice *device,
1476                         GDBusMethodInvocation *context,
1477                         NMConnection *connection,
1478                         const char *permission,
1479                         gboolean allow_interaction,
1480                         NMDeviceAuthRequestFunc callback,
1481                         gpointer user_data,
1482                         NMManager *self)
1483 {
1484         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1485         GError *error = NULL;
1486         NMAuthSubject *subject = NULL;
1487         char *error_desc = NULL;
1488         NMAuthChain *chain;
1489
1490         /* Validate the caller */
1491         subject = nm_auth_subject_new_unix_process_from_context (context);
1492         if (!subject) {
1493                 error = g_error_new_literal (NM_MANAGER_ERROR,
1494                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1495                                              "Failed to get request UID.");
1496                 goto done;
1497         }
1498
1499         /* Ensure the subject has permissions for this connection */
1500         if (connection && !nm_auth_is_subject_in_acl (connection,
1501                                                       subject,
1502                                                       &error_desc)) {
1503                 error = g_error_new_literal (NM_MANAGER_ERROR,
1504                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1505                                              error_desc);
1506                 g_free (error_desc);
1507                 goto done;
1508         }
1509
1510         /* Validate the request */
1511         chain = nm_auth_chain_new_subject (subject, context, device_auth_done_cb, self);
1512         if (!chain) {
1513                 error = g_error_new_literal (NM_MANAGER_ERROR,
1514                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1515                                              "Unable to authenticate request.");
1516                 goto done;
1517         }
1518
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);
1525
1526 done:
1527         if (error)
1528                 callback (device, context, subject, error, user_data);
1529
1530         g_clear_object (&subject);
1531         g_clear_error (&error);
1532 }
1533
1534 static gboolean
1535 match_connection_filter (NMConnection *connection, gpointer user_data)
1536 {
1537         if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
1538                 return FALSE;
1539
1540         return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
1541 }
1542
1543 /**
1544  * get_existing_connection:
1545  * @manager: #NMManager instance
1546  * @device: #NMDevice instance
1547  * @out_generated: (allow-none): return TRUE, if the connection was generated.
1548  *
1549  * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
1550  *   the device does not support assuming existing connections.
1551  */
1552 static NMSettingsConnection *
1553 get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
1554 {
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);
1563
1564         if (out_generated)
1565                 *out_generated = FALSE;
1566
1567         nm_device_capture_initial_config (device);
1568
1569         if (ifindex) {
1570                 int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex);
1571
1572                 if (master_ifindex) {
1573                         master = nm_manager_get_device_by_ifindex (self, master_ifindex);
1574                         if (!master) {
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);
1577                                 return NULL;
1578                         }
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));
1582                                 return NULL;
1583                         }
1584                 }
1585         }
1586
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()
1591          * returns NULL.
1592          */
1593         connection = nm_device_generate_connection (device, master);
1594         if (!connection)
1595                 return NULL;
1596
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.
1602          *
1603          * When no configured connection matches the generated connection, we keep
1604          * the generated connection instead.
1605          */
1606         connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections));
1607         matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
1608                                                                      connection,
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,
1613                                                                      device));
1614         if (matched) {
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);
1619                 return matched;
1620         }
1621
1622         _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
1623                nm_device_get_iface (device),
1624                nm_connection_get_id (connection));
1625
1626         added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
1627         if (added) {
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,
1631                                                   TRUE);
1632                 if (out_generated)
1633                         *out_generated = TRUE;
1634         } else {
1635                 _LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
1636                        nm_device_get_iface (device),
1637                        nm_connection_get_id (connection),
1638                        error->message);
1639                 g_clear_error (&error);
1640         }
1641         g_object_unref (connection);
1642
1643         return added ? added : NULL;
1644 }
1645
1646 static gboolean
1647 assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
1648 {
1649         NMActiveConnection *active, *master_ac;
1650         NMAuthSubject *subject;
1651         GError *error = NULL;
1652
1653         _LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
1654                nm_device_get_iface (device));
1655
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);
1661         }
1662         g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1663
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);
1667
1668         if (!active) {
1669                 _LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
1670                        nm_connection_get_path (NM_CONNECTION (connection)),
1671                        error->message);
1672                 g_error_free (error);
1673                 return FALSE;
1674         }
1675
1676         /* If the device is a slave or VLAN, find the master ActiveConnection */
1677         master_ac = NULL;
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);
1680
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);
1686
1687         return TRUE;
1688 }
1689
1690 static gboolean
1691 recheck_assume_connection (NMManager *self, NMDevice *device)
1692 {
1693         NMSettingsConnection *connection;
1694         gboolean was_unmanaged = FALSE, success, generated = FALSE;
1695         NMDeviceState state;
1696
1697         g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
1698         g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1699
1700         if (nm_device_get_is_nm_owned (device))
1701                 return FALSE;
1702
1703         if (!nm_device_get_managed (device, FALSE))
1704                 return FALSE;
1705
1706         state = nm_device_get_state (device);
1707         if (state > NM_DEVICE_STATE_DISCONNECTED)
1708                 return FALSE;
1709
1710         connection = get_existing_connection (self, device, &generated);
1711         if (!connection) {
1712                 _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
1713                        nm_device_get_iface (device));
1714                 return FALSE;
1715         }
1716
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);
1722         }
1723
1724         success = assume_connection (self, device, connection);
1725         if (!success) {
1726                 if (was_unmanaged) {
1727                         nm_device_state_changed (device,
1728                                                  NM_DEVICE_STATE_UNAVAILABLE,
1729                                                  NM_DEVICE_STATE_REASON_CONFIG_FAILED);
1730                 }
1731
1732                 if (generated) {
1733                         _LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
1734                                nm_device_get_iface (device));
1735
1736                         nm_settings_connection_delete (connection, NULL, NULL);
1737                 }
1738         }
1739
1740         return success;
1741 }
1742
1743 static void
1744 recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
1745 {
1746         recheck_assume_connection (user_data, device);
1747 }
1748
1749 static void
1750 device_ip_iface_changed (NMDevice *device,
1751                          GParamSpec *pspec,
1752                          NMManager *self)
1753 {
1754         const char *ip_iface = nm_device_get_ip_iface (device);
1755         GSList *iter;
1756
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.
1761          */
1762         for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
1763                 NMDevice *candidate = NM_DEVICE (iter->data);
1764
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);
1769                         break;
1770                 }
1771         }
1772 }
1773
1774 static void
1775 device_iface_changed (NMDevice *device,
1776                       GParamSpec *pspec,
1777                       NMManager *self)
1778 {
1779         /* Virtual connections may refer to the new device name as
1780          * parent device, retry to activate them.
1781          */
1782         retry_connections_for_parent_device (self, device);
1783 }
1784
1785
1786 static void
1787 device_realized (NMDevice *device,
1788                  GParamSpec *pspec,
1789                  NMManager *self)
1790 {
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);
1794 }
1795
1796 static void
1797 _device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
1798 {
1799         g_return_if_fail (NM_IS_MANAGER (self));
1800         g_return_if_fail (NM_IS_DEVICE (device));
1801
1802         nm_device_realize_finish (device, plink);
1803
1804         if (!nm_device_get_managed (device, FALSE))
1805                 return;
1806
1807         if (recheck_assume_connection (self, device))
1808                 return;
1809
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);
1816 }
1817
1818 /**
1819  * add_device:
1820  * @self: the #NMManager
1821  * @device: the #NMDevice to add
1822  * @error: (out): the #GError
1823  *
1824  * If successful, this function will increase the references count of @device.
1825  * Callers should decrease the reference count.
1826  */
1827 static gboolean
1828 add_device (NMManager *self, NMDevice *device, GError **error)
1829 {
1830         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1831         const char *iface, *type_desc;
1832         RfKillType rtype;
1833         GSList *iter, *remove = NULL;
1834         int ifindex;
1835         const char *dbus_path;
1836
1837         /* No duplicates */
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);
1842                 return FALSE;
1843         }
1844
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.
1848          *
1849          * FIXME: use parent/child device relationships instead of removing
1850          * the child NMDevice entirely
1851          */
1852         for (iter = priv->devices; iter; iter = iter->next) {
1853                 NMDevice *candidate = iter->data;
1854
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);
1858         }
1859         for (iter = remove; iter; iter = iter->next)
1860                 remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
1861         g_slist_free (remove);
1862
1863         priv->devices = g_slist_append (priv->devices, g_object_ref (device));
1864
1865         g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
1866                           G_CALLBACK (manager_device_state_changed),
1867                           self);
1868
1869         g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
1870                           G_CALLBACK (device_auth_request_cb),
1871                           self);
1872
1873         g_signal_connect (device, NM_DEVICE_REMOVED,
1874                           G_CALLBACK (device_removed_cb),
1875                           self);
1876
1877         g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
1878                           G_CALLBACK (recheck_assume_connection_cb),
1879                           self);
1880
1881         g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
1882                           G_CALLBACK (device_ip_iface_changed),
1883                           self);
1884
1885         g_signal_connect (device, "notify::" NM_DEVICE_IFACE,
1886                           G_CALLBACK (device_iface_changed),
1887                           self);
1888
1889         g_signal_connect (device, "notify::" NM_DEVICE_REAL,
1890                           G_CALLBACK (device_realized),
1891                           self);
1892
1893         if (priv->startup) {
1894                 g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
1895                                   G_CALLBACK (device_has_pending_action_changed),
1896                                   self);
1897         }
1898
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
1901          * global state.
1902          */
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));
1907         }
1908
1909         iface = nm_device_get_iface (device);
1910         g_assert (iface);
1911         type_desc = nm_device_get_type_desc (device);
1912         g_assert (type_desc);
1913
1914         nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings));
1915
1916         nm_device_set_unmanaged_flags (device,
1917                                        NM_UNMANAGED_SLEEPING,
1918                                        manager_sleeping (self));
1919
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);
1922
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);
1926
1927         for (iter = priv->devices; iter; iter = iter->next) {
1928                 NMDevice *d = iter->data;
1929
1930                 if (d != device)
1931                         nm_device_notify_new_device_added (d, device);
1932         }
1933
1934         /* Virtual connections may refer to the new device as
1935          * parent device, retry to activate them.
1936          */
1937         retry_connections_for_parent_device (self, device);
1938
1939         return TRUE;
1940 }
1941
1942 /*******************************************************************/
1943
1944 static void
1945 factory_device_added_cb (NMDeviceFactory *factory,
1946                          NMDevice *device,
1947                          gpointer user_data)
1948 {
1949         NMManager *self = user_data;
1950         GError *error = NULL;
1951
1952         g_return_if_fail (NM_IS_MANAGER (self));
1953
1954         if (nm_device_realize_start (device, NULL, NULL, &error)) {
1955                 add_device (self, device, NULL);
1956                 _device_realize_finish (self, device, NULL);
1957         } else {
1958                 _LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
1959                        nm_device_get_iface (device), error->message);
1960                 g_error_free (error);
1961         }
1962 }
1963
1964 static gboolean
1965 factory_component_added_cb (NMDeviceFactory *factory,
1966                             GObject *component,
1967                             gpointer user_data)
1968 {
1969         GSList *iter;
1970
1971         g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE);
1972
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))
1975                         return TRUE;
1976         }
1977         return FALSE;
1978 }
1979
1980 static void
1981 _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
1982 {
1983         NMManager *self = NM_MANAGER (user_data);
1984
1985         g_signal_connect (factory,
1986                           NM_DEVICE_FACTORY_DEVICE_ADDED,
1987                           G_CALLBACK (factory_device_added_cb),
1988                           self);
1989         g_signal_connect (factory,
1990                           NM_DEVICE_FACTORY_COMPONENT_ADDED,
1991                           G_CALLBACK (factory_component_added_cb),
1992                           self);
1993 }
1994
1995 /*******************************************************************/
1996
1997 static void
1998 platform_link_added (NMManager *self,
1999                      int ifindex,
2000                      const NMPlatformLink *plink)
2001 {
2002         NMDeviceFactory *factory;
2003         NMDevice *device = NULL;
2004         GError *error = NULL;
2005         gboolean nm_plugin_missing = FALSE;
2006         GSList *iter;
2007
2008         g_return_if_fail (ifindex > 0);
2009
2010         if (nm_manager_get_device_by_ifindex (self, ifindex))
2011                 return;
2012
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;
2017
2018                 if (strcmp (nm_device_get_iface (candidate), plink->name))
2019                         continue;
2020
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.
2024                          */
2025                         return;
2026                 } else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
2027                         /* Success */
2028                         _device_realize_finish (self, candidate, plink);
2029                         return;
2030                 }
2031
2032                 _LOGD (LOGD_DEVICE, "(%s): failed to realize from plink: '%s'",
2033                        plink->name, error->message);
2034                 g_clear_error (&error);
2035
2036                 /* Try next unrealized device */
2037         }
2038
2039         /* Try registered device factories */
2040         factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
2041         if (factory) {
2042                 gboolean ignore = FALSE;
2043
2044                 device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
2045                 if (!device) {
2046                         if (!ignore) {
2047                                 _LOGW (LOGD_HW, "%s: factory failed to create device: %s",
2048                                        plink->name, error->message);
2049                                 g_clear_error (&error);
2050                         }
2051                         return;
2052                 }
2053         }
2054
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;
2065                         /* fall through */
2066                 default:
2067                         device = nm_device_generic_new (plink);
2068                         break;
2069                 }
2070         }
2071
2072         if (device) {
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);
2078                 } else {
2079                         _LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
2080                                plink->name, error->message);
2081                         g_clear_error (&error);
2082                 }
2083                 g_object_unref (device);
2084         }
2085 }
2086
2087 typedef struct {
2088         NMManager *self;
2089         int ifindex;
2090 } PlatformLinkCbData;
2091
2092 static gboolean
2093 _platform_link_cb_idle (PlatformLinkCbData *data)
2094 {
2095         NMManager *self = data->self;
2096         const NMPlatformLink *l;
2097
2098         if (!self)
2099                 goto out;
2100
2101         g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
2102
2103         l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
2104         if (l) {
2105                 NMPlatformLink pllink;
2106
2107                 pllink = *l; /* make a copy of the link instance */
2108                 platform_link_added (self, data->ifindex, &pllink);
2109         } else {
2110                 NMDevice *device;
2111                 GError *error = NULL;
2112
2113                 device = nm_manager_get_device_by_ifindex (self, data->ifindex);
2114                 if (device) {
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),
2120                                                error->message);
2121                                         g_clear_error (&error);
2122                                         remove_device (self, device, FALSE, TRUE);
2123                                 }
2124                         } else {
2125                                 /* Hardware and external devices always get removed when their kernel link is gone */
2126                                 remove_device (self, device, FALSE, TRUE);
2127                         }
2128                 }
2129         }
2130
2131 out:
2132         g_slice_free (PlatformLinkCbData, data);
2133         return G_SOURCE_REMOVE;
2134 }
2135
2136 static void
2137 platform_link_cb (NMPlatform *platform,
2138                   NMPObjectType obj_type,
2139                   int ifindex,
2140                   NMPlatformLink *plink,
2141                   NMPlatformSignalChangeType change_type,
2142                   gpointer user_data)
2143 {
2144         PlatformLinkCbData *data;
2145
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);
2154                 break;
2155         default:
2156                 break;
2157         }
2158 }
2159
2160 static void
2161 platform_query_devices (NMManager *self)
2162 {
2163         GArray *links_array;
2164         NMPlatformLink *links;
2165         int i;
2166
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]);
2171
2172         g_array_unref (links_array);
2173 }
2174
2175 static void
2176 rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
2177                                   RfKillType rtype,
2178                                   RfKillState udev_state,
2179                                   gpointer user_data)
2180 {
2181         nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
2182 }
2183
2184 const GSList *
2185 nm_manager_get_devices (NMManager *manager)
2186 {
2187         g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2188
2189         return NM_MANAGER_GET_PRIVATE (manager)->devices;
2190 }
2191
2192 static NMDevice *
2193 nm_manager_get_connection_device (NMManager *self,
2194                                   NMConnection *connection)
2195 {
2196         NMActiveConnection *ac = find_ac_for_connection (self, connection);
2197         if (ac == NULL)
2198                 return NULL;
2199
2200         return nm_active_connection_get_device (ac);
2201 }
2202
2203 static NMDevice *
2204 nm_manager_get_best_device_for_connection (NMManager *self,
2205                                            NMConnection *connection,
2206                                            gboolean for_user_request)
2207 {
2208         const GSList *devices, *iter;
2209         NMDevice *act_device = nm_manager_get_connection_device (self, connection);
2210         NMDeviceCheckConAvailableFlags flags;
2211
2212         if (act_device)
2213                 return act_device;
2214
2215         flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
2216
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);
2221
2222                 if (nm_device_check_connection_available (device, connection, flags, NULL))
2223                         return device;
2224         }
2225
2226         /* No luck. :( */
2227         return NULL;
2228 }
2229
2230 static void
2231 _get_devices (NMManager *self,
2232               GDBusMethodInvocation *context,
2233               gboolean all_devices)
2234 {
2235         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2236         gs_free const char **paths = NULL;
2237         guint i;
2238         GSList *iter;
2239
2240         paths = g_new (const char *, g_slist_length (priv->devices) + 1);
2241
2242         for (i = 0, iter = priv->devices; iter; iter = iter->next) {
2243                 const char *path;
2244
2245                 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
2246                 if (   path
2247                     && (all_devices || nm_device_is_real (iter->data)))
2248                         paths[i++] = path;
2249         }
2250         paths[i++] = NULL;
2251
2252         g_dbus_method_invocation_return_value (context,
2253                                                g_variant_new ("(^ao)", (char **) paths));
2254 }
2255
2256 static void
2257 impl_manager_get_devices (NMManager *self,
2258                           GDBusMethodInvocation *context)
2259 {
2260         _get_devices (self, context, FALSE);
2261 }
2262
2263 static void
2264 impl_manager_get_all_devices (NMManager *self,
2265                               GDBusMethodInvocation *context)
2266 {
2267         _get_devices (self, context, TRUE);
2268 }
2269
2270 static void
2271 impl_manager_get_device_by_ip_iface (NMManager *self,
2272                                      GDBusMethodInvocation *context,
2273                                      const char *iface)
2274 {
2275         NMDevice *device;
2276         const char *path = NULL;
2277
2278         device = find_device_by_ip_iface (self, iface);
2279         if (device)
2280                 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
2281
2282         if (path == NULL) {
2283                 g_dbus_method_invocation_return_error (context,
2284                                                        NM_MANAGER_ERROR,
2285                                                        NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2286                                                        "No device found for the requested iface.");
2287         } else {
2288                 g_dbus_method_invocation_return_value (context,
2289                                                        g_variant_new ("(o)", path));
2290         }
2291 }
2292
2293 static gboolean
2294 is_compatible_with_slave (NMConnection *master, NMConnection *slave)
2295 {
2296         NMSettingConnection *s_con;
2297
2298         g_return_val_if_fail (master, FALSE);
2299         g_return_val_if_fail (slave, FALSE);
2300
2301         s_con = nm_connection_get_setting_connection (slave);
2302         g_assert (s_con);
2303
2304         return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
2305 }
2306
2307 /**
2308  * find_master:
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
2319  *
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.
2323  *
2324  * If @connection does have a master, then the outputs depend on what is in its
2325  * #NMSettingConnection:master property:
2326  *
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
2332  * will be returned.
2333  *
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).
2339  *
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.)
2345  *
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
2348  **/
2349 static gboolean
2350 find_master (NMManager *self,
2351              NMConnection *connection,
2352              NMDevice *device,
2353              NMSettingsConnection **out_master_connection,
2354              NMDevice **out_master_device,
2355              NMActiveConnection **out_master_ac,
2356              GError **error)
2357 {
2358         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2359         NMSettingConnection *s_con;
2360         const char *master;
2361         NMDevice *master_device = NULL;
2362         NMSettingsConnection *master_connection = NULL;
2363         GSList *iter;
2364
2365         s_con = nm_connection_get_setting_connection (connection);
2366         g_assert (s_con);
2367         master = nm_setting_connection_get_master (s_con);
2368
2369         if (master == NULL)
2370                 return TRUE;  /* success, but no master */
2371
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");
2378                         return FALSE;
2379                 }
2380
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));
2387                         return FALSE;
2388                 }
2389         } else {
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);
2396
2397                                 if (candidate == device)
2398                                         continue;
2399
2400                                 if (nm_device_get_settings_connection (candidate) == master_connection) {
2401                                         master_device = candidate;
2402                                         break;
2403                                 }
2404                         }
2405                 }
2406         }
2407
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));
2414
2415         if (master_device || master_connection)
2416                 return TRUE;
2417         else {
2418                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2419                                      "Master connection not found or invalid");
2420                 return FALSE;
2421         }
2422 }
2423
2424 /**
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
2433  *
2434  * Determines whether a given #NMConnection depends on another connection to
2435  * be activated, and if so, finds that master connection or creates it.
2436  *
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.
2440  *
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.
2445  *
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.
2448  *
2449  * Returns: the master #NMActiveConnection that the caller should depend on, or
2450  * %NULL if an error occurred
2451  */
2452 static NMActiveConnection *
2453 ensure_master_active_connection (NMManager *self,
2454                                  NMAuthSubject *subject,
2455                                  NMConnection *connection,
2456                                  NMDevice *device,
2457                                  NMSettingsConnection *master_connection,
2458                                  NMDevice *master_device,
2459                                  GError **error)
2460 {
2461         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2462         NMActiveConnection *master_ac = NULL;
2463         NMDeviceState master_state;
2464         GSList *iter;
2465
2466         g_assert (connection);
2467         g_assert (master_connection || master_device);
2468
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.
2471          */
2472         if (master_device) {
2473                 NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device);
2474
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().
2477                  */
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));
2484                         return NULL;
2485                 }
2486
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));
2493                 }
2494
2495                 /* If the device is disconnected, find a compatible connection and
2496                  * activate it on the device.
2497                  */
2498                 if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
2499                         GSList *connections;
2500
2501                         g_assert (master_connection == NULL);
2502
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);
2507
2508                                 /* Ensure eg bond/team slave and the candidate master is a
2509                                  * bond/team master
2510                                  */
2511                                 if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
2512                                         continue;
2513
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,
2516                                                                                     candidate,
2517                                                                                     NULL,
2518                                                                                     master_device,
2519                                                                                     subject,
2520                                                                                     error);
2521                                         if (!master_ac)
2522                                                 g_prefix_error (error, "%s", "Master device activation failed: ");
2523                                         g_slist_free (connections);
2524                                         return master_ac;
2525                                 }
2526                         }
2527                         g_slist_free (connections);
2528
2529                         g_set_error (error,
2530                                      NM_MANAGER_ERROR,
2531                                      NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2532                                      "No compatible connection found for master device %s.",
2533                                      nm_device_get_iface (master_device));
2534                         return NULL;
2535                 }
2536
2537                 /* Otherwise, the device is unmanaged, unavailable, or disconnecting */
2538                 g_set_error (error,
2539                              NM_MANAGER_ERROR,
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;
2545
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);
2549
2550                         if (candidate == device) {
2551                                 /* A device obviously can't be its own master */
2552                                 continue;
2553                         }
2554
2555                         if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
2556                                 continue;
2557
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)
2562                                         continue;
2563                         }
2564
2565                         master_ac = nm_manager_activate_connection (self,
2566                                                                     master_connection,
2567                                                                     NULL,
2568                                                                     candidate,
2569                                                                     subject,
2570                                                                     error);
2571                         if (!master_ac)
2572                                 g_prefix_error (error, "%s", "Master device activation failed: ");
2573                         return master_ac;
2574                 }
2575
2576                 g_set_error (error,
2577                              NM_MANAGER_ERROR,
2578                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2579                              "No compatible disconnected device found for master connection %s.",
2580                              nm_settings_connection_get_uuid (master_connection));
2581         } else
2582                 g_assert_not_reached ();
2583
2584         return NULL;
2585 }
2586
2587 /**
2588  * find_slaves:
2589  * @manager: #NMManager object
2590  * @connection: the master #NMSettingsConnection to find slave connections for
2591  * @device: the master #NMDevice for the @connection
2592  *
2593  * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
2594  * master, or has not any slaves, this will return %NULL.
2595  *
2596  * Returns: list of slave connections for given master @connection, or %NULL
2597  **/
2598 static GSList *
2599 find_slaves (NMManager *manager,
2600              NMSettingsConnection *connection,
2601              NMDevice *device)
2602 {
2603         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
2604         GSList *all_connections, *iter;
2605         GSList *slaves = NULL;
2606         NMSettingConnection *s_con;
2607         const char *master;
2608
2609         s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
2610         g_assert (s_con);
2611         master = nm_setting_connection_get_master (s_con);
2612
2613         if (master != NULL)
2614                 return NULL;  /* connection is not master */
2615
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.
2619          */
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;
2625
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);
2630                 }
2631         }
2632         g_slist_free (all_connections);
2633
2634         return g_slist_reverse (slaves);
2635 }
2636
2637 static gboolean
2638 should_connect_slaves (NMConnection *connection, NMDevice *device)
2639 {
2640         NMSettingConnection *s_con;
2641         NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
2642         gs_free char *value = NULL;
2643
2644         s_con = nm_connection_get_setting_connection (connection);
2645         g_assert (s_con);
2646
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)
2650                 goto out;
2651
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);
2655         if (value)
2656                 autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
2657
2658 out:
2659         if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
2660                 return FALSE;
2661         if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
2662                 return TRUE;
2663         return FALSE;
2664 }
2665
2666 static gboolean
2667 autoconnect_slaves (NMManager *self,
2668                     NMSettingsConnection *master_connection,
2669                     NMDevice *master_device,
2670                     NMAuthSubject *subject)
2671 {
2672         GError *local_err = NULL;
2673         gboolean ret = FALSE;
2674
2675         if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
2676                 GSList *slaves, *iter;
2677
2678                 iter = slaves = find_slaves (self, master_connection, master_device);
2679                 ret = slaves != NULL;
2680
2681                 while (iter) {
2682                         NMSettingsConnection *slave_connection = iter->data;
2683
2684                         iter = iter->next;
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));
2690
2691                         /* Schedule slave activation */
2692                         nm_manager_activate_connection (self,
2693                                                         slave_connection,
2694                                                         NULL,
2695                                                         nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
2696                                                         subject,
2697                                                         &local_err);
2698                         if (local_err) {
2699                                 _LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
2700                                 g_error_free (local_err);
2701                         }
2702                 }
2703                 g_slist_free (slaves);
2704         }
2705         return ret;
2706 }
2707
2708 static gboolean
2709 _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **error)
2710 {
2711         gboolean success;
2712
2713         g_assert (NM_IS_VPN_CONNECTION (active));
2714
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),
2718                                                       error);
2719         if (success)
2720                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2721         else
2722                 nm_exported_object_unexport (NM_EXPORTED_OBJECT (active));
2723         return success;
2724 }
2725
2726 static gboolean
2727 _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
2728 {
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;
2737
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);
2741
2742         g_assert (NM_IS_VPN_CONNECTION (active) == FALSE);
2743
2744         connection = nm_active_connection_get_settings_connection (active);
2745         g_assert (connection);
2746
2747         applied = nm_active_connection_get_applied_connection (active);
2748
2749         device = nm_active_connection_get_device (active);
2750         g_return_val_if_fail (device != NULL, FALSE);
2751
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.
2756          */
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,
2761                                         subject,
2762                                         &error_desc)) {
2763                 g_set_error (error,
2764                              NM_MANAGER_ERROR,
2765                              NM_MANAGER_ERROR_PERMISSION_DENIED,
2766                              "Private connection already active on the device: %s",
2767                              error_desc);
2768                 g_free (error_desc);
2769                 return FALSE;
2770         }
2771
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));
2777                 return FALSE;
2778         }
2779
2780         /* Create any backing resources the device needs */
2781         if (!nm_device_is_real (device)) {
2782                 NMDevice *parent;
2783
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));
2787                         return FALSE;
2788                 }
2789         }
2790
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,
2794                           error))
2795                 return FALSE;
2796
2797         /* Ensure there's a master active connection the new connection we're
2798          * activating can depend on.
2799          */
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));
2805                 }
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));
2810                 }
2811
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");
2816                         return FALSE;
2817                 }
2818
2819                 if (!master_ac) {
2820                         master_ac = ensure_master_active_connection (self,
2821                                                                      nm_active_connection_get_subject (active),
2822                                                                      applied,
2823                                                                      device,
2824                                                                      master_connection,
2825                                                                      master_device,
2826                                                                      error);
2827                         if (!master_ac) {
2828                                 if (error)
2829                                         g_assert (*error);
2830                                 return FALSE;
2831                         }
2832                 }
2833
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),
2837                        master_ac,
2838                        nm_exported_object_get_path (NM_EXPORTED_OBJECT  (master_ac)) ?: "");
2839         }
2840
2841         /* Check slaves for master connection and possibly activate them */
2842         autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
2843
2844         /* Disconnect the connection if connected or queued on another device */
2845         existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
2846         if (existing)
2847                 nm_device_steal_connection (existing, connection);
2848
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);
2854
2855         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_USER_EXPLICIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2856
2857         g_return_val_if_fail (nm_device_get_managed (device, FALSE), FALSE);
2858
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);
2863         }
2864
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);
2870         }
2871
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));
2876         return TRUE;
2877 }
2878
2879 static gboolean
2880 _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError **error)
2881 {
2882         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2883         gboolean success = FALSE;
2884
2885         /* Ensure activation request is still valid, eg that its device hasn't gone
2886          * away or that some other dependency has not failed.
2887          */
2888         if (nm_active_connection_get_state (active) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
2889                 g_set_error_literal (error,
2890                                      NM_MANAGER_ERROR,
2891                                      NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2892                                      "Activation failed because dependencies failed.");
2893                 return FALSE;
2894         }
2895
2896         if (NM_IS_VPN_CONNECTION (active))
2897                 success = _internal_activate_vpn (self, active, error);
2898         else
2899                 success = _internal_activate_device (self, active, error);
2900
2901         if (success) {
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
2907                  * is up-to-date.
2908                  */
2909                 active_connection_add (self, active);
2910                 policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
2911         }
2912
2913         return success;
2914 }
2915
2916 static NMActiveConnection *
2917 _new_vpn_active_connection (NMManager *self,
2918                             NMSettingsConnection *settings_connection,
2919                             const char *specific_object,
2920                             NMAuthSubject *subject,
2921                             GError **error)
2922 {
2923         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2924         NMActiveConnection *parent = NULL;
2925         NMDevice *device = NULL;
2926
2927         g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
2928
2929         if (specific_object) {
2930                 /* Find the specific connection the client requested we use */
2931                 parent = active_connection_get_by_path (self, specific_object);
2932                 if (!parent) {
2933                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
2934                                              "Base connection for VPN connection not active.");
2935                         return NULL;
2936                 }
2937         } else
2938                 parent = priv->primary_connection;
2939
2940         if (!parent) {
2941                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2942                                      "Could not find source connection.");
2943                 return NULL;
2944         }
2945
2946         device = nm_active_connection_get_device (parent);
2947         if (!device) {
2948                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2949                                      "Source connection had no active device.");
2950                 return NULL;
2951         }
2952
2953         return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
2954                                                              device,
2955                                                              nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)),
2956                                                              subject);
2957 }
2958
2959 static NMActiveConnection *
2960 _new_active_connection (NMManager *self,
2961                         NMConnection *connection,
2962                         const char *specific_object,
2963                         NMDevice *device,
2964                         NMAuthSubject *subject,
2965                         GError **error)
2966 {
2967         NMSettingsConnection *settings_connection = NULL;
2968         NMActiveConnection *existing_ac;
2969         gboolean is_vpn;
2970
2971         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
2972         g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
2973
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));
2980                 return NULL;
2981         }
2982
2983         /* Normalize the specific object */
2984         if (specific_object && g_strcmp0 (specific_object, "/") == 0)
2985                 specific_object = NULL;
2986
2987         is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME);
2988
2989         if (NM_IS_SETTINGS_CONNECTION (connection))
2990                 settings_connection = (NMSettingsConnection *) connection;
2991
2992         if (is_vpn) {
2993                 return _new_vpn_active_connection (self,
2994                                                    settings_connection,
2995                                                    specific_object,
2996                                                    subject,
2997                                                    error);
2998         }
2999
3000         return (NMActiveConnection *) nm_act_request_new (settings_connection,
3001                                                           specific_object,
3002                                                           subject,
3003                                                           device);
3004 }
3005
3006 static void
3007 _internal_activation_failed (NMManager *self,
3008                              NMActiveConnection *active,
3009                              const char *error_desc)
3010 {
3011         _LOGD (LOGD_CORE, "Failed to activate '%s': %s",
3012                nm_active_connection_get_settings_connection_id (active),
3013                error_desc);
3014
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);
3018         }
3019 }
3020
3021 static void
3022 _internal_activation_auth_done (NMActiveConnection *active,
3023                                 gboolean success,
3024                                 const char *error_desc,
3025                                 gpointer user_data1,
3026                                 gpointer user_data2)
3027 {
3028         NMManager *self = user_data1;
3029         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3030         GError *error = NULL;
3031
3032         priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
3033
3034         if (success) {
3035                 if (_internal_activate_generic (self, active, &error)) {
3036                         g_object_unref (active);
3037                         return;
3038                 }
3039         }
3040
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);
3045 }
3046
3047 /**
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
3055  *
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.
3061  *
3062  * Returns: (transfer none): the new #NMActiveConnection that tracks
3063  * activation of @connection on @device
3064  */
3065 NMActiveConnection *
3066 nm_manager_activate_connection (NMManager *self,
3067                                 NMSettingsConnection *connection,
3068                                 const char *specific_object,
3069                                 NMDevice *device,
3070                                 NMAuthSubject *subject,
3071                                 GError **error)
3072 {
3073         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3074         NMActiveConnection *active;
3075         char *error_desc = NULL;
3076         GSList *iter;
3077
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);
3082
3083         /* Ensure the subject has permissions for this connection */
3084         if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3085                                         subject,
3086                                         &error_desc)) {
3087                 g_set_error_literal (error,
3088                                      NM_MANAGER_ERROR,
3089                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3090                                      error_desc);
3091                 g_free (error_desc);
3092                 return NULL;
3093         }
3094
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;
3102
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))
3108                         return active;
3109         }
3110
3111         active = _new_active_connection (self,
3112                                          NM_CONNECTION (connection),
3113                                          specific_object,
3114                                          device,
3115                                          subject,
3116                                          error);
3117         if (active) {
3118                 priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
3119                 nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL);
3120         }
3121         return active;
3122 }
3123
3124 /**
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
3133  *
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.
3137  *
3138  * Returns: on success, the #NMAuthSubject representing the requestor, or
3139  *   %NULL on error
3140  */
3141 static NMAuthSubject *
3142 validate_activation_request (NMManager *self,
3143                              GDBusMethodInvocation *context,
3144                              NMConnection *connection,
3145                              const char *device_path,
3146                              NMDevice **out_device,
3147                              gboolean *out_vpn,
3148                              GError **error)
3149 {
3150         NMDevice *device = NULL;
3151         gboolean vpn = FALSE;
3152         NMAuthSubject *subject = NULL;
3153         char *error_desc = NULL;
3154
3155         g_assert (connection);
3156         g_assert (out_device);
3157         g_assert (out_vpn);
3158
3159         /* Validate the caller */
3160         subject = nm_auth_subject_new_unix_process_from_context (context);
3161         if (!subject) {
3162                 g_set_error_literal (error,
3163                                      NM_MANAGER_ERROR,
3164                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3165                                      "Failed to get request UID.");
3166                 return NULL;
3167         }
3168
3169         /* Ensure the subject has permissions for this connection */
3170         if (!nm_auth_is_subject_in_acl (connection,
3171                                         subject,
3172                                         &error_desc)) {
3173                 g_set_error_literal (error,
3174                                      NM_MANAGER_ERROR,
3175                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3176                                      error_desc);
3177                 g_free (error_desc);
3178                 goto error;
3179         }
3180
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,
3187                                      NM_MANAGER_ERROR,
3188                                      NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
3189                                      "Sharing IPv6 connections is not supported yet.");
3190                 return NULL;
3191         }
3192
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))
3196                 vpn = TRUE;
3197
3198         /* Normalize device path */
3199         if (device_path && g_strcmp0 (device_path, "/") == 0)
3200                 device_path = NULL;
3201
3202         /* And validate it */
3203         if (device_path) {
3204                 device = nm_manager_get_device_by_path (self, device_path);
3205                 if (!device) {
3206                         g_set_error_literal (error,
3207                                              NM_MANAGER_ERROR,
3208                                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3209                                              "Device not found");
3210                         goto error;
3211                 }
3212         } else
3213                 device = nm_manager_get_best_device_for_connection (self, connection, TRUE);
3214
3215         if (!device && !vpn) {
3216                 gboolean is_software = nm_connection_is_virtual (connection);
3217
3218                 /* VPN and software-device connections don't need a device yet */
3219                 if (!is_software) {
3220                         g_set_error_literal (error,
3221                                              NM_MANAGER_ERROR,
3222                                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3223                                              "No suitable device found for this connection.");
3224                         goto error;
3225                 }
3226
3227                 if (is_software) {
3228                         char *iface;
3229
3230                         /* Look for an existing device with the connection's interface name */
3231                         iface = nm_manager_get_connection_iface (self, connection, NULL, error);
3232                         if (!iface)
3233                                 goto error;
3234
3235                         device = find_device_by_iface (self, iface, connection, NULL);
3236                         g_free (iface);
3237                 }
3238         }
3239
3240         if ((!vpn || device_path) && !device) {
3241                 g_set_error_literal (error,
3242                                      NM_MANAGER_ERROR,
3243                                      NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3244                                      "Failed to find a compatible device for this connection");
3245                 goto error;
3246         }
3247
3248         *out_device = device;
3249         *out_vpn = vpn;
3250         return subject;
3251
3252 error:
3253         g_object_unref (subject);
3254         return NULL;
3255 }
3256
3257 /***********************************************************************/
3258
3259 static void
3260 _activation_auth_done (NMActiveConnection *active,
3261                        gboolean success,
3262                        const char *error_desc,
3263                        gpointer user_data1,
3264                        gpointer user_data2)
3265 {
3266         NMManager *self = user_data1;
3267         GDBusMethodInvocation *context = user_data2;
3268         GError *error = NULL;
3269         NMAuthSubject *subject;
3270         NMSettingsConnection *connection;
3271
3272         subject = nm_active_connection_get_subject (active);
3273         connection = nm_active_connection_get_settings_connection (active);
3274
3275         if (success) {
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,
3281                                                     subject, NULL);
3282                         g_object_unref (active);
3283                         return;
3284                 }
3285         } else {
3286                 error = g_error_new_literal (NM_MANAGER_ERROR,
3287                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3288                                              error_desc);
3289         }
3290
3291         g_assert (error);
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);
3295
3296         g_object_unref (active);
3297         g_dbus_method_invocation_take_error (context, error);
3298 }
3299
3300 static void
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)
3306 {
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;
3314
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)
3321                 device_path = NULL;
3322
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).
3327          */
3328         if (!connection_path) {
3329                 GPtrArray *available;
3330                 guint64 best_timestamp = 0;
3331                 guint i;
3332
3333                 /* If no connection is given, find a suitable connection for the given device path */
3334                 if (!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");
3337                         goto error;
3338                 }
3339                 device = nm_manager_get_device_by_path (self, device_path);
3340                 if (!device) {
3341                         error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3342                                              "Cannot activate unknown device %s", device_path);
3343                         goto error;
3344                 }
3345
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;
3350
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;
3355                         }
3356                 }
3357
3358                 if (available)
3359                         g_ptr_array_free (available, TRUE);
3360
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.");
3365                         goto error;
3366                 }
3367         }
3368
3369         g_assert (connection_path);
3370         connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
3371         if (!connection) {
3372                 error = g_error_new_literal (NM_MANAGER_ERROR,
3373                                              NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3374                                              "Connection could not be found.");
3375                 goto error;
3376         }
3377
3378         subject = validate_activation_request (self,
3379                                                context,
3380                                                NM_CONNECTION (connection),
3381                                                device_path,
3382                                                &device,
3383                                                &is_vpn,
3384                                                &error);
3385         if (!subject)
3386                 goto error;
3387
3388         active = _new_active_connection (self,
3389                                          NM_CONNECTION (connection),
3390                                          specific_object_path,
3391                                          device,
3392                                          subject,
3393                                          &error);
3394         if (!active)
3395                 goto error;
3396
3397         nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context);
3398         g_clear_object (&subject);
3399         return;
3400
3401 error:
3402         if (connection) {
3403                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3404                                             subject, error->message);
3405         }
3406         g_clear_object (&active);
3407         g_clear_object (&subject);
3408
3409         g_assert (error);
3410         g_dbus_method_invocation_take_error (context, error);
3411 }
3412
3413 /***********************************************************************/
3414
3415 typedef struct {
3416         NMManager *manager;
3417         NMActiveConnection *active;
3418 } AddAndActivateInfo;
3419
3420 static void
3421 activation_add_done (NMSettings *settings,
3422                      NMSettingsConnection *new_connection,
3423                      GError *error,
3424                      GDBusMethodInvocation *context,
3425                      NMAuthSubject *subject,
3426                      gpointer user_data)
3427 {
3428         AddAndActivateInfo *info = user_data;
3429         NMManager *self;
3430         gs_unref_object NMActiveConnection *active = NULL;
3431         GError *local = NULL;
3432
3433         self = info->manager;
3434         active = info->active;
3435         g_slice_free (AddAndActivateInfo, info);
3436
3437         if (!error) {
3438                 nm_active_connection_set_settings_connection (active, new_connection);
3439
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,
3443                                                                NULL, NULL);
3444                         g_dbus_method_invocation_return_value (
3445                             context,
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),
3451                                                     TRUE,
3452                                                     nm_active_connection_get_subject (active),
3453                                                     NULL);
3454                         return;
3455                 }
3456                 error = local;
3457         }
3458
3459         g_assert (error);
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,
3464                                     NULL,
3465                                     FALSE,
3466                                     nm_active_connection_get_subject (active),
3467                                     error->message);
3468         g_clear_error (&local);
3469 }
3470
3471 static void
3472 _add_and_activate_auth_done (NMActiveConnection *active,
3473                              gboolean success,
3474                              const char *error_desc,
3475                              gpointer user_data1,
3476                              gpointer user_data2)
3477 {
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;
3483
3484         if (success) {
3485                 NMConnection *connection;
3486
3487                 connection = g_object_steal_data (G_OBJECT (active),
3488                                                   TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE);
3489
3490                 info = g_slice_new (AddAndActivateInfo);
3491                 info->manager = self;
3492                 info->active = g_object_ref (active);
3493
3494                 /* Basic sender auth checks performed; try to add the connection */
3495                 nm_settings_add_connection_dbus (priv->settings,
3496                                                  connection,
3497                                                  FALSE,
3498                                                  context,
3499                                                  activation_add_done,
3500                                                  info);
3501                 g_object_unref (connection);
3502         } else {
3503                 g_assert (error_desc);
3504                 error = g_error_new_literal (NM_MANAGER_ERROR,
3505                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3506                                              error_desc);
3507                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3508                                             NULL,
3509                                             FALSE,
3510                                             nm_active_connection_get_subject (active),
3511                                             error->message);
3512                 g_dbus_method_invocation_take_error (context, error);
3513         }
3514
3515         g_object_unref (active);
3516 }
3517
3518 static void
3519 impl_manager_add_and_activate_connection (NMManager *self,
3520                                           GDBusMethodInvocation *context,
3521                                           GVariant *settings,
3522                                           const char *device_path,
3523                                           const char *specific_object_path)
3524 {
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;
3533
3534         /* Normalize object paths */
3535         if (g_strcmp0 (specific_object_path, "/") == 0)
3536                 specific_object_path = NULL;
3537         if (g_strcmp0 (device_path, "/") == 0)
3538                 device_path = NULL;
3539
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()).
3546          */
3547         connection = nm_simple_connection_new ();
3548         if (settings && g_variant_n_children (settings))
3549                 nm_connection_replace_settings (connection, settings, NULL);
3550
3551         subject = validate_activation_request (self,
3552                                                context,
3553                                                connection,
3554                                                device_path,
3555                                                &device,
3556                                                &vpn,
3557                                                &error);
3558         if (!subject)
3559                 goto error;
3560
3561         all_connections = nm_settings_get_connections (priv->settings);
3562         if (vpn) {
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);
3569                         goto error;
3570                 }
3571
3572                 nm_utils_complete_generic (NM_PLATFORM_GET,
3573                                            connection,
3574                                            NM_SETTING_VPN_SETTING_NAME,
3575                                            all_connections,
3576                                            NULL,
3577                                            _("VPN connection"),
3578                                            NULL,
3579                                            FALSE); /* No IPv6 by default for now */
3580         } else {
3581                 /* Let each device subclass complete the connection */
3582                 if (!nm_device_complete_connection (device,
3583                                                     connection,
3584                                                     specific_object_path,
3585                                                     all_connections,
3586                                                     &error))
3587                         goto error;
3588         }
3589         g_slist_free (all_connections);
3590         all_connections = NULL;
3591
3592         active = _new_active_connection (self,
3593                                          connection,
3594                                          specific_object_path,
3595                                          device,
3596                                          subject,
3597                                          &error);
3598         if (!active)
3599                 goto error;
3600
3601         g_object_set_data_full (G_OBJECT (active),
3602                                 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE,
3603                                 connection,
3604                                 g_object_unref);
3605
3606         nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context);
3607         g_object_unref (subject);
3608         return;
3609
3610 error:
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);
3616
3617         g_assert (error);
3618         g_dbus_method_invocation_take_error (context, error);
3619 }
3620
3621 /***********************************************************************/
3622
3623 gboolean
3624 nm_manager_deactivate_connection (NMManager *manager,
3625                                   const char *connection_path,
3626                                   NMDeviceStateReason reason,
3627                                   GError **error)
3628 {
3629         NMActiveConnection *active;
3630         gboolean success = FALSE;
3631
3632         active = active_connection_get_by_path (manager, connection_path);
3633         if (!active) {
3634                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3635                                      "The connection was not active.");
3636                 return FALSE;
3637         }
3638
3639         if (NM_IS_VPN_CONNECTION (active)) {
3640                 NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
3641
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))
3645                         success = TRUE;
3646                 else
3647                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3648                                              "The VPN connection was not active.");
3649         } else {
3650                 g_assert (NM_IS_ACT_REQUEST (active));
3651                 nm_device_state_changed (nm_active_connection_get_device (active),
3652                                          NM_DEVICE_STATE_DEACTIVATING,
3653                                          reason);
3654                 success = TRUE;
3655         }
3656
3657         if (success)
3658                 g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
3659
3660         return success;
3661 }
3662
3663 static void
3664 deactivate_net_auth_done_cb (NMAuthChain *chain,
3665                              GError *auth_error,
3666                              GDBusMethodInvocation *context,
3667                              gpointer user_data)
3668 {
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;
3674         char *path;
3675
3676         g_assert (context);
3677
3678         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3679
3680         path = nm_auth_chain_get_data (chain, "path");
3681         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3682
3683         if (auth_error) {
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");
3693         } else {
3694                 /* success; deactivation allowed */
3695                 if (!nm_manager_deactivate_connection (self,
3696                                                        path,
3697                                                        NM_DEVICE_STATE_REASON_USER_REQUESTED,
3698                                                        &error))
3699                         nm_assert (error);
3700         }
3701
3702         active = active_connection_get_by_path (self, path);
3703         if (active) {
3704                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
3705                                             nm_active_connection_get_settings_connection (active),
3706                                             !error,
3707                                             nm_auth_chain_get_subject (chain),
3708                                             error ? error->message : NULL);
3709         }
3710
3711         if (error)
3712                 g_dbus_method_invocation_take_error (context, error);
3713         else
3714                 g_dbus_method_invocation_return_value (context, NULL);
3715
3716         nm_auth_chain_unref (chain);
3717 }
3718
3719 static void
3720 impl_manager_deactivate_connection (NMManager *self,
3721                                     GDBusMethodInvocation *context,
3722                                     const char *active_path)
3723 {
3724         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3725         NMActiveConnection *ac;
3726         NMSettingsConnection *connection = NULL;
3727         GError *error = NULL;
3728         NMAuthSubject *subject = NULL;
3729         NMAuthChain *chain;
3730         char *error_desc = NULL;
3731
3732         /* Find the connection by its object path */
3733         ac = active_connection_get_by_path (self, active_path);
3734         if (ac)
3735                 connection = nm_active_connection_get_settings_connection (ac);
3736
3737         if (!connection) {
3738                 error = g_error_new_literal (NM_MANAGER_ERROR,
3739                                              NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3740                                              "The connection was not active.");
3741                 goto done;
3742         }
3743
3744         /* Validate the caller */
3745         subject = nm_auth_subject_new_unix_process_from_context (context);
3746         if (!subject) {
3747                 error = g_error_new_literal (NM_MANAGER_ERROR,
3748                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3749                                              "Failed to get request UID.");
3750                 goto done;
3751         }
3752
3753         /* Ensure the subject has permissions for this connection */
3754         if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3755                                         subject,
3756                                         &error_desc)) {
3757                 error = g_error_new_literal (NM_MANAGER_ERROR,
3758                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3759                                              error_desc);
3760                 g_free (error_desc);
3761                 goto done;
3762         }
3763
3764         /* Validate the user request */
3765         chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self);
3766         if (!chain) {
3767                 error = g_error_new_literal (NM_MANAGER_ERROR,
3768                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3769                                              "Unable to authenticate request.");
3770                 goto done;
3771         }
3772
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);
3776
3777 done:
3778         if (error) {
3779                 if (connection) {
3780                         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE,
3781                                                     subject, error->message);
3782                 }
3783                 g_dbus_method_invocation_take_error (context, error);
3784         }
3785         g_clear_object (&subject);
3786 }
3787
3788 static gboolean
3789 device_is_wake_on_lan (NMDevice *device)
3790 {
3791         return nm_platform_link_get_wake_on_lan (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device));
3792 }
3793
3794 static void
3795 do_sleep_wake (NMManager *self, gboolean sleeping_changed)
3796 {
3797         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3798         gboolean suspending, waking_from_suspend;
3799         GSList *iter;
3800
3801         suspending = sleeping_changed && priv->sleeping;
3802         waking_from_suspend = sleeping_changed && !priv->sleeping;
3803
3804         if (manager_sleeping (self)) {
3805                 _LOGI (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling");
3806
3807                 /* FIXME: are there still hardware devices that need to be disabled around
3808                  * suspend/resume?
3809                  */
3810                 for (iter = priv->devices; iter; iter = iter->next) {
3811                         NMDevice *device = iter->data;
3812
3813                         /* FIXME: shouldn't we be unmanaging software devices if !suspending? */
3814                         if (nm_device_is_software (device))
3815                                 continue;
3816                         /* Wake-on-LAN devices will be taken down post-suspend rather than pre- */
3817                         if (suspending && device_is_wake_on_lan (device))
3818                                 continue;
3819
3820                         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3821                 }
3822         } else {
3823                 _LOGI (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling");
3824
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.
3828                          */
3829                         for (iter = priv->devices; iter; iter = iter->next) {
3830                                 NMDevice *device = iter->data;
3831
3832                                 if (nm_device_is_software (device))
3833                                         continue;
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);
3836                         }
3837                 }
3838
3839                 /* Ensure rfkill state is up-to-date since we don't respond to state
3840                  * changes during sleep.
3841                  */
3842                 nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
3843
3844                 /* Re-manage managed devices */
3845                 for (iter = priv->devices; iter; iter = iter->next) {
3846                         NMDevice *device = NM_DEVICE (iter->data);
3847                         guint i;
3848
3849                         if (nm_device_is_software (device))
3850                                 continue;
3851
3852                         /* enable/disable wireless devices since that we don't respond
3853                          * to killswitch changes during sleep.
3854                          */
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);
3858
3859                                 if (rstate->desc) {
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);
3863                                 }
3864
3865                                 if (nm_device_get_rfkill_type (device) == rstate->rtype)
3866                                         nm_device_set_enabled (device, enabled);
3867                         }
3868
3869                         nm_device_set_autoconnect (device, TRUE);
3870
3871                         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
3872                 }
3873         }
3874
3875         nm_manager_update_state (self);
3876 }
3877
3878 static void
3879 _internal_sleep (NMManager *self, gboolean do_sleep)
3880 {
3881         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3882
3883         if (priv->sleeping == do_sleep)
3884                 return;
3885
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");
3890
3891         priv->sleeping = do_sleep;
3892
3893         do_sleep_wake (self, TRUE);
3894
3895         g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
3896 }
3897
3898 #if 0
3899 static void
3900 sleep_auth_done_cb (NMAuthChain *chain,
3901                     GError *error,
3902                     GDBusMethodInvocation *context,
3903                     gpointer user_data)
3904 {
3905         NMManager *self = NM_MANAGER (user_data);
3906         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3907         GError *ret_error;
3908         NMAuthCallResult result;
3909         gboolean do_sleep;
3910
3911         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3912
3913         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
3914         if (error) {
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",
3919                                          error->message);
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);
3926         } else {
3927                 /* Auth success */
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);
3931         }
3932
3933         nm_auth_chain_unref (chain);
3934 }
3935 #endif
3936
3937 static void
3938 impl_manager_sleep (NMManager *self,
3939                     GDBusMethodInvocation *context,
3940                     gboolean do_sleep)
3941 {
3942         NMManagerPrivate *priv;
3943         GError *error = NULL;
3944         gs_unref_object NMAuthSubject *subject = NULL;
3945 #if 0
3946         NMAuthChain *chain;
3947         const char *error_desc = NULL;
3948 #endif
3949
3950         g_return_if_fail (NM_IS_MANAGER (self));
3951
3952         priv = NM_MANAGER_GET_PRIVATE (self);
3953         subject = nm_auth_subject_new_unix_process_from_context (context);
3954
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,
3960                                          error->message);
3961                 g_dbus_method_invocation_take_error (context, error);
3962                 return;
3963         }
3964
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.
3972          */
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);
3976         return;
3977
3978 #if 0
3979         chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
3980         if (chain) {
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);
3984         } else {
3985                 error = g_error_new_literal (NM_MANAGER_ERROR,
3986                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3987                                              error_desc);
3988                 g_dbus_method_invocation_take_error (context, error);
3989         }
3990 #endif
3991 }
3992
3993 static void
3994 sleeping_cb (NMSleepMonitor *monitor, gpointer user_data)
3995 {
3996         nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
3997         _internal_sleep (NM_MANAGER (user_data), TRUE);
3998 }
3999
4000 static void
4001 resuming_cb (NMSleepMonitor *monitor, gpointer user_data)
4002 {
4003         nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
4004         _internal_sleep (NM_MANAGER (user_data), FALSE);
4005 }
4006
4007 static void
4008 _internal_enable (NMManager *self, gboolean enable)
4009 {
4010         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4011         GError *err = NULL;
4012
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,
4018                                                 &err)) {
4019                         /* Not a hard error */
4020                         _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s",
4021                                priv->state_file,
4022                                err->message);
4023                 }
4024         }
4025
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");
4030
4031         priv->net_enabled = enable;
4032
4033         do_sleep_wake (self, FALSE);
4034
4035         g_object_notify (G_OBJECT (self), NM_MANAGER_NETWORKING_ENABLED);
4036 }
4037
4038 static void
4039 enable_net_done_cb (NMAuthChain *chain,
4040                     GError *error,
4041                     GDBusMethodInvocation *context,
4042                     gpointer user_data)
4043 {
4044         NMManager *self = NM_MANAGER (user_data);
4045         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4046         GError *ret_error = NULL;
4047         NMAuthCallResult result;
4048         gboolean enable;
4049         NMAuthSubject *subject;
4050
4051         g_assert (context);
4052
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);
4056
4057         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4058         if (error) {
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",
4063                                          error->message);
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");
4068         } else {
4069                 /* Auth success */
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,
4073                                          subject, NULL);
4074         }
4075
4076         if (ret_error) {
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);
4080         }
4081
4082         nm_auth_chain_unref (chain);
4083 }
4084
4085 static void
4086 impl_manager_enable (NMManager *self,
4087                      GDBusMethodInvocation *context,
4088                      gboolean enable)
4089 {
4090         NMManagerPrivate *priv;
4091         NMAuthChain *chain;
4092         GError *error = NULL;
4093
4094         g_return_if_fail (NM_IS_MANAGER (self));
4095
4096         priv = NM_MANAGER_GET_PRIVATE (self);
4097
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");
4102                 goto done;
4103         }
4104
4105         chain = nm_auth_chain_new_context (context, enable_net_done_cb, self);
4106         if (!chain) {
4107                 error = g_error_new_literal (NM_MANAGER_ERROR,
4108                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4109                                              "Unable to authenticate request.");
4110                 goto done;
4111         }
4112
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);
4116
4117 done:
4118         if (error)
4119                 g_dbus_method_invocation_take_error (context, error);
4120 }
4121
4122 /* Permissions */
4123
4124 static void
4125 get_perm_add_result (NMAuthChain *chain, GVariantBuilder *results, const char *permission)
4126 {
4127         NMAuthCallResult result;
4128
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");
4136         else {
4137                 nm_log_dbg (LOGD_CORE, "unknown auth chain result %d", result);
4138         }
4139 }
4140
4141 static void
4142 get_permissions_done_cb (NMAuthChain *chain,
4143                          GError *error,
4144                          GDBusMethodInvocation *context,
4145                          gpointer user_data)
4146 {
4147         NMManager *self = NM_MANAGER (user_data);
4148         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4149         GError *ret_error;
4150         GVariantBuilder results;
4151
4152         g_assert (context);
4153
4154         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4155         if (error) {
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",
4160                                          error->message);
4161                 g_dbus_method_invocation_take_error (context, ret_error);
4162         } else {
4163                 g_variant_builder_init (&results, G_VARIANT_TYPE ("a{ss}"));
4164
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);
4176
4177                 g_dbus_method_invocation_return_value (context,
4178                                                        g_variant_new ("(a{ss})", &results));
4179         }
4180
4181         nm_auth_chain_unref (chain);
4182 }
4183
4184 static void
4185 impl_manager_get_permissions (NMManager *self,
4186                               GDBusMethodInvocation *context)
4187 {
4188         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4189         NMAuthChain *chain;
4190         GError *error = NULL;
4191
4192         chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self);
4193         if (!chain) {
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);
4198                 return;
4199         }
4200
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);
4213 }
4214
4215 static void
4216 impl_manager_get_state (NMManager *self,
4217                         GDBusMethodInvocation *context)
4218 {
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));
4222 }
4223
4224 static void
4225 impl_manager_set_logging (NMManager *self,
4226                           GDBusMethodInvocation *context,
4227                           const char *level,
4228                           const char *domains)
4229 {
4230         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4231         GError *error = NULL;
4232         gulong caller_uid = G_MAXULONG;
4233
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.");
4238                 goto done;
4239         }
4240
4241         if (0 != caller_uid) {
4242                 error = g_error_new_literal (NM_MANAGER_ERROR,
4243                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4244                                              "Permission denied");
4245                 goto done;
4246         }
4247
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 ());
4251         }
4252
4253 done:
4254         if (error)
4255                 g_dbus_method_invocation_take_error (context, error);
4256         else
4257                 g_dbus_method_invocation_return_value (context, NULL);
4258 }
4259
4260 static void
4261 impl_manager_get_logging (NMManager *manager,
4262                           GDBusMethodInvocation *context)
4263 {
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 ()));
4268 }
4269
4270 static void
4271 connectivity_check_done (GObject *object,
4272                          GAsyncResult *result,
4273                          gpointer user_data)
4274 {
4275         GDBusMethodInvocation *context = user_data;
4276         NMConnectivityState state;
4277         GError *error = NULL;
4278
4279         state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
4280         if (error)
4281                 g_dbus_method_invocation_take_error (context, error);
4282         else {
4283                 g_dbus_method_invocation_return_value (context,
4284                                                        g_variant_new ("(u)", state));
4285         }
4286 }
4287
4288
4289 static void
4290 check_connectivity_auth_done_cb (NMAuthChain *chain,
4291                                  GError *auth_error,
4292                                  GDBusMethodInvocation *context,
4293                                  gpointer user_data)
4294 {
4295         NMManager *self = NM_MANAGER (user_data);
4296         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4297         GError *error = NULL;
4298         NMAuthCallResult result;
4299
4300         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4301
4302         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4303
4304         if (auth_error) {
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");
4314         } else {
4315                 /* it's allowed */
4316                 nm_connectivity_check_async (priv->connectivity,
4317                                              connectivity_check_done,
4318                                              context);
4319         }
4320
4321         if (error)
4322                 g_dbus_method_invocation_take_error (context, error);
4323         nm_auth_chain_unref (chain);
4324 }
4325
4326 static void
4327 impl_manager_check_connectivity (NMManager *self,
4328                                  GDBusMethodInvocation *context)
4329 {
4330         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4331         NMAuthChain *chain;
4332         GError *error = NULL;
4333
4334         /* Validate the request */
4335         chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self);
4336         if (!chain) {
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);
4341                 return;
4342         }
4343
4344         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4345         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
4346 }
4347
4348 static void
4349 start_factory (NMDeviceFactory *factory, gpointer user_data)
4350 {
4351         nm_device_factory_start (factory);
4352 }
4353
4354 gboolean
4355 nm_manager_start (NMManager *self, GError **error)
4356 {
4357         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4358         GSList *iter, *connections;
4359         guint i;
4360
4361         if (!nm_settings_start (priv->settings, error))
4362                 return FALSE;
4363
4364         g_signal_connect (NM_PLATFORM_GET,
4365                           NM_PLATFORM_SIGNAL_LINK_CHANGED,
4366                           G_CALLBACK (platform_link_cb),
4367                           self);
4368
4369         /* Set initial radio enabled/disabled state */
4370         for (i = 0; i < RFKILL_TYPE_MAX; i++) {
4371                 RadioState *rstate = &priv->radio_states[i];
4372                 gboolean enabled;
4373
4374                 if (!rstate->desc)
4375                         continue;
4376
4377                 /* recheck kernel rfkill state */
4378                 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
4379
4380                 if (rstate->desc) {
4381                         _LOGI (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
4382                                rstate->desc,
4383                                (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
4384                                rstate->user_enabled ? "enabled" : "disabled");
4385                 }
4386                 enabled = radio_enabled_for_rstate (rstate, TRUE);
4387                 manager_update_radio_enabled (self, rstate, enabled);
4388         }
4389
4390         /* Log overall networking status - enabled/disabled */
4391         _LOGI (LOGD_CORE, "Networking is %s by state file",
4392                priv->net_enabled ? "enabled" : "disabled");
4393
4394         system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
4395         system_hostname_changed_cb (priv->settings, NULL, self);
4396
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);
4400
4401         platform_query_devices (self);
4402
4403         /* Load VPN plugins */
4404         priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
4405
4406         /* Connections added before the manager is started do not emit
4407          * connection-added signals thus devices have to be created manually.
4408          */
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);
4414
4415         priv->devices_inited = TRUE;
4416
4417         check_if_startup_complete (self);
4418
4419         return TRUE;
4420 }
4421
4422 void
4423 nm_manager_stop (NMManager *self)
4424 {
4425         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4426
4427         /* Remove all devices */
4428         while (priv->devices)
4429                 remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
4430
4431         _active_connection_cleanup (self);
4432 }
4433
4434 static gboolean
4435 handle_firmware_changed (gpointer user_data)
4436 {
4437         NMManager *self = NM_MANAGER (user_data);
4438         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4439         GSList *iter;
4440
4441         priv->fw_changed_id = 0;
4442
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);
4447
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));
4452
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);
4457                 }
4458         }
4459
4460         return FALSE;
4461 }
4462
4463 static void
4464 connectivity_changed (NMConnectivity *connectivity,
4465                       GParamSpec *pspec,
4466                       gpointer user_data)
4467 {
4468         NMManager *self = NM_MANAGER (user_data);
4469
4470         _LOGD (LOGD_CORE, "connectivity checking indicates %s",
4471                nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
4472
4473         nm_manager_update_state (self);
4474         g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
4475 }
4476
4477 static void
4478 firmware_dir_changed (GFileMonitor *monitor,
4479                       GFile *file,
4480                       GFile *other_file,
4481                       GFileMonitorEvent event_type,
4482                       gpointer user_data)
4483 {
4484         NMManager *self = NM_MANAGER (user_data);
4485         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4486
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);
4497                 }
4498                 break;
4499         default:
4500                 break;
4501         }
4502 }
4503
4504 static void
4505 connection_metered_changed (GObject *object,
4506                             NMMetered metered,
4507                             gpointer user_data)
4508 {
4509         nm_manager_update_metered (NM_MANAGER (user_data));
4510 }
4511
4512 static void
4513 policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4514 {
4515         NMManager *self = NM_MANAGER (user_data);
4516         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4517         NMDevice *best;
4518         NMActiveConnection *ac;
4519
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.
4523          */
4524         best = nm_policy_get_default_ip4_device (priv->policy);
4525         if (!best)
4526                 best = nm_policy_get_default_ip6_device (priv->policy);
4527
4528         if (best)
4529                 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
4530         else
4531                 ac = NULL;
4532
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),
4537                                                               self);
4538                         g_clear_object (&priv->primary_connection);
4539                 }
4540
4541                 priv->primary_connection = ac ? g_object_ref (ac) : NULL;
4542
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);
4546                 }
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);
4551         }
4552 }
4553
4554 static void
4555 policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4556 {
4557         NMManager *self = NM_MANAGER (user_data);
4558         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4559         NMDevice *activating, *best;
4560         NMActiveConnection *ac;
4561
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
4567          * something else.
4568          */
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);
4573
4574         if (activating)
4575                 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
4576         else
4577                 ac = NULL;
4578
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);
4584         }
4585 }
4586
4587 #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
4588
4589 typedef struct {
4590         NMManager *self;
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;
4600
4601 static void
4602 free_property_filter_data (PropertyFilterData *pfd)
4603 {
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);
4610 }
4611
4612 static void
4613 prop_set_auth_done_cb (NMAuthChain *chain,
4614                        GError *error,
4615                        GDBusMethodInvocation *context, /* NULL */
4616                        gpointer user_data)
4617 {
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;
4626         GVariant *args;
4627
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"));
4634                 if (error)
4635                         error_message = error->message;
4636                 goto done;
4637         }
4638
4639         object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr,
4640                                                                            g_dbus_message_get_path (pfd->message)));
4641         if (!object) {
4642                 reply = g_dbus_message_new_method_error (pfd->message,
4643                                                          "org.freedesktop.DBus.Error.UnknownObject",
4644                                                          (error_message = "Object doesn't exist."));
4645                 goto done;
4646         }
4647
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."));
4653                 goto done;
4654         }
4655
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);
4659
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));
4663
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"));
4668                         goto done;
4669                 }
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);
4673         } else {
4674                 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
4675                 /* the same here */
4676                 g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL);
4677         }
4678
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;
4682 done:
4683         nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message);
4684
4685         g_dbus_connection_send_message (pfd->connection, reply,
4686                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4687                                         NULL, NULL);
4688         g_object_unref (reply);
4689         nm_auth_chain_unref (chain);
4690
4691         free_property_filter_data (pfd);
4692 }
4693
4694 static gboolean
4695 do_set_property_check (gpointer user_data)
4696 {
4697         PropertyFilterData *pfd = user_data;
4698         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4699         GDBusMessage *reply = NULL;
4700         NMAuthChain *chain;
4701         const char *error_message = NULL;
4702
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."));
4708                 goto out;
4709         }
4710
4711         /* Validate the user request */
4712         chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd);
4713         if (!chain) {
4714                 reply = g_dbus_message_new_method_error (pfd->message,
4715                                                          NM_PERM_DENIED_ERROR,
4716                                                          (error_message = "Could not authenticate request."));
4717                 goto out;
4718         }
4719
4720         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4721         nm_auth_chain_add_call (chain, pfd->permission, TRUE);
4722
4723 out:
4724         if (reply) {
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,
4728                                                 NULL, NULL);
4729                 g_object_unref (reply);
4730                 free_property_filter_data (pfd);
4731         }
4732
4733         return FALSE;
4734 }
4735
4736 static GDBusMessage *
4737 prop_filter (GDBusConnection *connection,
4738              GDBusMessage *message,
4739              gboolean incoming,
4740              gpointer user_data)
4741 {
4742         gs_unref_object NMManager *self = NULL;
4743         GVariant *args;
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;
4752
4753         self = g_weak_ref_get (user_data);
4754         if (!self)
4755                 return message;
4756
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.
4759          */
4760
4761         /* Only filter org.freedesktop.DBus.Properties.Set calls */
4762         if (   !incoming
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)
4766                 return message;
4767
4768         args = g_dbus_message_get_body (message);
4769         if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)")))
4770                 return message;
4771         g_variant_get (args, "(&s&sv)", &propiface, &propname, &value);
4772
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}");
4792                 } else
4793                         return message;
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;
4804                 } else
4805                         return message;
4806                 interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
4807         } else
4808                 return message;
4809
4810         if (!g_variant_is_of_type (value, expected_type))
4811                 return message;
4812
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.
4816          */
4817         pfd = g_slice_new0 (PropertyFilterData);
4818         pfd->self = self;
4819         self = NULL;
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));
4829         } else
4830                 pfd->audit_prop_value = g_strdup (pfd->glib_propname);
4831
4832         g_idle_add (do_set_property_check, pfd);
4833
4834         return NULL;
4835 }
4836
4837 /******************************************************************************/
4838
4839 static int
4840 _set_prop_filter_free2 (gpointer user_data)
4841 {
4842         g_slice_free (GWeakRef, user_data);
4843         return G_SOURCE_REMOVE;
4844 }
4845
4846 static void
4847 _set_prop_filter_free (gpointer user_data)
4848 {
4849         g_weak_ref_clear (user_data);
4850
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);
4857 }
4858
4859 static void
4860 _set_prop_filter (NMManager *self, GDBusConnection *connection)
4861 {
4862         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4863
4864         nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id));
4865
4866         if (priv->prop_filter.connection == connection)
4867                 return;
4868
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);
4873         }
4874         if (connection) {
4875                 GWeakRef *wptr;
4876
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);
4881         }
4882 }
4883
4884 /******************************************************************************/
4885
4886 static void
4887 authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data)
4888 {
4889         /* Let clients know they should re-check their authorization */
4890         g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
4891 }
4892
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 {
4897         __u32 idx;
4898         __u8  type;
4899         __u8  op;
4900         __u8  soft, hard;
4901 } __attribute__((packed));
4902
4903 static void
4904 rfkill_change (const char *desc, RfKillType rtype, gboolean enabled)
4905 {
4906         int fd;
4907         struct rfkill_event event;
4908         ssize_t len;
4909
4910         g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
4911
4912         errno = 0;
4913         fd = open ("/dev/rfkill", O_RDWR);
4914         if (fd < 0) {
4915                 if (errno == EACCES)
4916                         nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device", desc);
4917                 return;
4918         }
4919
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);
4923                 close (fd);
4924                 return;
4925         }
4926
4927         memset (&event, 0, sizeof (event));
4928         event.op = KERN_RFKILL_OP_CHANGE_ALL;
4929         switch (rtype) {
4930         case RFKILL_TYPE_WLAN:
4931                 event.type = KERN_RFKILL_TYPE_WLAN;
4932                 break;
4933         case RFKILL_TYPE_WWAN:
4934                 event.type = KERN_RFKILL_TYPE_WWAN;
4935                 break;
4936         default:
4937                 g_assert_not_reached ();
4938         }
4939         event.soft = enabled ? 0 : 1;
4940
4941         len = write (fd, &event, sizeof (event));
4942         if (len < 0) {
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");
4948         } else {
4949                 /* Failed to write full structure */
4950                 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
4951         }
4952
4953         close (fd);
4954 }
4955
4956 static void
4957 manager_radio_user_toggled (NMManager *self,
4958                             RadioState *rstate,
4959                             gboolean enabled)
4960 {
4961         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4962         GError *error = NULL;
4963         gboolean old_enabled, new_enabled;
4964
4965         /* Don't touch devices if asleep/networking disabled */
4966         if (manager_sleeping (self))
4967                 return;
4968
4969         if (rstate->desc) {
4970                 _LOGD (LOGD_RFKILL, "(%s): setting radio %s by user",
4971                        rstate->desc,
4972                        enabled ? "enabled" : "disabled");
4973         }
4974
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,
4980                                                 &error)) {
4981                         _LOGW (LOGD_CORE, "writing to state file %s failed: %s",
4982                                priv->state_file,
4983                                error->message);
4984                         g_clear_error (&error);
4985                 }
4986         }
4987
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.
4996          */
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);
5004
5005                 manager_update_radio_enabled (self, rstate, new_enabled);
5006         }
5007 }
5008
5009 static gboolean
5010 periodic_update_active_connection_timestamps (gpointer user_data)
5011 {
5012         NMManager *manager = NM_MANAGER (user_data);
5013         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5014         GSList *iter;
5015
5016         for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
5017                 NMActiveConnection *ac = iter->data;
5018                 NMSettingsConnection *connection;
5019
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);
5023                 }
5024         }
5025
5026         return TRUE;
5027 }
5028
5029 static void
5030 dbus_connection_changed_cb (NMBusManager *dbus_mgr,
5031                             GDBusConnection *connection,
5032                             gpointer user_data)
5033 {
5034         _set_prop_filter (NM_MANAGER (user_data), connection);
5035 }
5036
5037 /**********************************************************************/
5038
5039 NM_DEFINE_SINGLETON_REGISTER (NMManager);
5040
5041 NMManager *
5042 nm_manager_get (void)
5043 {
5044         g_return_val_if_fail (singleton_instance, NULL);
5045         return singleton_instance;
5046 }
5047
5048 NMConnectionProvider *
5049 nm_connection_provider_get (void)
5050 {
5051         NMConnectionProvider *p;
5052
5053         g_return_val_if_fail (singleton_instance, NULL);
5054
5055         p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings);
5056         g_return_val_if_fail (p, NULL);
5057         return p;
5058 }
5059
5060 NMManager *
5061 nm_manager_setup (const char *state_file,
5062                   gboolean initial_net_enabled,
5063                   gboolean initial_wifi_enabled,
5064                   gboolean initial_wwan_enabled)
5065 {
5066         NMManager *self;
5067
5068         g_return_val_if_fail (!singleton_instance, singleton_instance);
5069
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,
5075                              NULL);
5076         nm_assert (NM_IS_MANAGER (self));
5077         singleton_instance = self;
5078
5079         nm_singleton_instance_register ();
5080         _LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance);
5081
5082         nm_exported_object_export ((NMExportedObject *) self);
5083
5084         return self;
5085 }
5086
5087 static void
5088 constructed (GObject *object)
5089 {
5090         NMManager *self = NM_MANAGER (object);
5091         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5092         NMConfigData *config_data;
5093
5094         G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
5095
5096         _set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr));
5097
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);
5111
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);
5121
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),
5126                           self);
5127
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);
5134
5135         priv->rfkill_mgr = nm_rfkill_manager_new ();
5136         g_signal_connect (priv->rfkill_mgr,
5137                           "rfkill-changed",
5138                           G_CALLBACK (rfkill_manager_rfkill_changed_cb),
5139                           self);
5140
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
5144          * rfkill.
5145          */
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);
5148 }
5149
5150 static void
5151 nm_manager_init (NMManager *self)
5152 {
5153         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5154         guint i;
5155         GFile *file;
5156
5157         /* Initialize rfkill structures and states */
5158         memset (priv->radio_states, 0, sizeof (priv->radio_states));
5159
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;
5166
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;
5173
5174         for (i = 0; i < RFKILL_TYPE_MAX; i++)
5175                 priv->radio_states[i].hw_enabled = TRUE;
5176
5177         priv->sleeping = FALSE;
5178         priv->state = NM_STATE_DISCONNECTED;
5179         priv->startup = TRUE;
5180
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),
5185                           self);
5186
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);
5193
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),
5198                           self);
5199
5200
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);
5206         }
5207
5208         if (priv->fw_monitor) {
5209                 g_signal_connect (priv->fw_monitor, "changed",
5210                                   G_CALLBACK (firmware_dir_changed),
5211                                   self);
5212                 _LOGI (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
5213                              KERNEL_FIRMWARE_DIR);
5214         } else {
5215                 _LOGW (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
5216                        KERNEL_FIRMWARE_DIR);
5217         }
5218
5219         /* Update timestamps in active connections */
5220         priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, self);
5221
5222         priv->metered = NM_METERED_UNKNOWN;
5223 }
5224
5225 static gboolean
5226 device_is_real (GObject *device, gpointer user_data)
5227 {
5228         return nm_device_is_real (NM_DEVICE (device));
5229 }
5230
5231 static void
5232 get_property (GObject *object, guint prop_id,
5233               GValue *value, GParamSpec *pspec)
5234 {
5235         NMManager *self = NM_MANAGER (object);
5236         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5237         NMConfigData *config_data;
5238         const NMGlobalDnsConfig *dns_config;
5239         const char *type;
5240
5241         switch (prop_id) {
5242         case PROP_VERSION:
5243                 g_value_set_string (value, VERSION);
5244                 break;
5245         case PROP_STATE:
5246                 nm_manager_update_state (self);
5247                 g_value_set_uint (value, priv->state);
5248                 break;
5249         case PROP_STARTUP:
5250                 g_value_set_boolean (value, priv->startup);
5251                 break;
5252         case PROP_NETWORKING_ENABLED:
5253                 g_value_set_boolean (value, priv->net_enabled);
5254                 break;
5255         case PROP_WIRELESS_ENABLED:
5256                 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
5257                 break;
5258         case PROP_WIRELESS_HARDWARE_ENABLED:
5259                 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
5260                 break;
5261         case PROP_WWAN_ENABLED:
5262                 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
5263                 break;
5264         case PROP_WWAN_HARDWARE_ENABLED:
5265                 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
5266                 break;
5267         case PROP_WIMAX_ENABLED:
5268                 g_value_set_boolean (value, FALSE);
5269                 break;
5270         case PROP_WIMAX_HARDWARE_ENABLED:
5271                 g_value_set_boolean (value, FALSE);
5272                 break;
5273         case PROP_ACTIVE_CONNECTIONS:
5274                 nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
5275                 break;
5276         case PROP_CONNECTIVITY:
5277                 g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
5278                 break;
5279         case PROP_PRIMARY_CONNECTION:
5280                 nm_utils_g_value_set_object_path (value, priv->primary_connection);
5281                 break;
5282         case PROP_PRIMARY_CONNECTION_TYPE:
5283                 type = NULL;
5284                 if (priv->primary_connection) {
5285                         NMConnection *con;
5286
5287                         con = nm_active_connection_get_applied_connection (priv->primary_connection);
5288                         if (con)
5289                                 type = nm_connection_get_connection_type (con);
5290                 }
5291                 g_value_set_string (value, type ? type : "");
5292                 break;
5293         case PROP_ACTIVATING_CONNECTION:
5294                 nm_utils_g_value_set_object_path (value, priv->activating_connection);
5295                 break;
5296         case PROP_HOSTNAME:
5297                 g_value_set_string (value, priv->hostname);
5298                 break;
5299         case PROP_SLEEPING:
5300                 g_value_set_boolean (value, priv->sleeping);
5301                 break;
5302         case PROP_DEVICES:
5303                 nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
5304                 break;
5305         case PROP_METERED:
5306                 g_value_set_uint (value, priv->metered);
5307                 break;
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);
5312                 break;
5313         case PROP_ALL_DEVICES:
5314                 nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
5315                 break;
5316         default:
5317                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5318                 break;
5319         }
5320 }
5321
5322 static void
5323 set_property (GObject *object, guint prop_id,
5324               const GValue *value, GParamSpec *pspec)
5325 {
5326         NMManager *self = NM_MANAGER (object);
5327         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5328         NMGlobalDnsConfig *dns_config;
5329         GError *error = NULL;
5330
5331         switch (prop_id) {
5332         case PROP_STATE_FILE:
5333                 /* construct-only */
5334                 priv->state_file = g_value_dup_string (value);
5335                 break;
5336         case PROP_NETWORKING_ENABLED:
5337                 /* construct-only */
5338                 priv->net_enabled = g_value_get_boolean (value);
5339                 break;
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);
5344                 } else {
5345                         manager_radio_user_toggled (NM_MANAGER (object),
5346                                                     &priv->radio_states[RFKILL_TYPE_WLAN],
5347                                                     g_value_get_boolean (value));
5348                 }
5349                 break;
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);
5354                 } else {
5355                         manager_radio_user_toggled (NM_MANAGER (object),
5356                                                     &priv->radio_states[RFKILL_TYPE_WWAN],
5357                                                     g_value_get_boolean (value));
5358                 }
5359                 break;
5360         case PROP_WIMAX_ENABLED:
5361                 /* WIMAX is depreacted. This does nothing. */
5362                 break;
5363         case PROP_GLOBAL_DNS_CONFIGURATION:
5364                 dns_config = nm_global_dns_config_from_dbus (value, &error);
5365                 if (!error)
5366                         nm_config_set_global_dns (priv->config, dns_config, &error);
5367
5368                 nm_global_dns_config_free (dns_config);
5369
5370                 if (error) {
5371                         _LOGD (LOGD_CORE, "set global DNS failed with error: %s", error->message);
5372                         g_error_free (error);
5373                 }
5374                 break;
5375         default:
5376                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5377                 break;
5378         }
5379 }
5380
5381 static void
5382 _deinit_device_factory (NMDeviceFactory *factory, gpointer user_data)
5383 {
5384         g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NM_MANAGER (user_data));
5385 }
5386
5387 static void
5388 dispose (GObject *object)
5389 {
5390         NMManager *manager = NM_MANAGER (object);
5391         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5392
5393         g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
5394         priv->auth_chains = NULL;
5395
5396         g_signal_handlers_disconnect_by_func (nm_auth_manager_get (),
5397                                               G_CALLBACK (authority_changed_cb),
5398                                               manager);
5399
5400         g_assert (priv->devices == NULL);
5401
5402         nm_clear_g_source (&priv->ac_cleanup_id);
5403
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);
5409
5410         if (priv->config) {
5411                 g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
5412                 g_clear_object (&priv->config);
5413         }
5414         if (priv->connectivity) {
5415                 g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
5416                 g_clear_object (&priv->connectivity);
5417         }
5418
5419         g_free (priv->hostname);
5420
5421         if (priv->policy) {
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);
5425         }
5426
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);
5434         }
5435
5436         g_clear_pointer (&priv->state_file, g_free);
5437         g_clear_object (&priv->vpn_manager);
5438
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);
5443         }
5444         _set_prop_filter (manager, NULL);
5445
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);
5450         }
5451
5452         if (priv->fw_monitor) {
5453                 g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager);
5454
5455                 nm_clear_g_source (&priv->fw_changed_id);
5456
5457                 g_file_monitor_cancel (priv->fw_monitor);
5458                 g_clear_object (&priv->fw_monitor);
5459         }
5460
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);
5464         }
5465
5466         nm_device_factory_manager_for_each_factory (_deinit_device_factory, manager);
5467
5468         nm_clear_g_source (&priv->timestamp_update_id);
5469
5470         G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
5471 }
5472
5473 static void
5474 nm_manager_class_init (NMManagerClass *manager_class)
5475 {
5476         GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
5477         NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
5478
5479         g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
5480
5481         exported_object_class->export_path = NM_DBUS_PATH;
5482
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;
5488
5489         /* properties */
5490         g_object_class_install_property
5491                 (object_class, PROP_VERSION,
5492                  g_param_spec_string (NM_MANAGER_VERSION, "", "",
5493                                       NULL,
5494                                       G_PARAM_READABLE |
5495                                       G_PARAM_STATIC_STRINGS));
5496
5497         g_object_class_install_property (object_class,
5498                                          PROP_STATE_FILE,
5499                                          g_param_spec_string (NM_MANAGER_STATE_FILE, "", "",
5500                                                               NULL,
5501                                                               G_PARAM_WRITABLE |
5502                                                               G_PARAM_CONSTRUCT_ONLY |
5503                                                               G_PARAM_STATIC_STRINGS));
5504
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,
5509                                     G_PARAM_READABLE |
5510                                     G_PARAM_STATIC_STRINGS));
5511
5512         g_object_class_install_property
5513                 (object_class, PROP_STARTUP,
5514                  g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
5515                                        TRUE,
5516                                        G_PARAM_READABLE |
5517                                        G_PARAM_STATIC_STRINGS));
5518
5519         g_object_class_install_property
5520                 (object_class, PROP_NETWORKING_ENABLED,
5521                  g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
5522                                        TRUE,
5523                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
5524                                        G_PARAM_STATIC_STRINGS));
5525
5526         g_object_class_install_property
5527                 (object_class, PROP_WIRELESS_ENABLED,
5528                  g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
5529                                        TRUE,
5530                                        G_PARAM_READWRITE |
5531                                        G_PARAM_CONSTRUCT |
5532                                        G_PARAM_STATIC_STRINGS));
5533
5534         g_object_class_install_property
5535                 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
5536                  g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
5537                                        TRUE,
5538                                        G_PARAM_READABLE |
5539                                        G_PARAM_STATIC_STRINGS));
5540
5541         g_object_class_install_property
5542                 (object_class, PROP_WWAN_ENABLED,
5543                  g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
5544                                        TRUE,
5545                                        G_PARAM_READWRITE |
5546                                        G_PARAM_CONSTRUCT |
5547                                        G_PARAM_STATIC_STRINGS));
5548
5549         g_object_class_install_property
5550                 (object_class, PROP_WWAN_HARDWARE_ENABLED,
5551                  g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
5552                                        TRUE,
5553                                        G_PARAM_READABLE |
5554                                        G_PARAM_STATIC_STRINGS));
5555
5556         g_object_class_install_property
5557                 (object_class, PROP_WIMAX_ENABLED,
5558                  g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
5559                                        TRUE,
5560                                        G_PARAM_READWRITE |
5561                                        G_PARAM_STATIC_STRINGS));
5562
5563         g_object_class_install_property
5564                 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
5565                  g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
5566                                        TRUE,
5567                                        G_PARAM_READABLE |
5568                                        G_PARAM_STATIC_STRINGS));
5569
5570         g_object_class_install_property
5571                 (object_class, PROP_ACTIVE_CONNECTIONS,
5572                  g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
5573                                      G_TYPE_STRV,
5574                                      G_PARAM_READABLE |
5575                                      G_PARAM_STATIC_STRINGS));
5576
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,
5581                                     G_PARAM_READABLE |
5582                                     G_PARAM_STATIC_STRINGS));
5583
5584         g_object_class_install_property
5585                 (object_class, PROP_PRIMARY_CONNECTION,
5586                  g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION, "", "",
5587                                       NULL,
5588                                       G_PARAM_READABLE |
5589                                       G_PARAM_STATIC_STRINGS));
5590
5591         g_object_class_install_property
5592                 (object_class, PROP_PRIMARY_CONNECTION_TYPE,
5593                  g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "",
5594                                       NULL,
5595                                       G_PARAM_READABLE |
5596                                       G_PARAM_STATIC_STRINGS));
5597
5598
5599         g_object_class_install_property
5600                 (object_class, PROP_ACTIVATING_CONNECTION,
5601                  g_param_spec_string (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
5602                                       NULL,
5603                                       G_PARAM_READABLE |
5604                                       G_PARAM_STATIC_STRINGS));
5605
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, "", "",
5610                                       NULL,
5611                                       G_PARAM_READABLE |
5612                                       G_PARAM_STATIC_STRINGS));
5613
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, "", "",
5618                                        FALSE,
5619                                        G_PARAM_READABLE |
5620                                        G_PARAM_STATIC_STRINGS));
5621
5622         g_object_class_install_property
5623                 (object_class, PROP_DEVICES,
5624                  g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
5625                                      G_TYPE_STRV,
5626                                      G_PARAM_READABLE |
5627                                      G_PARAM_STATIC_STRINGS));
5628
5629         /**
5630          * NMManager:metered:
5631          *
5632          * Whether the connectivity is metered.
5633          *
5634          * Since: 1.2
5635          **/
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,
5640                                     G_PARAM_READABLE |
5641                                     G_PARAM_STATIC_STRINGS));
5642
5643         /**
5644          * NMManager:global-dns-configuration:
5645          *
5646          * The global DNS configuration.
5647          *
5648          * Since: 1.2
5649          **/
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}"),
5654                                        NULL,
5655                                        G_PARAM_READWRITE |
5656                                        G_PARAM_STATIC_STRINGS));
5657
5658         /**
5659          * NMManager:all-devices:
5660          *
5661          * All devices, including those that are not realized.
5662          *
5663          * Since: 1.2
5664          **/
5665         g_object_class_install_property
5666                 (object_class, PROP_ALL_DEVICES,
5667                  g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
5668                                      G_TYPE_STRV,
5669                                      G_PARAM_READABLE |
5670                                      G_PARAM_STATIC_STRINGS));
5671
5672         /* signals */
5673
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),
5678                               G_SIGNAL_RUN_FIRST,
5679                               G_STRUCT_OFFSET (NMManagerClass, device_added),
5680                               NULL, NULL, NULL,
5681                               G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5682
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,
5688                               NULL, NULL, NULL,
5689                               G_TYPE_NONE, 1, G_TYPE_OBJECT);
5690
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),
5695                               G_SIGNAL_RUN_FIRST,
5696                               G_STRUCT_OFFSET (NMManagerClass, device_removed),
5697                               NULL, NULL, NULL,
5698                               G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5699
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,
5705                               NULL, NULL, NULL,
5706                               G_TYPE_NONE, 1, G_TYPE_OBJECT);
5707
5708         signals[STATE_CHANGED] =
5709                 g_signal_new (NM_MANAGER_STATE_CHANGED,
5710                               G_OBJECT_CLASS_TYPE (object_class),
5711                               G_SIGNAL_RUN_FIRST,
5712                               G_STRUCT_OFFSET (NMManagerClass, state_changed),
5713                               NULL, NULL, NULL,
5714                               G_TYPE_NONE, 1, G_TYPE_UINT);
5715
5716         signals[CHECK_PERMISSIONS] =
5717                 g_signal_new ("check-permissions",
5718                               G_OBJECT_CLASS_TYPE (object_class),
5719                               G_SIGNAL_RUN_FIRST,
5720                               0, NULL, NULL, NULL,
5721                               G_TYPE_NONE, 0);
5722
5723         signals[USER_PERMISSIONS_CHANGED] =
5724                 g_signal_new ("user-permissions-changed",
5725                               G_OBJECT_CLASS_TYPE (object_class),
5726                               G_SIGNAL_RUN_FIRST,
5727                               0, NULL, NULL, NULL,
5728                               G_TYPE_NONE, 0);
5729
5730         signals[ACTIVE_CONNECTION_ADDED] =
5731                 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
5732                               G_OBJECT_CLASS_TYPE (object_class),
5733                               G_SIGNAL_RUN_FIRST,
5734                               0, NULL, NULL, NULL,
5735                               G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5736
5737         signals[ACTIVE_CONNECTION_REMOVED] =
5738                 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
5739                               G_OBJECT_CLASS_TYPE (object_class),
5740                               G_SIGNAL_RUN_FIRST,
5741                               0, NULL, NULL, NULL,
5742                               G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5743
5744         signals[CONFIGURE_QUIT] =
5745                 g_signal_new (NM_MANAGER_CONFIGURE_QUIT,
5746                               G_OBJECT_CLASS_TYPE (object_class),
5747                               G_SIGNAL_RUN_FIRST,
5748                               0, NULL, NULL, NULL,
5749                               G_TYPE_NONE, 0);
5750
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,
5766                                                 NULL);
5767 }
5768