dc394a490404eaedc6d8a06129efa6a623199993
[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 static void active_connection_parent_active (NMActiveConnection *active,
230                                              NMActiveConnection *parent_ac,
231                                              NMManager *self);
232
233 /* Returns: whether to notify D-Bus of the removal or not */
234 static gboolean
235 active_connection_remove (NMManager *self, NMActiveConnection *active)
236 {
237         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
238         gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
239         GSList *found;
240
241         /* FIXME: switch to a GList for faster removal */
242         found = g_slist_find (priv->active_connections, active);
243         if (found) {
244                 NMSettingsConnection *connection;
245
246                 priv->active_connections = g_slist_remove (priv->active_connections, active);
247                 g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
248                 g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
249                 g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
250                 g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
251
252                 if (   nm_active_connection_get_assumed (active)
253                     && (connection = nm_active_connection_get_settings_connection (active))
254                     && nm_settings_connection_get_nm_generated_assumed (connection))
255                         g_object_ref (connection);
256                 else
257                         connection = NULL;
258
259                 nm_exported_object_clear_and_unexport (&active);
260
261                 if (   connection
262                     && nm_settings_has_connection (priv->settings, connection)) {
263                         _LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
264                                nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
265                         nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL);
266                         g_object_unref (connection);
267                 }
268         }
269
270         return found && notify;
271 }
272
273 static gboolean
274 _active_connection_cleanup (gpointer user_data)
275 {
276         NMManager *self = NM_MANAGER (user_data);
277         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
278         GSList *iter;
279
280         priv->ac_cleanup_id = 0;
281
282         g_object_freeze_notify (G_OBJECT (self));
283         iter = priv->active_connections;
284         while (iter) {
285                 NMActiveConnection *ac = iter->data;
286
287                 iter = iter->next;
288                 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
289                         if (active_connection_remove (self, ac))
290                                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
291                 }
292         }
293         g_object_thaw_notify (G_OBJECT (self));
294
295         return FALSE;
296 }
297
298 static void
299 active_connection_state_changed (NMActiveConnection *active,
300                                  GParamSpec *pspec,
301                                  NMManager *self)
302 {
303         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
304         NMActiveConnectionState state;
305
306         state = nm_active_connection_get_state (active);
307         if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
308                 /* Destroy active connections from an idle handler to ensure that
309                  * their last property change notifications go out, which wouldn't
310                  * happen if we destroyed them immediately when their state was set
311                  * to DEACTIVATED.
312                  */
313                 if (!priv->ac_cleanup_id)
314                         priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
315         }
316
317         nm_manager_update_state (self);
318 }
319
320 static void
321 active_connection_default_changed (NMActiveConnection *active,
322                                    GParamSpec *pspec,
323                                    NMManager *self)
324 {
325         nm_manager_update_state (self);
326 }
327
328 /**
329  * active_connection_add():
330  * @self: the #NMManager
331  * @active: the #NMActiveConnection to manage
332  *
333  * Begins to track and manage @active.  Increases the refcount of @active.
334  */
335 static void
336 active_connection_add (NMManager *self, NMActiveConnection *active)
337 {
338         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
339
340         g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
341
342         priv->active_connections = g_slist_prepend (priv->active_connections,
343                                                     g_object_ref (active));
344
345         g_signal_connect (active,
346                           "notify::" NM_ACTIVE_CONNECTION_STATE,
347                           G_CALLBACK (active_connection_state_changed),
348                           self);
349         g_signal_connect (active,
350                           "notify::" NM_ACTIVE_CONNECTION_DEFAULT,
351                           G_CALLBACK (active_connection_default_changed),
352                           self);
353         g_signal_connect (active,
354                           "notify::" NM_ACTIVE_CONNECTION_DEFAULT6,
355                           G_CALLBACK (active_connection_default_changed),
356                           self);
357
358         g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
359
360         /* Only notify D-Bus if the active connection is actually exported */
361         if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active)))
362                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
363 }
364
365 const GSList *
366 nm_manager_get_active_connections (NMManager *manager)
367 {
368         return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
369 }
370
371 static NMActiveConnection *
372 find_ac_for_connection (NMManager *manager, NMConnection *connection)
373 {
374         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
375         GSList *iter;
376         const char *uuid = NULL;
377         gboolean is_settings_connection;
378
379         is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
380
381         if (!is_settings_connection)
382                 uuid = nm_connection_get_uuid (connection);
383
384         for (iter = priv->active_connections; iter; iter = iter->next) {
385                 NMActiveConnection *ac = iter->data;
386                 NMSettingsConnection *con;
387
388                 con = nm_active_connection_get_settings_connection (ac);
389
390                 /* depending on whether we have a NMSettingsConnection or a NMConnection,
391                  * we lookup by UUID or by reference. */
392                 if (is_settings_connection) {
393                         if (con != (NMSettingsConnection *) connection)
394                                 continue;
395                 } else {
396                         if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
397                                 continue;
398                 }
399                 if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
400                         return ac;
401         }
402
403         return NULL;
404 }
405
406 /* Filter out connections that are already active.
407  * nm_settings_get_connections() returns sorted list. We need to preserve the
408  * order so that we didn't change auto-activation order (recent timestamps
409  * are first).
410  * Caller is responsible for freeing the returned list with g_slist_free().
411  */
412 GSList *
413 nm_manager_get_activatable_connections (NMManager *manager)
414 {
415         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
416         GSList *all_connections = nm_settings_get_connections (priv->settings);
417         GSList *connections = NULL, *iter;
418         NMSettingsConnection *connection;
419
420         for (iter = all_connections; iter; iter = iter->next) {
421                 connection = iter->data;
422
423                 if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
424                         connections = g_slist_prepend (connections, connection);
425         }
426
427         g_slist_free (all_connections);
428         return g_slist_reverse (connections);
429 }
430
431 static NMActiveConnection *
432 active_connection_get_by_path (NMManager *manager, const char *path)
433 {
434         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
435         GSList *iter;
436
437         g_return_val_if_fail (manager != NULL, NULL);
438         g_return_val_if_fail (path != NULL, NULL);
439
440         for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
441                 NMActiveConnection *candidate = iter->data;
442
443                 if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
444                         return candidate;
445         }
446         return NULL;
447 }
448
449 /************************************************************************/
450
451 static void
452 _config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
453 {
454         g_object_set (NM_MANAGER_GET_PRIVATE (self)->connectivity,
455                       NM_CONNECTIVITY_URI, nm_config_data_get_connectivity_uri (config_data),
456                       NM_CONNECTIVITY_INTERVAL, nm_config_data_get_connectivity_interval (config_data),
457                       NM_CONNECTIVITY_RESPONSE, nm_config_data_get_connectivity_response (config_data),
458                       NULL);
459
460         if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG))
461                 g_object_notify (G_OBJECT (self), NM_MANAGER_GLOBAL_DNS_CONFIGURATION);
462 }
463
464 /************************************************************************/
465
466 static NMDevice *
467 nm_manager_get_device_by_path (NMManager *manager, const char *path)
468 {
469         GSList *iter;
470
471         g_return_val_if_fail (path != NULL, NULL);
472
473         for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
474                 if (!strcmp (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)), path))
475                         return NM_DEVICE (iter->data);
476         }
477         return NULL;
478 }
479
480 NMDevice *
481 nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
482 {
483         GSList *iter;
484
485         for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
486                 NMDevice *device = NM_DEVICE (iter->data);
487
488                 if (nm_device_get_ifindex (device) == ifindex)
489                         return device;
490         }
491
492         return NULL;
493 }
494
495 static NMDevice *
496 find_device_by_hw_addr (NMManager *manager, const char *hwaddr)
497 {
498         GSList *iter;
499         const char *device_addr;
500
501         g_return_val_if_fail (hwaddr != NULL, NULL);
502
503         if (nm_utils_hwaddr_valid (hwaddr, -1)) {
504                 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
505                         device_addr = nm_device_get_hw_address (NM_DEVICE (iter->data));
506                         if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
507                                 return NM_DEVICE (iter->data);
508                 }
509         }
510         return NULL;
511 }
512
513 static NMDevice *
514 find_device_by_ip_iface (NMManager *self, const gchar *iface)
515 {
516         GSList *iter;
517
518         g_return_val_if_fail (iface != NULL, NULL);
519
520         for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
521                 NMDevice *candidate = iter->data;
522
523                 if (   nm_device_is_real (candidate)
524                     && g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
525                         return candidate;
526         }
527         return NULL;
528 }
529
530 /**
531  * find_device_by_iface:
532  * @self: the #NMManager
533  * @iface: the device interface to find
534  * @connection: a connection to ensure the returned device is compatible with
535  * @slave: a slave connection to ensure a master is compatible with
536  *
537  * Finds a device by interface name, preferring realized devices.  If @slave
538  * is given, this function will only return master devices and will ensure
539  * @slave, when activated, can be a slave of the returned master device.  If
540  * @connection is given, this function will only consider devices that are
541  * compatible with @connection.
542  *
543  * Returns: the matching #NMDevice
544  */
545 static NMDevice *
546 find_device_by_iface (NMManager *self,
547                       const char *iface,
548                       NMConnection *connection,
549                       NMConnection *slave)
550 {
551         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
552         NMDevice *fallback = NULL;
553         GSList *iter;
554
555         g_return_val_if_fail (iface != NULL, NULL);
556
557         for (iter = priv->devices; iter; iter = iter->next) {
558                 NMDevice *candidate = iter->data;
559
560                 if (strcmp (nm_device_get_iface (candidate), iface))
561                         continue;
562                 if (connection && !nm_device_check_connection_compatible (candidate, connection))
563                         continue;
564                 if (slave) {
565                         if (!nm_device_is_master (candidate))
566                                 continue;
567                         if (!nm_device_check_slave_connection_compatible (candidate, slave))
568                                 continue;
569                 }
570
571                 if (nm_device_is_real (candidate))
572                         return candidate;
573                 else if (!fallback)
574                         fallback = candidate;
575         }
576         return fallback;
577 }
578
579 static gboolean
580 manager_sleeping (NMManager *self)
581 {
582         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
583
584         if (priv->sleeping || !priv->net_enabled)
585                 return TRUE;
586         return FALSE;
587 }
588
589 static const char *
590 _nm_state_to_string (NMState state)
591 {
592         switch (state) {
593         case NM_STATE_ASLEEP:
594                 return "ASLEEP";
595         case NM_STATE_DISCONNECTED:
596                 return "DISCONNECTED";
597         case NM_STATE_DISCONNECTING:
598                 return "DISCONNECTING";
599         case NM_STATE_CONNECTING:
600                 return "CONNECTING";
601         case NM_STATE_CONNECTED_LOCAL:
602                 return "CONNECTED_LOCAL";
603         case NM_STATE_CONNECTED_SITE:
604                 return "CONNECTED_SITE";
605         case NM_STATE_CONNECTED_GLOBAL:
606                 return "CONNECTED_GLOBAL";
607         case NM_STATE_UNKNOWN:
608         default:
609                 return "UNKNOWN";
610         }
611 }
612
613 static void
614 set_state (NMManager *self, NMState state)
615 {
616         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
617
618         if (priv->state == state)
619                 return;
620
621         priv->state = state;
622
623         _LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
624
625         g_object_notify (G_OBJECT (self), NM_MANAGER_STATE);
626         g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state);
627 }
628
629 static void
630 checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
631 {
632         NMManager *manager = user_data;
633         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
634         NMConnectivityState connectivity;
635
636         if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
637                 connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
638
639                 if (connectivity == NM_CONNECTIVITY_FULL)
640                         set_state (manager, NM_STATE_CONNECTED_GLOBAL);
641                 else if (   connectivity == NM_CONNECTIVITY_PORTAL
642                          || connectivity == NM_CONNECTIVITY_LIMITED)
643                         set_state (manager, NM_STATE_CONNECTED_SITE);
644                 g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY);
645         }
646
647         g_object_unref (manager);
648 }
649
650 static NMState
651 find_best_device_state (NMManager *manager)
652 {
653         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
654         NMState best_state = NM_STATE_DISCONNECTED;
655         GSList *iter;
656
657         for (iter = priv->active_connections; iter; iter = iter->next) {
658                 NMActiveConnection *ac = NM_ACTIVE_CONNECTION (iter->data);
659                 NMActiveConnectionState ac_state = nm_active_connection_get_state (ac);
660
661                 switch (ac_state) {
662                 case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
663                         if (   nm_active_connection_get_default (ac)
664                             || nm_active_connection_get_default6 (ac)) {
665                                 if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL)
666                                         return NM_STATE_CONNECTED_GLOBAL;
667
668                                 best_state = NM_STATE_CONNECTED_SITE;
669                         } else {
670                                 if (best_state < NM_STATE_CONNECTING)
671                                         best_state = NM_STATE_CONNECTED_LOCAL;
672                         }
673                         break;
674                 case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
675                         if (!nm_active_connection_get_assumed (ac)) {
676                                 if (best_state != NM_STATE_CONNECTED_GLOBAL)
677                                         best_state = NM_STATE_CONNECTING;
678                         }
679                         break;
680                 case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
681                         if (!nm_active_connection_get_assumed (ac)) {
682                                 if (best_state < NM_STATE_DISCONNECTING)
683                                         best_state = NM_STATE_DISCONNECTING;
684                         }
685                         break;
686                 default:
687                         break;
688                 }
689         }
690
691         return best_state;
692 }
693
694 static void
695 nm_manager_update_metered (NMManager *self)
696 {
697         NMManagerPrivate *priv;
698         NMDevice *device;
699         NMMetered value = NM_METERED_UNKNOWN;
700
701         g_return_if_fail (NM_IS_MANAGER (self));
702         priv = NM_MANAGER_GET_PRIVATE (self);
703
704         if (priv->primary_connection) {
705                 device =  nm_active_connection_get_device (priv->primary_connection);
706                 if (device)
707                         value = nm_device_get_metered (device);
708         }
709
710         if (value != priv->metered) {
711                 priv->metered = value;
712                 _LOGD (LOGD_CORE, "new metered value: %d", (int) priv->metered);
713                 g_object_notify (G_OBJECT (self), NM_MANAGER_METERED);
714         }
715 }
716
717 static void
718 nm_manager_update_state (NMManager *manager)
719 {
720         NMManagerPrivate *priv;
721         NMState new_state = NM_STATE_DISCONNECTED;
722
723         g_return_if_fail (NM_IS_MANAGER (manager));
724
725         priv = NM_MANAGER_GET_PRIVATE (manager);
726
727         if (manager_sleeping (manager))
728                 new_state = NM_STATE_ASLEEP;
729         else
730                 new_state = find_best_device_state (manager);
731
732         nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
733
734         if (new_state == NM_STATE_CONNECTED_SITE) {
735                 nm_connectivity_check_async (priv->connectivity,
736                                              checked_connectivity,
737                                              g_object_ref (manager));
738         }
739
740         set_state (manager, new_state);
741 }
742
743 static void
744 manager_device_state_changed (NMDevice *device,
745                               NMDeviceState new_state,
746                               NMDeviceState old_state,
747                               NMDeviceStateReason reason,
748                               gpointer user_data)
749 {
750         NMManager *self = NM_MANAGER (user_data);
751         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
752
753         switch (new_state) {
754         case NM_DEVICE_STATE_UNMANAGED:
755         case NM_DEVICE_STATE_UNAVAILABLE:
756         case NM_DEVICE_STATE_DISCONNECTED:
757         case NM_DEVICE_STATE_PREPARE:
758         case NM_DEVICE_STATE_FAILED:
759                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
760                 break;
761         default:
762                 break;
763         }
764
765         if (   new_state == NM_DEVICE_STATE_UNAVAILABLE
766             || new_state == NM_DEVICE_STATE_DISCONNECTED)
767                 nm_settings_device_added (priv->settings, device);
768 }
769
770 static void device_has_pending_action_changed (NMDevice *device,
771                                                GParamSpec *pspec,
772                                                NMManager *self);
773
774 static void
775 check_if_startup_complete (NMManager *self)
776 {
777         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
778         GSList *iter;
779
780         if (!priv->startup)
781                 return;
782
783         if (!priv->devices_inited)
784                 return;
785
786         if (!nm_settings_get_startup_complete (priv->settings)) {
787                 _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
788                 return;
789         }
790
791         for (iter = priv->devices; iter; iter = iter->next) {
792                 NMDevice *dev = iter->data;
793
794                 if (nm_device_has_pending_action (dev)) {
795                         _LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
796                                nm_device_get_iface (dev));
797                         return;
798                 }
799         }
800
801         _LOGI (LOGD_CORE, "startup complete");
802
803         priv->startup = FALSE;
804         g_object_notify (G_OBJECT (self), "startup");
805
806         /* We don't have to watch notify::has-pending-action any more. */
807         for (iter = priv->devices; iter; iter = iter->next) {
808                 NMDevice *dev = iter->data;
809
810                 g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
811         }
812
813         if (nm_config_get_configure_and_quit (nm_config_get ()))
814                 g_signal_emit (self, signals[CONFIGURE_QUIT], 0);
815 }
816
817 static void
818 device_has_pending_action_changed (NMDevice *device,
819                                    GParamSpec *pspec,
820                                    NMManager *self)
821 {
822         check_if_startup_complete (self);
823 }
824
825 static void
826 settings_startup_complete_changed (NMSettings *settings,
827                                    GParamSpec *pspec,
828                                    NMManager *self)
829 {
830         check_if_startup_complete (self);
831 }
832
833 static void
834 remove_device (NMManager *self,
835                NMDevice *device,
836                gboolean quitting,
837                gboolean allow_unmanage)
838 {
839         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
840
841         _LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)",
842                nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
843
844         if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
845                 NMActRequest *req = nm_device_get_act_request (device);
846                 gboolean unmanage = FALSE;
847
848                 /* Leave activated interfaces up when quitting so their configuration
849                  * can be taken over when NM restarts.  This ensures connectivity while
850                  * NM is stopped. Devices which do not support connection assumption
851                  * cannot be left up.
852                  */
853                 if (!quitting)  /* Forced removal; device already gone */
854                         unmanage = TRUE;
855                 else if (!nm_device_can_assume_active_connection (device))
856                         unmanage = TRUE;
857                 else if (!req)
858                         unmanage = TRUE;
859
860                 if (unmanage) {
861                         if (quitting)
862                                 nm_device_set_unmanaged_by_quitting (device);
863                         else
864                                 nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
865                 } else if (quitting && nm_config_get_configure_and_quit (nm_config_get ())) {
866                         nm_device_spawn_iface_helper (device);
867                 }
868         }
869
870         g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
871
872         nm_settings_device_removed (priv->settings, device, quitting);
873         priv->devices = g_slist_remove (priv->devices, device);
874
875         if (nm_device_is_real (device)) {
876                 g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
877                 g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
878                 nm_device_removed (device);
879         }
880         g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device);
881         g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
882
883         nm_exported_object_clear_and_unexport (&device);
884
885         check_if_startup_complete (self);
886 }
887
888 static void
889 device_removed_cb (NMDevice *device, gpointer user_data)
890 {
891         remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
892 }
893
894 NMState
895 nm_manager_get_state (NMManager *manager)
896 {
897         g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
898
899         return NM_MANAGER_GET_PRIVATE (manager)->state;
900 }
901
902 /***************************/
903
904 static NMDevice *
905 find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
906 {
907         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
908         NMDeviceFactory *factory;
909         const char *parent_name = NULL;
910         NMSettingsConnection *parent_connection;
911         NMDevice *parent, *first_compatible = NULL;
912         GSList *iter;
913
914         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
915
916         if (!cached_factory) {
917                 factory = nm_device_factory_manager_find_factory_for_connection (connection);
918                 if (!factory)
919                         return NULL;
920         } else
921                 factory = cached_factory;
922
923         parent_name = nm_device_factory_get_connection_parent (factory, connection);
924         if (!parent_name)
925                 return NULL;
926
927         /* Try as an interface name of a parent device */
928         parent = find_device_by_iface (self, parent_name, NULL, NULL);
929         if (parent)
930                 return parent;
931
932         /* Maybe a hardware address */
933         parent = find_device_by_hw_addr (self, parent_name);
934         if (parent)
935                 return parent;
936
937         /* Maybe a connection UUID */
938         parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name);
939         if (!parent_connection)
940                 return NULL;
941
942         /* Check if the parent connection is currently activated or is comaptible
943          * with some known device.
944          */
945         for (iter = priv->devices; iter; iter = iter->next) {
946                 NMDevice *candidate = iter->data;
947
948                 if (nm_device_get_settings_connection (candidate) == parent_connection)
949                         return candidate;
950
951                 if (   !first_compatible
952                     && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
953                         first_compatible = candidate;
954         }
955
956         return first_compatible;
957 }
958
959 /**
960  * nm_manager_get_connection_iface:
961  * @self: the #NMManager
962  * @connection: the #NMConnection to get the interface for
963  * @out_parent: on success, the parent device if any
964  * @error: an error if determining the virtual interface name failed
965  *
966  * Given @connection, returns the interface name that the connection
967  * would need to use when activated. %NULL is returned if the name
968  * is not specified in connection or a the name for a virtual device
969  * could not be generated.
970  *
971  * Returns: the expected interface name (caller takes ownership), or %NULL
972  */
973 char *
974 nm_manager_get_connection_iface (NMManager *self,
975                                  NMConnection *connection,
976                                  NMDevice **out_parent,
977                                  GError **error)
978 {
979         NMDeviceFactory *factory;
980         char *iface = NULL;
981         NMDevice *parent = NULL;
982
983         if (out_parent)
984                 *out_parent = NULL;
985
986         factory = nm_device_factory_manager_find_factory_for_connection (connection);
987         if (!factory) {
988                 g_set_error (error,
989                              NM_MANAGER_ERROR,
990                              NM_MANAGER_ERROR_FAILED,
991                              "NetworkManager plugin for '%s' unavailable",
992                              nm_connection_get_connection_type (connection));
993                 return NULL;
994         }
995
996         if (   !out_parent
997             && !NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_iface) {
998                 /* optimization. Shortcut lookup of the partent device. */
999                 iface = g_strdup (nm_connection_get_interface_name (connection));
1000                 if (!iface) {
1001                         g_set_error (error,
1002                                      NM_MANAGER_ERROR,
1003                                      NM_MANAGER_ERROR_FAILED,
1004                                      "failed to determine interface name: error determine name for %s",
1005                                      nm_connection_get_connection_type (connection));
1006                 }
1007                 return iface;
1008         }
1009
1010         parent = find_parent_device_for_connection (self, connection, factory);
1011         iface = nm_device_factory_get_connection_iface (factory,
1012                                                         connection,
1013                                                         parent ? nm_device_get_ip_iface (parent) : NULL,
1014                                                         error);
1015         if (!iface)
1016                 return NULL;
1017
1018         if (out_parent)
1019                 *out_parent = parent;
1020         return iface;
1021 }
1022
1023 /**
1024  * system_create_virtual_device:
1025  * @self: the #NMManager
1026  * @connection: the connection which might require a virtual device
1027  *
1028  * If @connection requires a virtual device and one does not yet exist for it,
1029  * creates that device.
1030  *
1031  * Returns: A #NMDevice that was just realized; %NULL if none
1032  */
1033 static NMDevice *
1034 system_create_virtual_device (NMManager *self, NMConnection *connection)
1035 {
1036         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1037         NMDeviceFactory *factory;
1038         gs_free_slist GSList *connections = NULL;
1039         GSList *iter;
1040         gs_free char *iface = NULL;
1041         NMDevice *device = NULL, *parent = NULL;
1042         GError *error = NULL;
1043
1044         g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
1045         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
1046
1047         iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
1048         if (!iface) {
1049                 _LOGD (LOGD_DEVICE, "(%s) can't get a name of a virtual device: %s",
1050                        nm_connection_get_id (connection), error->message);
1051                 g_error_free (error);
1052                 return NULL;
1053         }
1054
1055         /* See if there's a device that is already compatible with this connection */
1056         for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1057                 NMDevice *candidate = iter->data;
1058
1059                 if (nm_device_check_connection_compatible (candidate, connection)) {
1060                         if (nm_device_is_real (candidate)) {
1061                                 _LOGD (LOGD_DEVICE, "(%s) already created virtual interface name %s",
1062                                        nm_connection_get_id (connection), iface);
1063                                 return NULL;
1064                         }
1065
1066                         device = candidate;
1067                         break;
1068                 }
1069         }
1070
1071         if (!device) {
1072                 /* No matching device found. Proceed creating a new one. */
1073
1074                 factory = nm_device_factory_manager_find_factory_for_connection (connection);
1075                 if (!factory) {
1076                         _LOGE (LOGD_DEVICE, "(%s:%s) NetworkManager plugin for '%s' unavailable",
1077                                nm_connection_get_id (connection), iface,
1078                                nm_connection_get_connection_type (connection));
1079                         return NULL;
1080                 }
1081
1082                 device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, &error);
1083                 if (!device) {
1084                         _LOGW (LOGD_DEVICE, "(%s) factory can't create the device: %s",
1085                                nm_connection_get_id (connection), error->message);
1086                         g_error_free (error);
1087                         return NULL;
1088                 }
1089
1090                 _LOGD (LOGD_DEVICE, "(%s) create virtual device %s",
1091                        nm_connection_get_id (connection),
1092                        nm_device_get_iface (device));
1093
1094                 if (!add_device (self, device, &error)) {
1095                         _LOGW (LOGD_DEVICE, "(%s) can't register the device with manager: %s",
1096                                nm_connection_get_id (connection), error->message);
1097                         g_error_free (error);
1098                         g_object_unref (device);
1099                         return NULL;
1100                 }
1101
1102                 /* Add device takes a reference that NMManager still owns, so it's
1103                  * safe to unref here and still return @device.
1104                  */
1105                 g_object_unref (device);
1106         }
1107
1108         /* Create backing resources if the device has any autoconnect connections */
1109         connections = nm_settings_get_connections (priv->settings);
1110         for (iter = connections; iter; iter = g_slist_next (iter)) {
1111                 NMConnection *candidate = iter->data;
1112                 NMSettingConnection *s_con;
1113
1114                 if (!nm_device_check_connection_compatible (device, candidate))
1115                         continue;
1116
1117                 s_con = nm_connection_get_setting_connection (candidate);
1118                 g_assert (s_con);
1119                 if (!nm_setting_connection_get_autoconnect (s_con))
1120                         continue;
1121
1122                 /* Create any backing resources the device needs */
1123                 if (!nm_device_create_and_realize (device, connection, parent, &error)) {
1124                         _LOGW (LOGD_DEVICE, "(%s) couldn't create the device: %s",
1125                                nm_connection_get_id (connection), error->message);
1126                         g_error_free (error);
1127                         remove_device (self, device, FALSE, TRUE);
1128                         return NULL;
1129                 }
1130                 break;
1131         }
1132
1133         return device;
1134 }
1135
1136 static void
1137 retry_connections_for_parent_device (NMManager *self, NMDevice *device)
1138 {
1139         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1140         GSList *connections, *iter;
1141
1142         g_return_if_fail (device);
1143
1144         connections = nm_settings_get_connections (priv->settings);
1145         for (iter = connections; iter; iter = g_slist_next (iter)) {
1146                 NMConnection *candidate = iter->data;
1147                 gs_free_error GError *error = NULL;
1148                 gs_free char *ifname = NULL;
1149                 NMDevice *parent;
1150
1151                 parent = find_parent_device_for_connection (self, candidate, NULL);
1152                 if (parent == device) {
1153                         /* Only try to activate devices that don't already exist */
1154                         ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error);
1155                         if (ifname) {
1156                                 if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
1157                                         connection_changed (priv->settings, candidate, self);
1158                         }
1159                 }
1160         }
1161
1162         g_slist_free (connections);
1163 }
1164
1165 static void
1166 connection_changed (NMSettings *settings,
1167                     NMConnection *connection,
1168                     NMManager *manager)
1169 {
1170         NMDevice *device;
1171
1172         if (!nm_connection_is_virtual (connection))
1173                 return;
1174
1175         device = system_create_virtual_device (manager, connection);
1176         if (!device)
1177                 return;
1178
1179         /* Maybe the device that was created was needed by some other
1180          * connection's device (parent of a VLAN). Let the connections
1181          * can use the newly created device as a parent know. */
1182         retry_connections_for_parent_device (manager, device);
1183 }
1184
1185 static void
1186 connection_removed (NMSettings *settings,
1187                     NMSettingsConnection *connection,
1188                     NMManager *manager)
1189 {
1190         /*
1191          * Do not delete existing virtual devices to keep connectivity up.
1192          * Virtual devices are reused when NetworkManager is restarted.
1193          */
1194 }
1195
1196 static void
1197 system_unmanaged_devices_changed_cb (NMSettings *settings,
1198                                      GParamSpec *pspec,
1199                                      gpointer user_data)
1200 {
1201         NMManager *self = NM_MANAGER (user_data);
1202         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1203         const GSList *unmanaged_specs, *iter;
1204
1205         unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
1206         for (iter = priv->devices; iter; iter = g_slist_next (iter))
1207                 nm_device_set_unmanaged_by_user_config (NM_DEVICE (iter->data), unmanaged_specs);
1208 }
1209
1210 static void
1211 system_hostname_changed_cb (NMSettings *settings,
1212                             GParamSpec *pspec,
1213                             gpointer user_data)
1214 {
1215         NMManager *self = NM_MANAGER (user_data);
1216         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1217         char *hostname;
1218
1219         hostname = nm_settings_get_hostname (priv->settings);
1220
1221         /* nm_settings_get_hostname() does not return an empty hostname. */
1222         nm_assert (!hostname || *hostname);
1223
1224         if (!hostname && !priv->hostname)
1225                 return;
1226         if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) {
1227                 g_free (hostname);
1228                 return;
1229         }
1230
1231         /* realloc, to free possibly trailing data after NUL. */
1232         if (hostname)
1233                 hostname = g_realloc (hostname, strlen (hostname) + 1);
1234
1235         g_free (priv->hostname);
1236         priv->hostname = hostname;
1237         g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
1238
1239         nm_dhcp_manager_set_default_hostname (nm_dhcp_manager_get (), priv->hostname);
1240 }
1241
1242 /*******************************************************************/
1243 /* General NMManager stuff                                         */
1244 /*******************************************************************/
1245
1246 /* Store value into key-file; supported types: boolean, int, string */
1247 static gboolean
1248 write_value_to_state_file (const char *filename,
1249                            const char *group,
1250                            const char *key,
1251                            GType value_type,
1252                            gpointer value,
1253                            GError **error)
1254 {
1255         GKeyFile *key_file;
1256         char *data;
1257         gsize len = 0;
1258         gboolean ret = FALSE;
1259
1260         g_return_val_if_fail (filename != NULL, FALSE);
1261         g_return_val_if_fail (group != NULL, FALSE);
1262         g_return_val_if_fail (key != NULL, FALSE);
1263         g_return_val_if_fail (value_type == G_TYPE_BOOLEAN ||
1264                               value_type == G_TYPE_INT ||
1265                               value_type == G_TYPE_STRING,
1266                               FALSE);
1267
1268         key_file = g_key_file_new ();
1269
1270         g_key_file_set_list_separator (key_file, ',');
1271         g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
1272         switch (value_type) {
1273         case G_TYPE_BOOLEAN:
1274                 g_key_file_set_boolean (key_file, group, key, *((gboolean *) value));
1275                 break;
1276         case G_TYPE_INT:
1277                 g_key_file_set_integer (key_file, group, key, *((gint *) value));
1278                 break;
1279         case G_TYPE_STRING:
1280                 g_key_file_set_string (key_file, group, key, *((const gchar **) value));
1281                 break;
1282         }
1283
1284         data = g_key_file_to_data (key_file, &len, NULL);
1285         if (data) {
1286                 ret = g_file_set_contents (filename, data, len, error);
1287                 g_free (data);
1288         }
1289         g_key_file_free (key_file);
1290
1291         return ret;
1292 }
1293
1294 static gboolean
1295 radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
1296 {
1297         gboolean enabled;
1298
1299         enabled = rstate->user_enabled && rstate->hw_enabled;
1300         if (check_changeable)
1301                 enabled &= rstate->sw_enabled;
1302         return enabled;
1303 }
1304
1305 static gboolean
1306 radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
1307 {
1308         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1309
1310         return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
1311 }
1312
1313 static void
1314 manager_update_radio_enabled (NMManager *self,
1315                               RadioState *rstate,
1316                               gboolean enabled)
1317 {
1318         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1319         GSList *iter;
1320
1321         /* Do nothing for radio types not yet implemented */
1322         if (!rstate->prop)
1323                 return;
1324
1325         g_object_notify (G_OBJECT (self), rstate->prop);
1326
1327         /* Don't touch devices if asleep/networking disabled */
1328         if (manager_sleeping (self))
1329                 return;
1330
1331         /* enable/disable wireless devices as required */
1332         for (iter = priv->devices; iter; iter = iter->next) {
1333                 NMDevice *device = NM_DEVICE (iter->data);
1334
1335                 if (nm_device_get_rfkill_type (device) == rstate->rtype) {
1336                         _LOGD (LOGD_RFKILL, "(%s): setting radio %s",
1337                                nm_device_get_iface (device),
1338                                enabled ? "enabled" : "disabled");
1339                         nm_device_set_enabled (device, enabled);
1340                 }
1341         }
1342 }
1343
1344 static void
1345 update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate)
1346 {
1347         switch (nm_rfkill_manager_get_rfkill_state (rfkill_mgr, rstate->rtype)) {
1348         case RFKILL_UNBLOCKED:
1349                 rstate->sw_enabled = TRUE;
1350                 rstate->hw_enabled = TRUE;
1351                 break;
1352         case RFKILL_SOFT_BLOCKED:
1353                 rstate->sw_enabled = FALSE;
1354                 rstate->hw_enabled = TRUE;
1355                 break;
1356         case RFKILL_HARD_BLOCKED:
1357                 rstate->sw_enabled = FALSE;
1358                 rstate->hw_enabled = FALSE;
1359                 break;
1360         default:
1361                 g_warn_if_reached ();
1362                 break;
1363         }
1364 }
1365
1366 static void
1367 manager_rfkill_update_one_type (NMManager *self,
1368                                 RadioState *rstate,
1369                                 RfKillType rtype)
1370 {
1371         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1372         gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
1373
1374         old_enabled = radio_enabled_for_rstate (rstate, TRUE);
1375         old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1376         old_hwe = rstate->hw_enabled;
1377
1378         /* recheck kernel rfkill state */
1379         update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
1380
1381         /* Print out all states affecting device enablement */
1382         if (rstate->desc) {
1383                 _LOGD (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
1384                        rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
1385         }
1386
1387         /* Log new killswitch state */
1388         new_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1389         if (old_rfkilled != new_rfkilled) {
1390                 _LOGI (LOGD_RFKILL, "%s now %s by radio killswitch",
1391                        rstate->desc,
1392                        new_rfkilled ? "enabled" : "disabled");
1393         }
1394
1395         /* Send out property changed signal for HW enabled */
1396         if (rstate->hw_enabled != old_hwe) {
1397                 if (rstate->hw_prop)
1398                         g_object_notify (G_OBJECT (self), rstate->hw_prop);
1399         }
1400
1401         /* And finally update the actual device radio state itself; respect the
1402          * daemon state here because this is never called from user-triggered
1403          * radio changes and we only want to ignore the daemon enabled state when
1404          * handling user radio change requests.
1405          */
1406         new_enabled = radio_enabled_for_rstate (rstate, TRUE);
1407         if (new_enabled != old_enabled)
1408                 manager_update_radio_enabled (self, rstate, new_enabled);
1409 }
1410
1411 static void
1412 nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
1413 {
1414         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1415         guint i;
1416
1417         if (rtype != RFKILL_TYPE_UNKNOWN)
1418                 manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
1419         else {
1420                 /* Otherwise sync all radio types */
1421                 for (i = 0; i < RFKILL_TYPE_MAX; i++)
1422                         manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
1423         }
1424 }
1425
1426 static void
1427 device_auth_done_cb (NMAuthChain *chain,
1428                      GError *auth_error,
1429                      GDBusMethodInvocation *context,
1430                      gpointer user_data)
1431 {
1432         NMManager *self = NM_MANAGER (user_data);
1433         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1434         GError *error = NULL;
1435         NMAuthCallResult result;
1436         NMDevice *device;
1437         const char *permission;
1438         NMDeviceAuthRequestFunc callback;
1439         NMAuthSubject *subject;
1440
1441         g_assert (context);
1442
1443         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
1444
1445         permission = nm_auth_chain_get_data (chain, "requested-permission");
1446         g_assert (permission);
1447         callback = nm_auth_chain_get_data (chain, "callback");
1448         g_assert (callback);
1449         device = nm_auth_chain_get_data (chain, "device");
1450         g_assert (device);
1451
1452         result = nm_auth_chain_get_result (chain, permission);
1453         subject = nm_auth_chain_get_subject (chain);
1454
1455         if (auth_error) {
1456                 /* translate the auth error into a manager permission denied error */
1457                 _LOGD (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
1458                 error = g_error_new (NM_MANAGER_ERROR,
1459                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
1460                                      "%s request failed: %s",
1461                                      permission, auth_error->message);
1462         } else if (result != NM_AUTH_CALL_RESULT_YES) {
1463                 _LOGD (LOGD_CORE, "%s request failed: not authorized", permission);
1464                 error = g_error_new (NM_MANAGER_ERROR,
1465                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
1466                                      "%s request failed: not authorized",
1467                                      permission);
1468         }
1469
1470         g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
1471
1472         callback (device,
1473                   context,
1474                   subject,
1475                   error,
1476                   nm_auth_chain_get_data (chain, "user-data"));
1477
1478         g_clear_error (&error);
1479         nm_auth_chain_unref (chain);
1480 }
1481
1482 static void
1483 device_auth_request_cb (NMDevice *device,
1484                         GDBusMethodInvocation *context,
1485                         NMConnection *connection,
1486                         const char *permission,
1487                         gboolean allow_interaction,
1488                         NMDeviceAuthRequestFunc callback,
1489                         gpointer user_data,
1490                         NMManager *self)
1491 {
1492         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1493         GError *error = NULL;
1494         NMAuthSubject *subject = NULL;
1495         char *error_desc = NULL;
1496         NMAuthChain *chain;
1497
1498         /* Validate the caller */
1499         subject = nm_auth_subject_new_unix_process_from_context (context);
1500         if (!subject) {
1501                 error = g_error_new_literal (NM_MANAGER_ERROR,
1502                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1503                                              "Failed to get request UID.");
1504                 goto done;
1505         }
1506
1507         /* Ensure the subject has permissions for this connection */
1508         if (connection && !nm_auth_is_subject_in_acl (connection,
1509                                                       subject,
1510                                                       &error_desc)) {
1511                 error = g_error_new_literal (NM_MANAGER_ERROR,
1512                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1513                                              error_desc);
1514                 g_free (error_desc);
1515                 goto done;
1516         }
1517
1518         /* Validate the request */
1519         chain = nm_auth_chain_new_subject (subject, context, device_auth_done_cb, self);
1520         if (!chain) {
1521                 error = g_error_new_literal (NM_MANAGER_ERROR,
1522                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
1523                                              "Unable to authenticate request.");
1524                 goto done;
1525         }
1526
1527         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
1528         nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
1529         nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
1530         nm_auth_chain_set_data (chain, "callback", callback, NULL);
1531         nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
1532         nm_auth_chain_add_call (chain, permission, allow_interaction);
1533
1534 done:
1535         if (error)
1536                 callback (device, context, subject, error, user_data);
1537
1538         g_clear_object (&subject);
1539         g_clear_error (&error);
1540 }
1541
1542 static gboolean
1543 match_connection_filter (NMConnection *connection, gpointer user_data)
1544 {
1545         if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
1546                 return FALSE;
1547
1548         return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
1549 }
1550
1551 /**
1552  * get_existing_connection:
1553  * @manager: #NMManager instance
1554  * @device: #NMDevice instance
1555  * @out_generated: (allow-none): return TRUE, if the connection was generated.
1556  *
1557  * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
1558  *   the device does not support assuming existing connections.
1559  */
1560 static NMSettingsConnection *
1561 get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
1562 {
1563         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1564         gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self);
1565         NMConnection *connection = NULL;
1566         NMSettingsConnection *matched;
1567         NMSettingsConnection *added = NULL;
1568         GError *error = NULL;
1569         NMDevice *master = NULL;
1570         int ifindex = nm_device_get_ifindex (device);
1571
1572         if (out_generated)
1573                 *out_generated = FALSE;
1574
1575         nm_device_capture_initial_config (device);
1576
1577         if (ifindex) {
1578                 int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex);
1579
1580                 if (master_ifindex) {
1581                         master = nm_manager_get_device_by_ifindex (self, master_ifindex);
1582                         if (!master) {
1583                                 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)",
1584                                        nm_device_get_iface (device), nm_platform_link_get_name (NM_PLATFORM_GET, master_ifindex), master_ifindex);
1585                                 return NULL;
1586                         }
1587                         if (!nm_device_get_act_request (master)) {
1588                                 _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates",
1589                                        nm_device_get_iface (device), nm_device_get_iface (master));
1590                                 return NULL;
1591                         }
1592                 }
1593         }
1594
1595         /* The core of the API is nm_device_generate_connection() function and
1596          * update_connection() virtual method and the convenient connection_type
1597          * class attribute. Subclasses supporting the new API must have
1598          * update_connection() implemented, otherwise nm_device_generate_connection()
1599          * returns NULL.
1600          */
1601         connection = nm_device_generate_connection (device, master);
1602         if (!connection)
1603                 return NULL;
1604
1605         /* Now we need to compare the generated connection to each configured
1606          * connection. The comparison function is the heart of the connection
1607          * assumption implementation and it must compare the connections very
1608          * carefully to sort out various corner cases. Also, the comparison is
1609          * not entirely symmetric.
1610          *
1611          * When no configured connection matches the generated connection, we keep
1612          * the generated connection instead.
1613          */
1614         connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections));
1615         matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
1616                                                                      connection,
1617                                                                      nm_device_has_carrier (device),
1618                                                                      nm_device_get_ip4_route_metric (device),
1619                                                                      nm_device_get_ip6_route_metric (device),
1620                                                                      match_connection_filter,
1621                                                                      device));
1622         if (matched) {
1623                 _LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
1624                        nm_device_get_iface (device),
1625                        nm_settings_connection_get_id (matched));
1626                 g_object_unref (connection);
1627                 return matched;
1628         }
1629
1630         _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
1631                nm_device_get_iface (device),
1632                nm_connection_get_id (connection));
1633
1634         added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
1635         if (added) {
1636                 nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
1637                                                   NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
1638                                                   NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
1639                                                   TRUE);
1640                 if (out_generated)
1641                         *out_generated = TRUE;
1642         } else {
1643                 _LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
1644                        nm_device_get_iface (device),
1645                        nm_connection_get_id (connection),
1646                        error->message);
1647                 g_clear_error (&error);
1648         }
1649         g_object_unref (connection);
1650
1651         return added ? added : NULL;
1652 }
1653
1654 static gboolean
1655 assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
1656 {
1657         NMActiveConnection *active, *master_ac;
1658         NMAuthSubject *subject;
1659         GError *error = NULL;
1660
1661         _LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
1662                nm_device_get_iface (device));
1663
1664         /* Move device to DISCONNECTED to activate the connection */
1665         if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
1666                 nm_device_state_changed (device,
1667                                          NM_DEVICE_STATE_DISCONNECTED,
1668                                          NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1669         }
1670         g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1671
1672         subject = nm_auth_subject_new_internal ();
1673         active = _new_active_connection (self, NM_CONNECTION (connection), NULL, device, subject, &error);
1674         g_object_unref (subject);
1675
1676         if (!active) {
1677                 _LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
1678                        nm_connection_get_path (NM_CONNECTION (connection)),
1679                        error->message);
1680                 g_error_free (error);
1681                 return FALSE;
1682         }
1683
1684         /* If the device is a slave or VLAN, find the master ActiveConnection */
1685         master_ac = NULL;
1686         if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
1687                 nm_active_connection_set_master (active, master_ac);
1688
1689         nm_active_connection_set_assumed (active, TRUE);
1690         nm_exported_object_export (NM_EXPORTED_OBJECT (active));
1691         active_connection_add (self, active);
1692         nm_device_queue_activation (device, NM_ACT_REQUEST (active));
1693         g_object_unref (active);
1694
1695         return TRUE;
1696 }
1697
1698 static gboolean
1699 recheck_assume_connection (NMManager *self, NMDevice *device)
1700 {
1701         NMSettingsConnection *connection;
1702         gboolean was_unmanaged = FALSE, success, generated = FALSE;
1703         NMDeviceState state;
1704
1705         g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
1706         g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1707
1708         if (nm_device_get_is_nm_owned (device))
1709                 return FALSE;
1710
1711         if (!nm_device_get_managed (device, FALSE))
1712                 return FALSE;
1713
1714         state = nm_device_get_state (device);
1715         if (state > NM_DEVICE_STATE_DISCONNECTED)
1716                 return FALSE;
1717
1718         connection = get_existing_connection (self, device, &generated);
1719         if (!connection) {
1720                 _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
1721                        nm_device_get_iface (device));
1722                 return FALSE;
1723         }
1724
1725         if (state == NM_DEVICE_STATE_UNMANAGED) {
1726                 was_unmanaged = TRUE;
1727                 nm_device_state_changed (device,
1728                                          NM_DEVICE_STATE_UNAVAILABLE,
1729                                          NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1730         }
1731
1732         success = assume_connection (self, device, connection);
1733         if (!success) {
1734                 if (was_unmanaged) {
1735                         nm_device_state_changed (device,
1736                                                  NM_DEVICE_STATE_UNAVAILABLE,
1737                                                  NM_DEVICE_STATE_REASON_CONFIG_FAILED);
1738                 }
1739
1740                 if (generated) {
1741                         _LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
1742                                nm_device_get_iface (device));
1743
1744                         nm_settings_connection_delete (connection, NULL, NULL);
1745                 }
1746         }
1747
1748         return success;
1749 }
1750
1751 static void
1752 recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
1753 {
1754         recheck_assume_connection (user_data, device);
1755 }
1756
1757 static void
1758 device_ip_iface_changed (NMDevice *device,
1759                          GParamSpec *pspec,
1760                          NMManager *self)
1761 {
1762         const char *ip_iface = nm_device_get_ip_iface (device);
1763         GSList *iter;
1764
1765         /* Remove NMDevice objects that are actually child devices of others,
1766          * when the other device finally knows its IP interface name.  For example,
1767          * remove the PPP interface that's a child of a WWAN device, since it's
1768          * not really a standalone NMDevice.
1769          */
1770         for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
1771                 NMDevice *candidate = NM_DEVICE (iter->data);
1772
1773                 if (   candidate != device
1774                     && g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
1775                     && nm_device_is_real (candidate)) {
1776                         remove_device (self, candidate, FALSE, FALSE);
1777                         break;
1778                 }
1779         }
1780 }
1781
1782 static void
1783 device_iface_changed (NMDevice *device,
1784                       GParamSpec *pspec,
1785                       NMManager *self)
1786 {
1787         /* Virtual connections may refer to the new device name as
1788          * parent device, retry to activate them.
1789          */
1790         retry_connections_for_parent_device (self, device);
1791 }
1792
1793
1794 static void
1795 device_realized (NMDevice *device,
1796                  GParamSpec *pspec,
1797                  NMManager *self)
1798 {
1799         /* Emit D-Bus signals */
1800         g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
1801         g_object_notify (G_OBJECT (self), NM_MANAGER_DEVICES);
1802 }
1803
1804 static void
1805 _device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
1806 {
1807         g_return_if_fail (NM_IS_MANAGER (self));
1808         g_return_if_fail (NM_IS_DEVICE (device));
1809
1810         nm_device_realize_finish (device, plink);
1811
1812         if (!nm_device_get_managed (device, FALSE))
1813                 return;
1814
1815         if (recheck_assume_connection (self, device))
1816                 return;
1817
1818         /* if we failed to assume a connection for the managed device, but the device
1819          * is still unavailable. Set UNAVAILABLE state again, this time with NOW_MANAGED. */
1820         nm_device_state_changed (device,
1821                                  NM_DEVICE_STATE_UNAVAILABLE,
1822                                  NM_DEVICE_STATE_REASON_NOW_MANAGED);
1823         nm_device_emit_recheck_auto_activate (device);
1824 }
1825
1826 /**
1827  * add_device:
1828  * @self: the #NMManager
1829  * @device: the #NMDevice to add
1830  * @error: (out): the #GError
1831  *
1832  * If successful, this function will increase the references count of @device.
1833  * Callers should decrease the reference count.
1834  */
1835 static gboolean
1836 add_device (NMManager *self, NMDevice *device, GError **error)
1837 {
1838         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1839         const char *iface, *type_desc;
1840         RfKillType rtype;
1841         GSList *iter, *remove = NULL;
1842         int ifindex;
1843         const char *dbus_path;
1844
1845         /* No duplicates */
1846         ifindex = nm_device_get_ifindex (device);
1847         if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) {
1848                 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
1849                              "A device with ifindex %d already exists", ifindex);
1850                 return FALSE;
1851         }
1852
1853         /* Remove existing devices owned by the new device; eg remove ethernet
1854          * ports that are owned by a WWAN modem, since udev may announce them
1855          * before the modem is fully discovered.
1856          *
1857          * FIXME: use parent/child device relationships instead of removing
1858          * the child NMDevice entirely
1859          */
1860         for (iter = priv->devices; iter; iter = iter->next) {
1861                 NMDevice *candidate = iter->data;
1862
1863                 iface = nm_device_get_ip_iface (candidate);
1864                 if (nm_device_is_real (candidate) && nm_device_owns_iface (device, iface))
1865                         remove = g_slist_prepend (remove, candidate);
1866         }
1867         for (iter = remove; iter; iter = iter->next)
1868                 remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
1869         g_slist_free (remove);
1870
1871         priv->devices = g_slist_append (priv->devices, g_object_ref (device));
1872
1873         g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
1874                           G_CALLBACK (manager_device_state_changed),
1875                           self);
1876
1877         g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
1878                           G_CALLBACK (device_auth_request_cb),
1879                           self);
1880
1881         g_signal_connect (device, NM_DEVICE_REMOVED,
1882                           G_CALLBACK (device_removed_cb),
1883                           self);
1884
1885         g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
1886                           G_CALLBACK (recheck_assume_connection_cb),
1887                           self);
1888
1889         g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
1890                           G_CALLBACK (device_ip_iface_changed),
1891                           self);
1892
1893         g_signal_connect (device, "notify::" NM_DEVICE_IFACE,
1894                           G_CALLBACK (device_iface_changed),
1895                           self);
1896
1897         g_signal_connect (device, "notify::" NM_DEVICE_REAL,
1898                           G_CALLBACK (device_realized),
1899                           self);
1900
1901         if (priv->startup) {
1902                 g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
1903                                   G_CALLBACK (device_has_pending_action_changed),
1904                                   self);
1905         }
1906
1907         /* Update global rfkill state for this device type with the device's
1908          * rfkill state, and then set this device's rfkill state based on the
1909          * global state.
1910          */
1911         rtype = nm_device_get_rfkill_type (device);
1912         if (rtype != RFKILL_TYPE_UNKNOWN) {
1913                 nm_manager_rfkill_update (self, rtype);
1914                 nm_device_set_enabled (device, radio_enabled_for_type (self, rtype, TRUE));
1915         }
1916
1917         iface = nm_device_get_iface (device);
1918         g_assert (iface);
1919         type_desc = nm_device_get_type_desc (device);
1920         g_assert (type_desc);
1921
1922         nm_device_set_unmanaged_by_user_config (device, nm_settings_get_unmanaged_specs (priv->settings));
1923
1924         nm_device_set_unmanaged_flags (device,
1925                                        NM_UNMANAGED_SLEEPING,
1926                                        manager_sleeping (self));
1927
1928         dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
1929         _LOGI (LOGD_DEVICE, "(%s): new %s device (%s)", iface, type_desc, dbus_path);
1930
1931         nm_settings_device_added (priv->settings, device);
1932         g_signal_emit (self, signals[INTERNAL_DEVICE_ADDED], 0, device);
1933         g_object_notify (G_OBJECT (self), NM_MANAGER_ALL_DEVICES);
1934
1935         for (iter = priv->devices; iter; iter = iter->next) {
1936                 NMDevice *d = iter->data;
1937
1938                 if (d != device)
1939                         nm_device_notify_new_device_added (d, device);
1940         }
1941
1942         /* Virtual connections may refer to the new device as
1943          * parent device, retry to activate them.
1944          */
1945         retry_connections_for_parent_device (self, device);
1946
1947         return TRUE;
1948 }
1949
1950 /*******************************************************************/
1951
1952 static void
1953 factory_device_added_cb (NMDeviceFactory *factory,
1954                          NMDevice *device,
1955                          gpointer user_data)
1956 {
1957         NMManager *self = user_data;
1958         GError *error = NULL;
1959
1960         g_return_if_fail (NM_IS_MANAGER (self));
1961
1962         if (nm_device_realize_start (device, NULL, NULL, &error)) {
1963                 add_device (self, device, NULL);
1964                 _device_realize_finish (self, device, NULL);
1965         } else {
1966                 _LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
1967                        nm_device_get_iface (device), error->message);
1968                 g_error_free (error);
1969         }
1970 }
1971
1972 static gboolean
1973 factory_component_added_cb (NMDeviceFactory *factory,
1974                             GObject *component,
1975                             gpointer user_data)
1976 {
1977         GSList *iter;
1978
1979         g_return_val_if_fail (NM_IS_MANAGER (user_data), FALSE);
1980
1981         for (iter = NM_MANAGER_GET_PRIVATE (user_data)->devices; iter; iter = iter->next) {
1982                 if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
1983                         return TRUE;
1984         }
1985         return FALSE;
1986 }
1987
1988 static void
1989 _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
1990 {
1991         NMManager *self = NM_MANAGER (user_data);
1992
1993         g_signal_connect (factory,
1994                           NM_DEVICE_FACTORY_DEVICE_ADDED,
1995                           G_CALLBACK (factory_device_added_cb),
1996                           self);
1997         g_signal_connect (factory,
1998                           NM_DEVICE_FACTORY_COMPONENT_ADDED,
1999                           G_CALLBACK (factory_component_added_cb),
2000                           self);
2001 }
2002
2003 /*******************************************************************/
2004
2005 static void
2006 platform_link_added (NMManager *self,
2007                      int ifindex,
2008                      const NMPlatformLink *plink)
2009 {
2010         NMDeviceFactory *factory;
2011         NMDevice *device = NULL;
2012         GError *error = NULL;
2013         gboolean nm_plugin_missing = FALSE;
2014         GSList *iter;
2015
2016         g_return_if_fail (ifindex > 0);
2017
2018         if (nm_manager_get_device_by_ifindex (self, ifindex))
2019                 return;
2020
2021         /* Let unrealized devices try to realize themselves with the link */
2022         for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
2023                 NMDevice *candidate = iter->data;
2024                 gboolean compatible = TRUE;
2025
2026                 if (strcmp (nm_device_get_iface (candidate), plink->name))
2027                         continue;
2028
2029                 if (nm_device_is_real (candidate)) {
2030                         /* Ignore the link added event since there's already a realized
2031                          * device with the link's name.
2032                          */
2033                         return;
2034                 } else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
2035                         /* Success */
2036                         _device_realize_finish (self, candidate, plink);
2037                         return;
2038                 }
2039
2040                 _LOGD (LOGD_DEVICE, "(%s): failed to realize from plink: '%s'",
2041                        plink->name, error->message);
2042                 g_clear_error (&error);
2043
2044                 /* Try next unrealized device */
2045         }
2046
2047         /* Try registered device factories */
2048         factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
2049         if (factory) {
2050                 gboolean ignore = FALSE;
2051
2052                 device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
2053                 if (!device) {
2054                         if (!ignore) {
2055                                 _LOGW (LOGD_HW, "%s: factory failed to create device: %s",
2056                                        plink->name, error->message);
2057                                 g_clear_error (&error);
2058                         }
2059                         return;
2060                 }
2061         }
2062
2063         if (device == NULL) {
2064                 switch (plink->type) {
2065                 case NM_LINK_TYPE_WWAN_ETHERNET:
2066                 case NM_LINK_TYPE_BNEP:
2067                 case NM_LINK_TYPE_OLPC_MESH:
2068                 case NM_LINK_TYPE_TEAM:
2069                 case NM_LINK_TYPE_WIFI:
2070                         _LOGI (LOGD_HW, "(%s): '%s' plugin not available; creating generic device",
2071                                plink->name, nm_link_type_to_string (plink->type));
2072                         nm_plugin_missing = TRUE;
2073                         /* fall through */
2074                 default:
2075                         device = nm_device_generic_new (plink);
2076                         break;
2077                 }
2078         }
2079
2080         if (device) {
2081                 if (nm_plugin_missing)
2082                         nm_device_set_nm_plugin_missing (device, TRUE);
2083                 if (nm_device_realize_start (device, plink, NULL, &error)) {
2084                         add_device (self, device, NULL);
2085                         _device_realize_finish (self, device, plink);
2086                 } else {
2087                         _LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
2088                                plink->name, error->message);
2089                         g_clear_error (&error);
2090                 }
2091                 g_object_unref (device);
2092         }
2093 }
2094
2095 typedef struct {
2096         NMManager *self;
2097         int ifindex;
2098 } PlatformLinkCbData;
2099
2100 static gboolean
2101 _platform_link_cb_idle (PlatformLinkCbData *data)
2102 {
2103         NMManager *self = data->self;
2104         const NMPlatformLink *l;
2105
2106         if (!self)
2107                 goto out;
2108
2109         g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
2110
2111         l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
2112         if (l) {
2113                 NMPlatformLink pllink;
2114
2115                 pllink = *l; /* make a copy of the link instance */
2116                 platform_link_added (self, data->ifindex, &pllink);
2117         } else {
2118                 NMDevice *device;
2119                 GError *error = NULL;
2120
2121                 device = nm_manager_get_device_by_ifindex (self, data->ifindex);
2122                 if (device) {
2123                         if (nm_device_is_software (device)) {
2124                                 /* Our software devices stick around until their connection is removed */
2125                                 if (!nm_device_unrealize (device, FALSE, &error)) {
2126                                         _LOGW (LOGD_DEVICE, "(%s): failed to unrealize: %s",
2127                                                nm_device_get_iface (device),
2128                                                error->message);
2129                                         g_clear_error (&error);
2130                                         remove_device (self, device, FALSE, TRUE);
2131                                 }
2132                         } else {
2133                                 /* Hardware and external devices always get removed when their kernel link is gone */
2134                                 remove_device (self, device, FALSE, TRUE);
2135                         }
2136                 }
2137         }
2138
2139 out:
2140         g_slice_free (PlatformLinkCbData, data);
2141         return G_SOURCE_REMOVE;
2142 }
2143
2144 static void
2145 platform_link_cb (NMPlatform *platform,
2146                   NMPObjectType obj_type,
2147                   int ifindex,
2148                   NMPlatformLink *plink,
2149                   NMPlatformSignalChangeType change_type,
2150                   gpointer user_data)
2151 {
2152         PlatformLinkCbData *data;
2153
2154         switch (change_type) {
2155         case NM_PLATFORM_SIGNAL_ADDED:
2156         case NM_PLATFORM_SIGNAL_REMOVED:
2157                 data = g_slice_new (PlatformLinkCbData);
2158                 data->self = NM_MANAGER (user_data);
2159                 data->ifindex = ifindex;
2160                 g_object_add_weak_pointer (G_OBJECT (data->self), (gpointer *) &data->self);
2161                 g_idle_add ((GSourceFunc) _platform_link_cb_idle, data);
2162                 break;
2163         default:
2164                 break;
2165         }
2166 }
2167
2168 static void
2169 platform_query_devices (NMManager *self)
2170 {
2171         GArray *links_array;
2172         NMPlatformLink *links;
2173         int i;
2174
2175         links_array = nm_platform_link_get_all (NM_PLATFORM_GET);
2176         links = (NMPlatformLink *) links_array->data;
2177         for (i = 0; i < links_array->len; i++)
2178                 platform_link_added (self, links[i].ifindex, &links[i]);
2179
2180         g_array_unref (links_array);
2181 }
2182
2183 static void
2184 rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
2185                                   RfKillType rtype,
2186                                   RfKillState udev_state,
2187                                   gpointer user_data)
2188 {
2189         nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
2190 }
2191
2192 const GSList *
2193 nm_manager_get_devices (NMManager *manager)
2194 {
2195         g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2196
2197         return NM_MANAGER_GET_PRIVATE (manager)->devices;
2198 }
2199
2200 static NMDevice *
2201 nm_manager_get_connection_device (NMManager *self,
2202                                   NMConnection *connection)
2203 {
2204         NMActiveConnection *ac = find_ac_for_connection (self, connection);
2205         if (ac == NULL)
2206                 return NULL;
2207
2208         return nm_active_connection_get_device (ac);
2209 }
2210
2211 static NMDevice *
2212 nm_manager_get_best_device_for_connection (NMManager *self,
2213                                            NMConnection *connection,
2214                                            gboolean for_user_request)
2215 {
2216         const GSList *devices, *iter;
2217         NMDevice *act_device = nm_manager_get_connection_device (self, connection);
2218         NMDeviceCheckConAvailableFlags flags;
2219
2220         if (act_device)
2221                 return act_device;
2222
2223         flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
2224
2225         /* Pick the first device that's compatible with the connection. */
2226         devices = nm_manager_get_devices (self);
2227         for (iter = devices; iter; iter = g_slist_next (iter)) {
2228                 NMDevice *device = NM_DEVICE (iter->data);
2229
2230                 if (nm_device_check_connection_available (device, connection, flags, NULL))
2231                         return device;
2232         }
2233
2234         /* No luck. :( */
2235         return NULL;
2236 }
2237
2238 static void
2239 _get_devices (NMManager *self,
2240               GDBusMethodInvocation *context,
2241               gboolean all_devices)
2242 {
2243         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2244         gs_free const char **paths = NULL;
2245         guint i;
2246         GSList *iter;
2247
2248         paths = g_new (const char *, g_slist_length (priv->devices) + 1);
2249
2250         for (i = 0, iter = priv->devices; iter; iter = iter->next) {
2251                 const char *path;
2252
2253                 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
2254                 if (   path
2255                     && (all_devices || nm_device_is_real (iter->data)))
2256                         paths[i++] = path;
2257         }
2258         paths[i++] = NULL;
2259
2260         g_dbus_method_invocation_return_value (context,
2261                                                g_variant_new ("(^ao)", (char **) paths));
2262 }
2263
2264 static void
2265 impl_manager_get_devices (NMManager *self,
2266                           GDBusMethodInvocation *context)
2267 {
2268         _get_devices (self, context, FALSE);
2269 }
2270
2271 static void
2272 impl_manager_get_all_devices (NMManager *self,
2273                               GDBusMethodInvocation *context)
2274 {
2275         _get_devices (self, context, TRUE);
2276 }
2277
2278 static void
2279 impl_manager_get_device_by_ip_iface (NMManager *self,
2280                                      GDBusMethodInvocation *context,
2281                                      const char *iface)
2282 {
2283         NMDevice *device;
2284         const char *path = NULL;
2285
2286         device = find_device_by_ip_iface (self, iface);
2287         if (device)
2288                 path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
2289
2290         if (path == NULL) {
2291                 g_dbus_method_invocation_return_error (context,
2292                                                        NM_MANAGER_ERROR,
2293                                                        NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2294                                                        "No device found for the requested iface.");
2295         } else {
2296                 g_dbus_method_invocation_return_value (context,
2297                                                        g_variant_new ("(o)", path));
2298         }
2299 }
2300
2301 static gboolean
2302 is_compatible_with_slave (NMConnection *master, NMConnection *slave)
2303 {
2304         NMSettingConnection *s_con;
2305
2306         g_return_val_if_fail (master, FALSE);
2307         g_return_val_if_fail (slave, FALSE);
2308
2309         s_con = nm_connection_get_setting_connection (slave);
2310         g_assert (s_con);
2311
2312         return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
2313 }
2314
2315 /**
2316  * find_master:
2317  * @self: #NMManager object
2318  * @connection: the #NMConnection to find the master connection and device for
2319  * @device: the #NMDevice, if any, which will activate @connection
2320  * @out_master_connection: on success, the master connection of @connection if
2321  *   that master connection was found
2322  * @out_master_device: on success, the master device of @connection if that
2323  *   master device was found
2324  * @out_master_ac: on success, the master ActiveConnection of @connection if
2325  *   there already is one
2326  * @error: the error, if an error occurred
2327  *
2328  * Given an #NMConnection, attempts to find its master. If @connection has
2329  * no master, this will return %TRUE and @out_master_connection and
2330  * @out_master_device will be untouched.
2331  *
2332  * If @connection does have a master, then the outputs depend on what is in its
2333  * #NMSettingConnection:master property:
2334  *
2335  * If "master" is the ifname of an existing #NMDevice, and that device has a
2336  * compatible master connection activated or activating on it, then
2337  * @out_master_device, @out_master_connection, and @out_master_ac will all be
2338  * set. If the device exists and is idle, only @out_master_device will be set.
2339  * If the device exists and has an incompatible connection on it, an error
2340  * will be returned.
2341  *
2342  * If "master" is the ifname of a non-existent device, then @out_master_device
2343  * will be %NULL, and @out_master_connection will be a connection whose
2344  * activation would cause the creation of that device. @out_master_ac MAY be
2345  * set in this case as well (if the connection has started activating, but has
2346  * not yet created its device).
2347  *
2348  * If "master" is the UUID of a compatible master connection, then
2349  * @out_master_connection will be the identified connection, and @out_master_device
2350  * and/or @out_master_ac will be set if the connection is currently activating.
2351  * (@out_master_device will not be set if the device exists but does not have
2352  * @out_master_connection active/activating on it.)
2353  *
2354  * Returns: %TRUE if the master device and/or connection could be found or if
2355  *  the connection did not require a master, %FALSE otherwise
2356  **/
2357 static gboolean
2358 find_master (NMManager *self,
2359              NMConnection *connection,
2360              NMDevice *device,
2361              NMSettingsConnection **out_master_connection,
2362              NMDevice **out_master_device,
2363              NMActiveConnection **out_master_ac,
2364              GError **error)
2365 {
2366         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2367         NMSettingConnection *s_con;
2368         const char *master;
2369         NMDevice *master_device = NULL;
2370         NMSettingsConnection *master_connection = NULL;
2371         GSList *iter;
2372
2373         s_con = nm_connection_get_setting_connection (connection);
2374         g_assert (s_con);
2375         master = nm_setting_connection_get_master (s_con);
2376
2377         if (master == NULL)
2378                 return TRUE;  /* success, but no master */
2379
2380         /* Try as an interface name first */
2381         master_device = find_device_by_iface (self, master, NULL, connection);
2382         if (master_device) {
2383                 if (master_device == device) {
2384                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2385                                              "Device cannot be its own master");
2386                         return FALSE;
2387                 }
2388
2389                 master_connection = nm_device_get_settings_connection (master_device);
2390                 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) {
2391                         g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2392                                      "The active connection on %s is not a valid master for '%s'",
2393                                      nm_device_get_iface (master_device),
2394                                      nm_connection_get_id (connection));
2395                         return FALSE;
2396                 }
2397         } else {
2398                 /* Try master as a connection UUID */
2399                 master_connection = nm_settings_get_connection_by_uuid (priv->settings, master);
2400                 if (master_connection) {
2401                         /* Check if the master connection is activated on some device already */
2402                         for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2403                                 NMDevice *candidate = NM_DEVICE (iter->data);
2404
2405                                 if (candidate == device)
2406                                         continue;
2407
2408                                 if (nm_device_get_settings_connection (candidate) == master_connection) {
2409                                         master_device = candidate;
2410                                         break;
2411                                 }
2412                         }
2413                 }
2414         }
2415
2416         if (out_master_connection)
2417                 *out_master_connection = master_connection;
2418         if (out_master_device)
2419                 *out_master_device = master_device;
2420         if (out_master_ac && master_connection)
2421                 *out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection));
2422
2423         if (master_device || master_connection)
2424                 return TRUE;
2425         else {
2426                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2427                                      "Master connection not found or invalid");
2428                 return FALSE;
2429         }
2430 }
2431
2432 /**
2433  * ensure_master_active_connection:
2434  * @self: the #NMManager
2435  * @subject: the #NMAuthSubject representing the requestor of this activation
2436  * @connection: the connection that should depend on @master_connection
2437  * @device: the #NMDevice, if any, which will activate @connection
2438  * @master_connection: the master connection, or %NULL
2439  * @master_device: the master device, or %NULL
2440  * @error: the error, if an error occurred
2441  *
2442  * Determines whether a given #NMConnection depends on another connection to
2443  * be activated, and if so, finds that master connection or creates it.
2444  *
2445  * If @master_device and @master_connection are both set then @master_connection
2446  * MUST already be activated or activating on @master_device, and the function will
2447  * return the existing #NMActiveConnection.
2448  *
2449  * If only @master_device is set, and it has an #NMActiveConnection, then the
2450  * function will return it if it is a compatible master, or an error if not. If it
2451  * doesn't have an AC, then the function will create one if a compatible master
2452  * connection exists, or return an error if not.
2453  *
2454  * If only @master_connection is set, then this will try to find or create a compatible
2455  * #NMDevice, and either activate @master_connection on that device or return an error.
2456  *
2457  * Returns: the master #NMActiveConnection that the caller should depend on, or
2458  * %NULL if an error occurred
2459  */
2460 static NMActiveConnection *
2461 ensure_master_active_connection (NMManager *self,
2462                                  NMAuthSubject *subject,
2463                                  NMConnection *connection,
2464                                  NMDevice *device,
2465                                  NMSettingsConnection *master_connection,
2466                                  NMDevice *master_device,
2467                                  GError **error)
2468 {
2469         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2470         NMActiveConnection *master_ac = NULL;
2471         NMDeviceState master_state;
2472         GSList *iter;
2473
2474         g_assert (connection);
2475         g_assert (master_connection || master_device);
2476
2477         /* If the master device isn't activated then we need to activate it using
2478          * compatible connection.  If it's already activating we can just proceed.
2479          */
2480         if (master_device) {
2481                 NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device);
2482
2483                 /* If we're passed a connection and a device, we require that connection
2484                  * be already activated on the device, eg returned from find_master().
2485                  */
2486                 g_assert (!master_connection || master_connection == device_connection);
2487                 if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) {
2488                         g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2489                                      "The active connection on %s is not a valid master for '%s'",
2490                                      nm_device_get_iface (master_device),
2491                                      nm_connection_get_id (connection));
2492                         return NULL;
2493                 }
2494
2495                 master_state = nm_device_get_state (master_device);
2496                 if (   (master_state == NM_DEVICE_STATE_ACTIVATED)
2497                     || nm_device_is_activating (master_device)) {
2498                         /* Device already using master_connection */
2499                         g_assert (device_connection);
2500                         return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
2501                 }
2502
2503                 /* If the device is disconnected, find a compatible connection and
2504                  * activate it on the device.
2505                  */
2506                 if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
2507                         GSList *connections;
2508
2509                         g_assert (master_connection == NULL);
2510
2511                         /* Find a compatible connection and activate this device using it */
2512                         connections = nm_manager_get_activatable_connections (self);
2513                         for (iter = connections; iter; iter = g_slist_next (iter)) {
2514                                 NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
2515
2516                                 /* Ensure eg bond/team slave and the candidate master is a
2517                                  * bond/team master
2518                                  */
2519                                 if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
2520                                         continue;
2521
2522                                 if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2523                                         master_ac = nm_manager_activate_connection (self,
2524                                                                                     candidate,
2525                                                                                     NULL,
2526                                                                                     master_device,
2527                                                                                     subject,
2528                                                                                     error);
2529                                         if (!master_ac)
2530                                                 g_prefix_error (error, "%s", "Master device activation failed: ");
2531                                         g_slist_free (connections);
2532                                         return master_ac;
2533                                 }
2534                         }
2535                         g_slist_free (connections);
2536
2537                         g_set_error (error,
2538                                      NM_MANAGER_ERROR,
2539                                      NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2540                                      "No compatible connection found for master device %s.",
2541                                      nm_device_get_iface (master_device));
2542                         return NULL;
2543                 }
2544
2545                 /* Otherwise, the device is unmanaged, unavailable, or disconnecting */
2546                 g_set_error (error,
2547                              NM_MANAGER_ERROR,
2548                              NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2549                              "Master device %s unmanaged or not available for activation",
2550                              nm_device_get_iface (master_device));
2551         } else if (master_connection) {
2552                 gboolean found_device = FALSE;
2553
2554                 /* Find a compatible device and activate it using this connection */
2555                 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2556                         NMDevice *candidate = NM_DEVICE (iter->data);
2557
2558                         if (candidate == device) {
2559                                 /* A device obviously can't be its own master */
2560                                 continue;
2561                         }
2562
2563                         if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
2564                                 continue;
2565
2566                         found_device = TRUE;
2567                         if (!nm_device_is_software (candidate)) {
2568                                 master_state = nm_device_get_state (candidate);
2569                                 if (nm_device_is_real (candidate) && master_state != NM_DEVICE_STATE_DISCONNECTED)
2570                                         continue;
2571                         }
2572
2573                         master_ac = nm_manager_activate_connection (self,
2574                                                                     master_connection,
2575                                                                     NULL,
2576                                                                     candidate,
2577                                                                     subject,
2578                                                                     error);
2579                         if (!master_ac)
2580                                 g_prefix_error (error, "%s", "Master device activation failed: ");
2581                         return master_ac;
2582                 }
2583
2584                 g_set_error (error,
2585                              NM_MANAGER_ERROR,
2586                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2587                              "No compatible disconnected device found for master connection %s.",
2588                              nm_settings_connection_get_uuid (master_connection));
2589         } else
2590                 g_assert_not_reached ();
2591
2592         return NULL;
2593 }
2594
2595 /**
2596  * find_slaves:
2597  * @manager: #NMManager object
2598  * @connection: the master #NMSettingsConnection to find slave connections for
2599  * @device: the master #NMDevice for the @connection
2600  *
2601  * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
2602  * master, or has not any slaves, this will return %NULL.
2603  *
2604  * Returns: list of slave connections for given master @connection, or %NULL
2605  **/
2606 static GSList *
2607 find_slaves (NMManager *manager,
2608              NMSettingsConnection *connection,
2609              NMDevice *device)
2610 {
2611         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
2612         GSList *all_connections, *iter;
2613         GSList *slaves = NULL;
2614         NMSettingConnection *s_con;
2615         const char *master;
2616
2617         s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
2618         g_assert (s_con);
2619         master = nm_setting_connection_get_master (s_con);
2620
2621         if (master != NULL)
2622                 return NULL;  /* connection is not master */
2623
2624         /* Search through all connections, not only inactive ones, because
2625          * even if a slave was already active, it might be deactivated during
2626          * master reactivation.
2627          */
2628         all_connections = nm_settings_get_connections (priv->settings);
2629         for (iter = all_connections; iter; iter = iter->next) {
2630                 NMSettingsConnection *master_connection = NULL;
2631                 NMDevice *master_device = NULL;
2632                 NMConnection *candidate = iter->data;
2633
2634                 find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL);
2635                 if (   (master_connection && master_connection == connection)
2636                     || (master_device && master_device == device)) {
2637                         slaves = g_slist_prepend (slaves, candidate);
2638                 }
2639         }
2640         g_slist_free (all_connections);
2641
2642         return g_slist_reverse (slaves);
2643 }
2644
2645 static gboolean
2646 should_connect_slaves (NMConnection *connection, NMDevice *device)
2647 {
2648         NMSettingConnection *s_con;
2649         NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
2650         gs_free char *value = NULL;
2651
2652         s_con = nm_connection_get_setting_connection (connection);
2653         g_assert (s_con);
2654
2655         /* Check autoconnect-slaves property */
2656         autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con);
2657         if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT)
2658                 goto out;
2659
2660         /* Check configuration default for autoconnect-slaves property */
2661         value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
2662                                                        "connection.autoconnect-slaves", device);
2663         if (value)
2664                 autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
2665
2666 out:
2667         if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
2668                 return FALSE;
2669         if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
2670                 return TRUE;
2671         return FALSE;
2672 }
2673
2674 static gboolean
2675 autoconnect_slaves (NMManager *self,
2676                     NMSettingsConnection *master_connection,
2677                     NMDevice *master_device,
2678                     NMAuthSubject *subject)
2679 {
2680         GError *local_err = NULL;
2681         gboolean ret = FALSE;
2682
2683         if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
2684                 GSList *slaves, *iter;
2685
2686                 iter = slaves = find_slaves (self, master_connection, master_device);
2687                 ret = slaves != NULL;
2688
2689                 while (iter) {
2690                         NMSettingsConnection *slave_connection = iter->data;
2691
2692                         iter = iter->next;
2693                         _LOGD (LOGD_CORE, "will activate slave connection '%s' (%s) as a dependency for master '%s' (%s)",
2694                                nm_settings_connection_get_id (slave_connection),
2695                                nm_settings_connection_get_uuid (slave_connection),
2696                                nm_settings_connection_get_id (master_connection),
2697                                nm_settings_connection_get_uuid (master_connection));
2698
2699                         /* Schedule slave activation */
2700                         nm_manager_activate_connection (self,
2701                                                         slave_connection,
2702                                                         NULL,
2703                                                         nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
2704                                                         subject,
2705                                                         &local_err);
2706                         if (local_err) {
2707                                 _LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
2708                                 g_error_free (local_err);
2709                         }
2710                 }
2711                 g_slist_free (slaves);
2712         }
2713         return ret;
2714 }
2715
2716 static gboolean
2717 _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **error)
2718 {
2719         gboolean success;
2720
2721         g_assert (NM_IS_VPN_CONNECTION (active));
2722
2723         nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2724         success = nm_vpn_manager_activate_connection (NM_MANAGER_GET_PRIVATE (self)->vpn_manager,
2725                                                       NM_VPN_CONNECTION (active),
2726                                                       error);
2727         if (success)
2728                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2729         else
2730                 nm_exported_object_unexport (NM_EXPORTED_OBJECT (active));
2731         return success;
2732 }
2733
2734 /* Traverse the device to disconnected state. This means that the device is ready
2735  * for connection and will proceed activating if there's an activation request
2736  * enqueued.
2737  */
2738 static void
2739 unmanaged_to_disconnected (NMDevice *device)
2740 {
2741         /* when creating the software device, it can happen that the device is
2742          * still unmanaged by NM_UNMANAGED_PLATFORM_INIT because we didn't yet
2743          * get the udev event. At this point, we can no longer delay the activation
2744          * and force the device to be managed. */
2745         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2746
2747         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_USER_EXPLICIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
2748
2749         g_return_if_fail (nm_device_get_managed (device, FALSE));
2750
2751         if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
2752                 nm_device_state_changed (device,
2753                                          NM_DEVICE_STATE_UNAVAILABLE,
2754                                          NM_DEVICE_STATE_REASON_USER_REQUESTED);
2755         }
2756
2757         if (   nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)
2758             && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
2759                 nm_device_state_changed (device,
2760                                          NM_DEVICE_STATE_DISCONNECTED,
2761                                          NM_DEVICE_STATE_REASON_USER_REQUESTED);
2762         }
2763 }
2764
2765 /* The parent connection is ready; we can proceed realizing the device and
2766  * progressing the device to disconencted state.
2767  */
2768 static void
2769 active_connection_parent_active (NMActiveConnection *active,
2770                                  NMActiveConnection *parent_ac,
2771                                  NMManager *self)
2772 {
2773         NMDevice *device = nm_active_connection_get_device (active);
2774         GError *error = NULL;
2775
2776         g_signal_handlers_disconnect_by_func (active,
2777                                               (GCallback) active_connection_parent_active,
2778                                               self);
2779
2780         if (parent_ac) {
2781                 NMSettingsConnection *connection = nm_active_connection_get_settings_connection (active);
2782                 NMDevice *parent = nm_active_connection_get_device (parent_ac);
2783
2784                 if (nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) {
2785                         /* We can now proceed to disconnected state so that activation proceeds. */
2786                         unmanaged_to_disconnected (device);
2787                 } else {
2788                         nm_log_warn (LOGD_CORE, "Could not realize device '%s': %s",
2789                                      nm_device_get_iface (device), error->message);
2790                         nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
2791                 }
2792         } else {
2793                 nm_log_warn (LOGD_CORE, "The parent connection device '%s' depended on disappeared.",
2794                              nm_device_get_iface (device));
2795                 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
2796         }
2797 }
2798
2799 static gboolean
2800 _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
2801 {
2802         NMDevice *device, *existing, *master_device = NULL;
2803         NMConnection *applied;
2804         NMSettingsConnection *connection;
2805         NMSettingsConnection *master_connection = NULL;
2806         NMConnection *existing_connection = NULL;
2807         NMActiveConnection *master_ac = NULL;
2808         NMAuthSubject *subject;
2809         char *error_desc = NULL;
2810
2811         g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
2812         g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
2813         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2814
2815         g_assert (NM_IS_VPN_CONNECTION (active) == FALSE);
2816
2817         connection = nm_active_connection_get_settings_connection (active);
2818         g_assert (connection);
2819
2820         applied = nm_active_connection_get_applied_connection (active);
2821
2822         device = nm_active_connection_get_device (active);
2823         g_return_val_if_fail (device != NULL, FALSE);
2824
2825         /* If the device is active and its connection is not visible to the
2826          * user that's requesting this new activation, fail, since other users
2827          * should not be allowed to implicitly deactivate private connections
2828          * by activating a connection of their own.
2829          */
2830         existing_connection = nm_device_get_applied_connection (device);
2831         subject = nm_active_connection_get_subject (active);
2832         if (existing_connection &&
2833             !nm_auth_is_subject_in_acl (existing_connection,
2834                                         subject,
2835                                         &error_desc)) {
2836                 g_set_error (error,
2837                              NM_MANAGER_ERROR,
2838                              NM_MANAGER_ERROR_PERMISSION_DENIED,
2839                              "Private connection already active on the device: %s",
2840                              error_desc);
2841                 g_free (error_desc);
2842                 return FALSE;
2843         }
2844
2845         /* Final connection must be available on device */
2846         if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
2847                 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2848                              "Connection '%s' is not available on the device %s at this time.",
2849                              nm_settings_connection_get_id (connection), nm_device_get_iface (device));
2850                 return FALSE;
2851         }
2852
2853         /* Create any backing resources the device needs */
2854         if (!nm_device_is_real (device)) {
2855                 NMDevice *parent;
2856
2857                 parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
2858
2859                 if (parent && !nm_device_is_real (parent)) {
2860                         NMSettingsConnection *parent_con;
2861                         NMActiveConnection *parent_ac;
2862
2863                         parent_con = nm_device_get_best_connection (parent, NULL, error);
2864                         if (!parent_con) {
2865                                 g_prefix_error (error, "%s failed to create parent: ", nm_device_get_iface (device));
2866                                 return FALSE;
2867                         }
2868
2869                         parent_ac = nm_manager_activate_connection (self, parent_con, NULL, parent, subject, error);
2870                         if (!parent_ac) {
2871                                 g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
2872                                 return FALSE;
2873                         }
2874
2875                         /* We can't realize now; defer until the parent device is ready. */
2876                         g_signal_connect (active,
2877                                           NM_ACTIVE_CONNECTION_PARENT_ACTIVE,
2878                                           (GCallback) active_connection_parent_active,
2879                                           self);
2880                         nm_active_connection_set_parent (active, parent_ac);
2881                 } else {
2882                         /* We can realize now; no need to wait for a parent device. */
2883                         if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
2884                                 g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
2885                                 return FALSE;
2886                         }
2887                 }
2888         }
2889
2890         /* Try to find the master connection/device if the connection has a dependency */
2891         if (!find_master (self, applied, device,
2892                           &master_connection, &master_device, &master_ac,
2893                           error))
2894                 return FALSE;
2895
2896         /* Ensure there's a master active connection the new connection we're
2897          * activating can depend on.
2898          */
2899         if (master_connection || master_device) {
2900                 if (master_connection) {
2901                         _LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
2902                                nm_settings_connection_get_id (connection),
2903                                nm_settings_connection_get_id (master_connection));
2904                 }
2905                 if (master_device) {
2906                         _LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'",
2907                                nm_settings_connection_get_id (connection),
2908                                nm_device_get_ip_iface (master_device));
2909                 }
2910
2911                 /* Ensure eg bond slave and the candidate master is a bond master */
2912                 if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) {
2913                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2914                                              "The master connection was not compatible");
2915                         return FALSE;
2916                 }
2917
2918                 if (!master_ac) {
2919                         master_ac = ensure_master_active_connection (self,
2920                                                                      nm_active_connection_get_subject (active),
2921                                                                      applied,
2922                                                                      device,
2923                                                                      master_connection,
2924                                                                      master_device,
2925                                                                      error);
2926                         if (!master_ac) {
2927                                 if (error)
2928                                         g_assert (*error);
2929                                 return FALSE;
2930                         }
2931                 }
2932
2933                 nm_active_connection_set_master (active, master_ac);
2934                 _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
2935                        nm_settings_connection_get_id (connection),
2936                        master_ac,
2937                        nm_exported_object_get_path (NM_EXPORTED_OBJECT  (master_ac)) ?: "");
2938         }
2939
2940         /* Check slaves for master connection and possibly activate them */
2941         autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
2942
2943         /* Disconnect the connection if connected or queued on another device */
2944         existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
2945         if (existing)
2946                 nm_device_steal_connection (existing, connection);
2947
2948         /* If the device is there, we can ready it for the activation. */
2949         if (nm_device_is_real (device))
2950                 unmanaged_to_disconnected (device);
2951
2952         /* Export the new ActiveConnection to clients and start it on the device */
2953         nm_exported_object_export (NM_EXPORTED_OBJECT (active));
2954         g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
2955         nm_device_queue_activation (device, NM_ACT_REQUEST (active));
2956         return TRUE;
2957 }
2958
2959 static gboolean
2960 _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError **error)
2961 {
2962         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2963         gboolean success = FALSE;
2964
2965         /* Ensure activation request is still valid, eg that its device hasn't gone
2966          * away or that some other dependency has not failed.
2967          */
2968         if (nm_active_connection_get_state (active) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
2969                 g_set_error_literal (error,
2970                                      NM_MANAGER_ERROR,
2971                                      NM_MANAGER_ERROR_DEPENDENCY_FAILED,
2972                                      "Activation failed because dependencies failed.");
2973                 return FALSE;
2974         }
2975
2976         if (NM_IS_VPN_CONNECTION (active))
2977                 success = _internal_activate_vpn (self, active, error);
2978         else
2979                 success = _internal_activate_device (self, active, error);
2980
2981         if (success) {
2982                 /* Force an update of the Manager's activating-connection property.
2983                  * The device changes state before the AC gets exported, which causes
2984                  * the manager's 'activating-connection' property to be NULL since the
2985                  * AC only gets a D-Bus path when it's exported.  So now that the AC
2986                  * is exported, make sure the manager's activating-connection property
2987                  * is up-to-date.
2988                  */
2989                 active_connection_add (self, active);
2990                 policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
2991         }
2992
2993         return success;
2994 }
2995
2996 static NMActiveConnection *
2997 _new_vpn_active_connection (NMManager *self,
2998                             NMSettingsConnection *settings_connection,
2999                             const char *specific_object,
3000                             NMAuthSubject *subject,
3001                             GError **error)
3002 {
3003         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3004         NMActiveConnection *parent = NULL;
3005         NMDevice *device = NULL;
3006
3007         g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
3008
3009         if (specific_object) {
3010                 /* Find the specific connection the client requested we use */
3011                 parent = active_connection_get_by_path (self, specific_object);
3012                 if (!parent) {
3013                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3014                                              "Base connection for VPN connection not active.");
3015                         return NULL;
3016                 }
3017         } else
3018                 parent = priv->primary_connection;
3019
3020         if (!parent) {
3021                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3022                                      "Could not find source connection.");
3023                 return NULL;
3024         }
3025
3026         device = nm_active_connection_get_device (parent);
3027         if (!device) {
3028                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3029                                      "Source connection had no active device.");
3030                 return NULL;
3031         }
3032
3033         return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
3034                                                              device,
3035                                                              nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)),
3036                                                              subject);
3037 }
3038
3039 static NMActiveConnection *
3040 _new_active_connection (NMManager *self,
3041                         NMConnection *connection,
3042                         const char *specific_object,
3043                         NMDevice *device,
3044                         NMAuthSubject *subject,
3045                         GError **error)
3046 {
3047         NMSettingsConnection *settings_connection = NULL;
3048         NMActiveConnection *existing_ac;
3049         gboolean is_vpn;
3050
3051         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
3052         g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
3053
3054         /* Can't create new AC for already-active connection */
3055         existing_ac = find_ac_for_connection (self, connection);
3056         if (NM_IS_VPN_CONNECTION (existing_ac)) {
3057                 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
3058                              "Connection '%s' is already active",
3059                              nm_connection_get_id (connection));
3060                 return NULL;
3061         }
3062
3063         /* Normalize the specific object */
3064         if (specific_object && g_strcmp0 (specific_object, "/") == 0)
3065                 specific_object = NULL;
3066
3067         is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME);
3068
3069         if (NM_IS_SETTINGS_CONNECTION (connection))
3070                 settings_connection = (NMSettingsConnection *) connection;
3071
3072         if (is_vpn) {
3073                 return _new_vpn_active_connection (self,
3074                                                    settings_connection,
3075                                                    specific_object,
3076                                                    subject,
3077                                                    error);
3078         }
3079
3080         return (NMActiveConnection *) nm_act_request_new (settings_connection,
3081                                                           specific_object,
3082                                                           subject,
3083                                                           device);
3084 }
3085
3086 static void
3087 _internal_activation_failed (NMManager *self,
3088                              NMActiveConnection *active,
3089                              const char *error_desc)
3090 {
3091         _LOGD (LOGD_CORE, "Failed to activate '%s': %s",
3092                nm_active_connection_get_settings_connection_id (active),
3093                error_desc);
3094
3095         if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
3096                 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
3097                 nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
3098         }
3099 }
3100
3101 static void
3102 _internal_activation_auth_done (NMActiveConnection *active,
3103                                 gboolean success,
3104                                 const char *error_desc,
3105                                 gpointer user_data1,
3106                                 gpointer user_data2)
3107 {
3108         NMManager *self = user_data1;
3109         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3110         GError *error = NULL;
3111
3112         priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
3113
3114         if (success) {
3115                 if (_internal_activate_generic (self, active, &error)) {
3116                         g_object_unref (active);
3117                         return;
3118                 }
3119         }
3120
3121         g_assert (error_desc || error);
3122         _internal_activation_failed (self, active, error_desc ? error_desc : error->message);
3123         g_object_unref (active);
3124         g_clear_error (&error);
3125 }
3126
3127 /**
3128  * nm_manager_activate_connection():
3129  * @self: the #NMManager
3130  * @connection: the #NMSettingsConnection to activate on @device
3131  * @specific_object: the specific object path, if any, for the activation
3132  * @device: the #NMDevice to activate @connection on
3133  * @subject: the subject which requested activation
3134  * @error: return location for an error
3135  *
3136  * Begins a new internally-initiated activation of @connection on @device.
3137  * @subject should be the subject of the activation that triggered this
3138  * one, or if this is an autoconnect request, a new internal subject.
3139  * The returned #NMActiveConnection is owned by the Manager and should be
3140  * referenced by the caller if the caller continues to use it.
3141  *
3142  * Returns: (transfer none): the new #NMActiveConnection that tracks
3143  * activation of @connection on @device
3144  */
3145 NMActiveConnection *
3146 nm_manager_activate_connection (NMManager *self,
3147                                 NMSettingsConnection *connection,
3148                                 const char *specific_object,
3149                                 NMDevice *device,
3150                                 NMAuthSubject *subject,
3151                                 GError **error)
3152 {
3153         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3154         NMActiveConnection *active;
3155         char *error_desc = NULL;
3156         GSList *iter;
3157
3158         g_return_val_if_fail (self != NULL, NULL);
3159         g_return_val_if_fail (connection != NULL, NULL);
3160         g_return_val_if_fail (error != NULL, NULL);
3161         g_return_val_if_fail (*error == NULL, NULL);
3162
3163         /* Ensure the subject has permissions for this connection */
3164         if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3165                                         subject,
3166                                         &error_desc)) {
3167                 g_set_error_literal (error,
3168                                      NM_MANAGER_ERROR,
3169                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3170                                      error_desc);
3171                 g_free (error_desc);
3172                 return NULL;
3173         }
3174
3175         /* Look for a active connection that's equivalent and is already pending authorization
3176          * and eventual activation. This is used to de-duplicate concurrent activations which would
3177          * otherwise race and cause the device to disconnect and reconnect repeatedly.
3178          * In particular, this allows the master and multiple slaves to concurrently auto-activate
3179          * while all the slaves would use the same active-connection. */
3180         for (iter = priv->authorizing_connections; iter; iter = g_slist_next (iter)) {
3181                 active = iter->data;
3182
3183                 if (   connection == nm_active_connection_get_settings_connection (active)
3184                     && g_strcmp0 (nm_active_connection_get_specific_object (active), specific_object) == 0
3185                     && nm_active_connection_get_device (active) == device
3186                     && nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
3187                     && nm_auth_subject_is_internal (subject))
3188                         return active;
3189         }
3190
3191         active = _new_active_connection (self,
3192                                          NM_CONNECTION (connection),
3193                                          specific_object,
3194                                          device,
3195                                          subject,
3196                                          error);
3197         if (active) {
3198                 priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
3199                 nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL);
3200         }
3201         return active;
3202 }
3203
3204 /**
3205  * validate_activation_request:
3206  * @self: the #NMManager
3207  * @context: the D-Bus context of the requestor
3208  * @connection: the partial or complete #NMConnection to be activated
3209  * @device_path: the object path of the device to be activated, or "/"
3210  * @out_device: on successful reutrn, the #NMDevice to be activated with @connection
3211  * @out_vpn: on successful return, %TRUE if @connection is a VPN connection
3212  * @error: location to store an error on failure
3213  *
3214  * Performs basic validation on an activation request, including ensuring that
3215  * the requestor is a valid Unix process, is not disallowed in @connection
3216  * permissions, and that a device exists that can activate @connection.
3217  *
3218  * Returns: on success, the #NMAuthSubject representing the requestor, or
3219  *   %NULL on error
3220  */
3221 static NMAuthSubject *
3222 validate_activation_request (NMManager *self,
3223                              GDBusMethodInvocation *context,
3224                              NMConnection *connection,
3225                              const char *device_path,
3226                              NMDevice **out_device,
3227                              gboolean *out_vpn,
3228                              GError **error)
3229 {
3230         NMDevice *device = NULL;
3231         gboolean vpn = FALSE;
3232         NMAuthSubject *subject = NULL;
3233         char *error_desc = NULL;
3234
3235         g_assert (connection);
3236         g_assert (out_device);
3237         g_assert (out_vpn);
3238
3239         /* Validate the caller */
3240         subject = nm_auth_subject_new_unix_process_from_context (context);
3241         if (!subject) {
3242                 g_set_error_literal (error,
3243                                      NM_MANAGER_ERROR,
3244                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3245                                      "Failed to get request UID.");
3246                 return NULL;
3247         }
3248
3249         /* Ensure the subject has permissions for this connection */
3250         if (!nm_auth_is_subject_in_acl (connection,
3251                                         subject,
3252                                         &error_desc)) {
3253                 g_set_error_literal (error,
3254                                      NM_MANAGER_ERROR,
3255                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3256                                      error_desc);
3257                 g_free (error_desc);
3258                 goto error;
3259         }
3260
3261         /* Not implemented yet, we want to fail early */
3262         if (   nm_connection_get_setting_connection (connection)
3263             && nm_connection_get_setting_ip6_config (connection)
3264             && !strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG),
3265                         NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
3266                 g_set_error_literal (error,
3267                                      NM_MANAGER_ERROR,
3268                                      NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
3269                                      "Sharing IPv6 connections is not supported yet.");
3270                 return NULL;
3271         }
3272
3273         /* Check whether it's a VPN or not */
3274         if (   nm_connection_get_setting_vpn (connection)
3275             || nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME))
3276                 vpn = TRUE;
3277
3278         /* Normalize device path */
3279         if (device_path && g_strcmp0 (device_path, "/") == 0)
3280                 device_path = NULL;
3281
3282         /* And validate it */
3283         if (device_path) {
3284                 device = nm_manager_get_device_by_path (self, device_path);
3285                 if (!device) {
3286                         g_set_error_literal (error,
3287                                              NM_MANAGER_ERROR,
3288                                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3289                                              "Device not found");
3290                         goto error;
3291                 }
3292         } else
3293                 device = nm_manager_get_best_device_for_connection (self, connection, TRUE);
3294
3295         if (!device && !vpn) {
3296                 gboolean is_software = nm_connection_is_virtual (connection);
3297
3298                 /* VPN and software-device connections don't need a device yet */
3299                 if (!is_software) {
3300                         g_set_error_literal (error,
3301                                              NM_MANAGER_ERROR,
3302                                              NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3303                                              "No suitable device found for this connection.");
3304                         goto error;
3305                 }
3306
3307                 if (is_software) {
3308                         char *iface;
3309
3310                         /* Look for an existing device with the connection's interface name */
3311                         iface = nm_manager_get_connection_iface (self, connection, NULL, error);
3312                         if (!iface)
3313                                 goto error;
3314
3315                         device = find_device_by_iface (self, iface, connection, NULL);
3316                         g_free (iface);
3317                 }
3318         }
3319
3320         if ((!vpn || device_path) && !device) {
3321                 g_set_error_literal (error,
3322                                      NM_MANAGER_ERROR,
3323                                      NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3324                                      "Failed to find a compatible device for this connection");
3325                 goto error;
3326         }
3327
3328         *out_device = device;
3329         *out_vpn = vpn;
3330         return subject;
3331
3332 error:
3333         g_object_unref (subject);
3334         return NULL;
3335 }
3336
3337 /***********************************************************************/
3338
3339 static void
3340 _activation_auth_done (NMActiveConnection *active,
3341                        gboolean success,
3342                        const char *error_desc,
3343                        gpointer user_data1,
3344                        gpointer user_data2)
3345 {
3346         NMManager *self = user_data1;
3347         GDBusMethodInvocation *context = user_data2;
3348         GError *error = NULL;
3349         NMAuthSubject *subject;
3350         NMSettingsConnection *connection;
3351
3352         subject = nm_active_connection_get_subject (active);
3353         connection = nm_active_connection_get_settings_connection (active);
3354
3355         if (success) {
3356                 if (_internal_activate_generic (self, active, &error)) {
3357                         g_dbus_method_invocation_return_value (context,
3358                                                                g_variant_new ("(o)",
3359                                                                nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3360                         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE,
3361                                                     subject, NULL);
3362                         g_object_unref (active);
3363                         return;
3364                 }
3365         } else {
3366                 error = g_error_new_literal (NM_MANAGER_ERROR,
3367                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3368                                              error_desc);
3369         }
3370
3371         g_assert (error);
3372         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3373                                     subject, error->message);
3374         _internal_activation_failed (self, active, error->message);
3375
3376         g_object_unref (active);
3377         g_dbus_method_invocation_take_error (context, error);
3378 }
3379
3380 static void
3381 impl_manager_activate_connection (NMManager *self,
3382                                   GDBusMethodInvocation *context,
3383                                   const char *connection_path,
3384                                   const char *device_path,
3385                                   const char *specific_object_path)
3386 {
3387         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3388         NMActiveConnection *active = NULL;
3389         NMAuthSubject *subject = NULL;
3390         NMSettingsConnection *connection = NULL;
3391         NMDevice *device = NULL;
3392         gboolean is_vpn = FALSE;
3393         GError *error = NULL;
3394
3395         /* Normalize object paths */
3396         if (g_strcmp0 (connection_path, "/") == 0)
3397                 connection_path = NULL;
3398         if (g_strcmp0 (specific_object_path, "/") == 0)
3399                 specific_object_path = NULL;
3400         if (g_strcmp0 (device_path, "/") == 0)
3401                 device_path = NULL;
3402
3403         /* If the connection path is given and valid, that connection is activated.
3404          * Otherwise the "best" connection for the device is chosen and activated,
3405          * regardless of whether that connection is autoconnect-enabled or not
3406          * (since this is an explicit request, not an auto-activation request).
3407          */
3408         if (connection_path) {
3409                 connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
3410                 if (!connection) {
3411                         error = g_error_new_literal (NM_MANAGER_ERROR,
3412                                                      NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3413                                                      "Connection could not be found.");
3414                         goto error;
3415                 }
3416         } else {
3417                 /* If no connection is given, find a suitable connection for the given device path */
3418                 if (!device_path) {
3419                         error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3420                                                      "Only devices may be activated without a specifying a connection");
3421                         goto error;
3422                 }
3423                 device = nm_manager_get_device_by_path (self, device_path);
3424                 if (!device) {
3425                         error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3426                                              "Cannot activate unknown device %s", device_path);
3427                         goto error;
3428                 }
3429
3430                 connection = nm_device_get_best_connection (device, specific_object_path, &error);
3431                 if (!connection)
3432                         goto error;
3433         }
3434
3435         subject = validate_activation_request (self,
3436                                                context,
3437                                                NM_CONNECTION (connection),
3438                                                device_path,
3439                                                &device,
3440                                                &is_vpn,
3441                                                &error);
3442         if (!subject)
3443                 goto error;
3444
3445         active = _new_active_connection (self,
3446                                          NM_CONNECTION (connection),
3447                                          specific_object_path,
3448                                          device,
3449                                          subject,
3450                                          &error);
3451         if (!active)
3452                 goto error;
3453
3454         nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context);
3455         g_clear_object (&subject);
3456         return;
3457
3458 error:
3459         if (connection) {
3460                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE,
3461                                             subject, error->message);
3462         }
3463         g_clear_object (&active);
3464         g_clear_object (&subject);
3465
3466         g_assert (error);
3467         g_dbus_method_invocation_take_error (context, error);
3468 }
3469
3470 /***********************************************************************/
3471
3472 typedef struct {
3473         NMManager *manager;
3474         NMActiveConnection *active;
3475 } AddAndActivateInfo;
3476
3477 static void
3478 activation_add_done (NMSettings *settings,
3479                      NMSettingsConnection *new_connection,
3480                      GError *error,
3481                      GDBusMethodInvocation *context,
3482                      NMAuthSubject *subject,
3483                      gpointer user_data)
3484 {
3485         AddAndActivateInfo *info = user_data;
3486         NMManager *self;
3487         gs_unref_object NMActiveConnection *active = NULL;
3488         GError *local = NULL;
3489
3490         self = info->manager;
3491         active = info->active;
3492         g_slice_free (AddAndActivateInfo, info);
3493
3494         if (!error) {
3495                 nm_active_connection_set_settings_connection (active, new_connection);
3496
3497                 if (_internal_activate_generic (self, active, &local)) {
3498                         nm_settings_connection_commit_changes (new_connection,
3499                                                                NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
3500                                                                NULL, NULL);
3501                         g_dbus_method_invocation_return_value (
3502                             context,
3503                             g_variant_new ("(oo)",
3504                                            nm_connection_get_path (NM_CONNECTION (new_connection)),
3505                                            nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
3506                         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3507                                                     nm_active_connection_get_settings_connection (active),
3508                                                     TRUE,
3509                                                     nm_active_connection_get_subject (active),
3510                                                     NULL);
3511                         return;
3512                 }
3513                 error = local;
3514         }
3515
3516         g_assert (error);
3517         _internal_activation_failed (self, active, error->message);
3518         nm_settings_connection_delete (new_connection, NULL, NULL);
3519         g_dbus_method_invocation_return_gerror (context, error);
3520         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3521                                     NULL,
3522                                     FALSE,
3523                                     nm_active_connection_get_subject (active),
3524                                     error->message);
3525         g_clear_error (&local);
3526 }
3527
3528 static void
3529 _add_and_activate_auth_done (NMActiveConnection *active,
3530                              gboolean success,
3531                              const char *error_desc,
3532                              gpointer user_data1,
3533                              gpointer user_data2)
3534 {
3535         NMManager *self = user_data1;
3536         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3537         GDBusMethodInvocation *context = user_data2;
3538         AddAndActivateInfo *info;
3539         GError *error = NULL;
3540
3541         if (success) {
3542                 NMConnection *connection;
3543
3544                 connection = g_object_steal_data (G_OBJECT (active),
3545                                                   TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE);
3546
3547                 info = g_slice_new (AddAndActivateInfo);
3548                 info->manager = self;
3549                 info->active = g_object_ref (active);
3550
3551                 /* Basic sender auth checks performed; try to add the connection */
3552                 nm_settings_add_connection_dbus (priv->settings,
3553                                                  connection,
3554                                                  FALSE,
3555                                                  context,
3556                                                  activation_add_done,
3557                                                  info);
3558                 g_object_unref (connection);
3559         } else {
3560                 g_assert (error_desc);
3561                 error = g_error_new_literal (NM_MANAGER_ERROR,
3562                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3563                                              error_desc);
3564                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
3565                                             NULL,
3566                                             FALSE,
3567                                             nm_active_connection_get_subject (active),
3568                                             error->message);
3569                 g_dbus_method_invocation_take_error (context, error);
3570         }
3571
3572         g_object_unref (active);
3573 }
3574
3575 static void
3576 impl_manager_add_and_activate_connection (NMManager *self,
3577                                           GDBusMethodInvocation *context,
3578                                           GVariant *settings,
3579                                           const char *device_path,
3580                                           const char *specific_object_path)
3581 {
3582         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3583         NMConnection *connection = NULL;
3584         GSList *all_connections = NULL;
3585         NMActiveConnection *active = NULL;
3586         NMAuthSubject *subject = NULL;
3587         GError *error = NULL;
3588         NMDevice *device = NULL;
3589         gboolean vpn = FALSE;
3590
3591         /* Normalize object paths */
3592         if (g_strcmp0 (specific_object_path, "/") == 0)
3593                 specific_object_path = NULL;
3594         if (g_strcmp0 (device_path, "/") == 0)
3595                 device_path = NULL;
3596
3597         /* Try to create a new connection with the given settings.
3598          * We allow empty settings for AddAndActivateConnection(). In that case,
3599          * the connection will be completed in nm_utils_complete_generic() or
3600          * nm_device_complete_connection() below. Just make sure we don't expect
3601          * specific data being in the connection till then (especially in
3602          * validate_activation_request()).
3603          */
3604         connection = nm_simple_connection_new ();
3605         if (settings && g_variant_n_children (settings))
3606                 _nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL);
3607
3608         subject = validate_activation_request (self,
3609                                                context,
3610                                                connection,
3611                                                device_path,
3612                                                &device,
3613                                                &vpn,
3614                                                &error);
3615         if (!subject)
3616                 goto error;
3617
3618         all_connections = nm_settings_get_connections (priv->settings);
3619         if (vpn) {
3620                 /* Try to fill the VPN's connection setting and name at least */
3621                 if (!nm_connection_get_setting_vpn (connection)) {
3622                         error = g_error_new_literal (NM_CONNECTION_ERROR,
3623                                                      NM_CONNECTION_ERROR_MISSING_SETTING,
3624                                                      "VPN connections require a 'vpn' setting");
3625                         g_prefix_error (&error, "%s: ", NM_SETTING_VPN_SETTING_NAME);
3626                         goto error;
3627                 }
3628
3629                 nm_utils_complete_generic (NM_PLATFORM_GET,
3630                                            connection,
3631                                            NM_SETTING_VPN_SETTING_NAME,
3632                                            all_connections,
3633                                            NULL,
3634                                            _("VPN connection"),
3635                                            NULL,
3636                                            FALSE); /* No IPv6 by default for now */
3637         } else {
3638                 /* Let each device subclass complete the connection */
3639                 if (!nm_device_complete_connection (device,
3640                                                     connection,
3641                                                     specific_object_path,
3642                                                     all_connections,
3643                                                     &error))
3644                         goto error;
3645         }
3646         g_slist_free (all_connections);
3647         all_connections = NULL;
3648
3649         active = _new_active_connection (self,
3650                                          connection,
3651                                          specific_object_path,
3652                                          device,
3653                                          subject,
3654                                          &error);
3655         if (!active)
3656                 goto error;
3657
3658         g_object_set_data_full (G_OBJECT (active),
3659                                 TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE,
3660                                 connection,
3661                                 g_object_unref);
3662
3663         nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context);
3664         g_object_unref (subject);
3665         return;
3666
3667 error:
3668         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, subject, error->message);
3669         g_clear_object (&connection);
3670         g_slist_free (all_connections);
3671         g_clear_object (&subject);
3672         g_clear_object (&active);
3673
3674         g_assert (error);
3675         g_dbus_method_invocation_take_error (context, error);
3676 }
3677
3678 /***********************************************************************/
3679
3680 gboolean
3681 nm_manager_deactivate_connection (NMManager *manager,
3682                                   const char *connection_path,
3683                                   NMDeviceStateReason reason,
3684                                   GError **error)
3685 {
3686         NMActiveConnection *active;
3687         gboolean success = FALSE;
3688
3689         active = active_connection_get_by_path (manager, connection_path);
3690         if (!active) {
3691                 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3692                                      "The connection was not active.");
3693                 return FALSE;
3694         }
3695
3696         if (NM_IS_VPN_CONNECTION (active)) {
3697                 NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
3698
3699                 if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
3700                         vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
3701                 if (nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE))
3702                         success = TRUE;
3703                 else
3704                         g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3705                                              "The VPN connection was not active.");
3706         } else {
3707                 g_assert (NM_IS_ACT_REQUEST (active));
3708                 nm_device_state_changed (nm_active_connection_get_device (active),
3709                                          NM_DEVICE_STATE_DEACTIVATING,
3710                                          reason);
3711                 success = TRUE;
3712         }
3713
3714         if (success)
3715                 g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
3716
3717         return success;
3718 }
3719
3720 static void
3721 deactivate_net_auth_done_cb (NMAuthChain *chain,
3722                              GError *auth_error,
3723                              GDBusMethodInvocation *context,
3724                              gpointer user_data)
3725 {
3726         NMManager *self = NM_MANAGER (user_data);
3727         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3728         GError *error = NULL;
3729         NMAuthCallResult result;
3730         NMActiveConnection *active;
3731         char *path;
3732
3733         g_assert (context);
3734
3735         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3736
3737         path = nm_auth_chain_get_data (chain, "path");
3738         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3739
3740         if (auth_error) {
3741                 _LOGD (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
3742                 error = g_error_new (NM_MANAGER_ERROR,
3743                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
3744                                      "Deactivate request failed: %s",
3745                                      auth_error->message);
3746         } else if (result != NM_AUTH_CALL_RESULT_YES) {
3747                 error = g_error_new_literal (NM_MANAGER_ERROR,
3748                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3749                                              "Not authorized to deactivate connections");
3750         } else {
3751                 /* success; deactivation allowed */
3752                 if (!nm_manager_deactivate_connection (self,
3753                                                        path,
3754                                                        NM_DEVICE_STATE_REASON_USER_REQUESTED,
3755                                                        &error))
3756                         nm_assert (error);
3757         }
3758
3759         active = active_connection_get_by_path (self, path);
3760         if (active) {
3761                 nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
3762                                             nm_active_connection_get_settings_connection (active),
3763                                             !error,
3764                                             nm_auth_chain_get_subject (chain),
3765                                             error ? error->message : NULL);
3766         }
3767
3768         if (error)
3769                 g_dbus_method_invocation_take_error (context, error);
3770         else
3771                 g_dbus_method_invocation_return_value (context, NULL);
3772
3773         nm_auth_chain_unref (chain);
3774 }
3775
3776 static void
3777 impl_manager_deactivate_connection (NMManager *self,
3778                                     GDBusMethodInvocation *context,
3779                                     const char *active_path)
3780 {
3781         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3782         NMActiveConnection *ac;
3783         NMSettingsConnection *connection = NULL;
3784         GError *error = NULL;
3785         NMAuthSubject *subject = NULL;
3786         NMAuthChain *chain;
3787         char *error_desc = NULL;
3788
3789         /* Find the connection by its object path */
3790         ac = active_connection_get_by_path (self, active_path);
3791         if (ac)
3792                 connection = nm_active_connection_get_settings_connection (ac);
3793
3794         if (!connection) {
3795                 error = g_error_new_literal (NM_MANAGER_ERROR,
3796                                              NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3797                                              "The connection was not active.");
3798                 goto done;
3799         }
3800
3801         /* Validate the caller */
3802         subject = nm_auth_subject_new_unix_process_from_context (context);
3803         if (!subject) {
3804                 error = g_error_new_literal (NM_MANAGER_ERROR,
3805                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3806                                              "Failed to get request UID.");
3807                 goto done;
3808         }
3809
3810         /* Ensure the subject has permissions for this connection */
3811         if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
3812                                         subject,
3813                                         &error_desc)) {
3814                 error = g_error_new_literal (NM_MANAGER_ERROR,
3815                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3816                                              error_desc);
3817                 g_free (error_desc);
3818                 goto done;
3819         }
3820
3821         /* Validate the user request */
3822         chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self);
3823         if (!chain) {
3824                 error = g_error_new_literal (NM_MANAGER_ERROR,
3825                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
3826                                              "Unable to authenticate request.");
3827                 goto done;
3828         }
3829
3830         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3831         nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
3832         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
3833
3834 done:
3835         if (error) {
3836                 if (connection) {
3837                         nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE,
3838                                                     subject, error->message);
3839                 }
3840                 g_dbus_method_invocation_take_error (context, error);
3841         }
3842         g_clear_object (&subject);
3843 }
3844
3845 static gboolean
3846 device_is_wake_on_lan (NMDevice *device)
3847 {
3848         return nm_platform_link_get_wake_on_lan (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device));
3849 }
3850
3851 static void
3852 do_sleep_wake (NMManager *self, gboolean sleeping_changed)
3853 {
3854         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3855         gboolean suspending, waking_from_suspend;
3856         GSList *iter;
3857
3858         suspending = sleeping_changed && priv->sleeping;
3859         waking_from_suspend = sleeping_changed && !priv->sleeping;
3860
3861         if (manager_sleeping (self)) {
3862                 _LOGI (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling");
3863
3864                 /* FIXME: are there still hardware devices that need to be disabled around
3865                  * suspend/resume?
3866                  */
3867                 for (iter = priv->devices; iter; iter = iter->next) {
3868                         NMDevice *device = iter->data;
3869
3870                         /* FIXME: shouldn't we be unmanaging software devices if !suspending? */
3871                         if (nm_device_is_software (device))
3872                                 continue;
3873                         /* Wake-on-LAN devices will be taken down post-suspend rather than pre- */
3874                         if (suspending && device_is_wake_on_lan (device))
3875                                 continue;
3876
3877                         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3878                 }
3879         } else {
3880                 _LOGI (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling");
3881
3882                 if (waking_from_suspend) {
3883                         /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this
3884                          * but for now it's the only way to make sure we re-check their connectivity.
3885                          */
3886                         for (iter = priv->devices; iter; iter = iter->next) {
3887                                 NMDevice *device = iter->data;
3888
3889                                 if (nm_device_is_software (device))
3890                                         continue;
3891                                 if (device_is_wake_on_lan (device))
3892                                         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
3893                         }
3894                 }
3895
3896                 /* Ensure rfkill state is up-to-date since we don't respond to state
3897                  * changes during sleep.
3898                  */
3899                 nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
3900
3901                 /* Re-manage managed devices */
3902                 for (iter = priv->devices; iter; iter = iter->next) {
3903                         NMDevice *device = NM_DEVICE (iter->data);
3904                         guint i;
3905
3906                         if (nm_device_is_software (device))
3907                                 continue;
3908
3909                         /* enable/disable wireless devices since that we don't respond
3910                          * to killswitch changes during sleep.
3911                          */
3912                         for (i = 0; i < RFKILL_TYPE_MAX; i++) {
3913                                 RadioState *rstate = &priv->radio_states[i];
3914                                 gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
3915
3916                                 if (rstate->desc) {
3917                                         _LOGD (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)",
3918                                                enabled ? "enabling" : "disabling",
3919                                                rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled);
3920                                 }
3921
3922                                 if (nm_device_get_rfkill_type (device) == rstate->rtype)
3923                                         nm_device_set_enabled (device, enabled);
3924                         }
3925
3926                         nm_device_set_autoconnect (device, TRUE);
3927
3928                         nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
3929                 }
3930         }
3931
3932         nm_manager_update_state (self);
3933 }
3934
3935 static void
3936 _internal_sleep (NMManager *self, gboolean do_sleep)
3937 {
3938         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3939
3940         if (priv->sleeping == do_sleep)
3941                 return;
3942
3943         _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s  enabled: %s)",
3944                do_sleep ? "sleep" : "wake",
3945                priv->sleeping ? "yes" : "no",
3946                priv->net_enabled ? "yes" : "no");
3947
3948         priv->sleeping = do_sleep;
3949
3950         do_sleep_wake (self, TRUE);
3951
3952         g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
3953 }
3954
3955 #if 0
3956 static void
3957 sleep_auth_done_cb (NMAuthChain *chain,
3958                     GError *error,
3959                     GDBusMethodInvocation *context,
3960                     gpointer user_data)
3961 {
3962         NMManager *self = NM_MANAGER (user_data);
3963         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3964         GError *ret_error;
3965         NMAuthCallResult result;
3966         gboolean do_sleep;
3967
3968         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3969
3970         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
3971         if (error) {
3972                 _LOGD (LOGD_SUSPEND, "Sleep/wake request failed: %s", error->message);
3973                 ret_error = g_error_new (NM_MANAGER_ERROR,
3974                                          NM_MANAGER_ERROR_PERMISSION_DENIED,
3975                                          "Sleep/wake request failed: %s",
3976                                          error->message);
3977                 g_dbus_method_invocation_take_error (context, ret_error);
3978         } else if (result != NM_AUTH_CALL_RESULT_YES) {
3979                 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
3980                                                  NM_MANAGER_ERROR_PERMISSION_DENIED,
3981                                                  "Not authorized to sleep/wake");
3982                 g_dbus_method_invocation_take_error (context, ret_error);
3983         } else {
3984                 /* Auth success */
3985                 do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
3986                 _internal_sleep (self, do_sleep);
3987                 g_dbus_method_invocation_return_value (context, NULL);
3988         }
3989
3990         nm_auth_chain_unref (chain);
3991 }
3992 #endif
3993
3994 static void
3995 impl_manager_sleep (NMManager *self,
3996                     GDBusMethodInvocation *context,
3997                     gboolean do_sleep)
3998 {
3999         NMManagerPrivate *priv;
4000         GError *error = NULL;
4001         gs_unref_object NMAuthSubject *subject = NULL;
4002 #if 0
4003         NMAuthChain *chain;
4004         const char *error_desc = NULL;
4005 #endif
4006
4007         g_return_if_fail (NM_IS_MANAGER (self));
4008
4009         priv = NM_MANAGER_GET_PRIVATE (self);
4010         subject = nm_auth_subject_new_unix_process_from_context (context);
4011
4012         if (priv->sleeping == do_sleep) {
4013                 error = g_error_new (NM_MANAGER_ERROR,
4014                                      NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
4015                                      "Already %s", do_sleep ? "asleep" : "awake");
4016                 nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", FALSE, subject,
4017                                          error->message);
4018                 g_dbus_method_invocation_take_error (context, error);
4019                 return;
4020         }
4021
4022         /* Unconditionally allow the request.  Previously it was polkit protected
4023          * but unfortunately that doesn't work for short-lived processes like
4024          * pm-utils.  It uses dbus-send without --print-reply, which quits
4025          * immediately after sending the request, and NM is unable to obtain the
4026          * sender's UID as dbus-send has already dropped off the bus.  Thus NM
4027          * fails the request.  Instead, don't validate the request, but rely on
4028          * D-Bus permissions to restrict the call to root.
4029          */
4030         _internal_sleep (self, do_sleep);
4031         nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", TRUE, subject, NULL);
4032         g_dbus_method_invocation_return_value (context, NULL);
4033         return;
4034
4035 #if 0
4036         chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
4037         if (chain) {
4038                 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4039                 nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
4040                 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
4041         } else {
4042                 error = g_error_new_literal (NM_MANAGER_ERROR,
4043                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4044                                              error_desc);
4045                 g_dbus_method_invocation_take_error (context, error);
4046         }
4047 #endif
4048 }
4049
4050 static void
4051 sleeping_cb (NMSleepMonitor *monitor, gpointer user_data)
4052 {
4053         nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
4054         _internal_sleep (NM_MANAGER (user_data), TRUE);
4055 }
4056
4057 static void
4058 resuming_cb (NMSleepMonitor *monitor, gpointer user_data)
4059 {
4060         nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
4061         _internal_sleep (NM_MANAGER (user_data), FALSE);
4062 }
4063
4064 static void
4065 _internal_enable (NMManager *self, gboolean enable)
4066 {
4067         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4068         GError *err = NULL;
4069
4070         /* Update "NetworkingEnabled" key in state file */
4071         if (priv->state_file) {
4072                 if (!write_value_to_state_file (priv->state_file,
4073                                                 "main", "NetworkingEnabled",
4074                                                 G_TYPE_BOOLEAN, (gpointer) &enable,
4075                                                 &err)) {
4076                         /* Not a hard error */
4077                         _LOGW (LOGD_SUSPEND, "writing to state file %s failed: %s",
4078                                priv->state_file,
4079                                err->message);
4080                 }
4081         }
4082
4083         _LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s  enabled: %s)",
4084                enable ? "enable" : "disable",
4085                priv->sleeping ? "yes" : "no",
4086                priv->net_enabled ? "yes" : "no");
4087
4088         priv->net_enabled = enable;
4089
4090         do_sleep_wake (self, FALSE);
4091
4092         g_object_notify (G_OBJECT (self), NM_MANAGER_NETWORKING_ENABLED);
4093 }
4094
4095 static void
4096 enable_net_done_cb (NMAuthChain *chain,
4097                     GError *error,
4098                     GDBusMethodInvocation *context,
4099                     gpointer user_data)
4100 {
4101         NMManager *self = NM_MANAGER (user_data);
4102         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4103         GError *ret_error = NULL;
4104         NMAuthCallResult result;
4105         gboolean enable;
4106         NMAuthSubject *subject;
4107
4108         g_assert (context);
4109
4110         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4111         enable = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enable"));
4112         subject = nm_auth_chain_get_subject (chain);
4113
4114         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4115         if (error) {
4116                 _LOGD (LOGD_CORE, "Enable request failed: %s", error->message);
4117                 ret_error = g_error_new (NM_MANAGER_ERROR,
4118                                          NM_MANAGER_ERROR_PERMISSION_DENIED,
4119                                          "Enable request failed: %s",
4120                                          error->message);
4121         } else if (result != NM_AUTH_CALL_RESULT_YES) {
4122                 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
4123                                                  NM_MANAGER_ERROR_PERMISSION_DENIED,
4124                                                  "Not authorized to enable/disable networking");
4125         } else {
4126                 /* Auth success */
4127                 _internal_enable (self, enable);
4128                 g_dbus_method_invocation_return_value (context, NULL);
4129                 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", TRUE,
4130                                          subject, NULL);
4131         }
4132
4133         if (ret_error) {
4134                 nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", FALSE,
4135                                          subject, ret_error->message);
4136                 g_dbus_method_invocation_take_error (context, ret_error);
4137         }
4138
4139         nm_auth_chain_unref (chain);
4140 }
4141
4142 static void
4143 impl_manager_enable (NMManager *self,
4144                      GDBusMethodInvocation *context,
4145                      gboolean enable)
4146 {
4147         NMManagerPrivate *priv;
4148         NMAuthChain *chain;
4149         GError *error = NULL;
4150
4151         g_return_if_fail (NM_IS_MANAGER (self));
4152
4153         priv = NM_MANAGER_GET_PRIVATE (self);
4154
4155         if (priv->net_enabled == enable) {
4156                 error = g_error_new (NM_MANAGER_ERROR,
4157                                      NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
4158                                      "Already %s", enable ? "enabled" : "disabled");
4159                 goto done;
4160         }
4161
4162         chain = nm_auth_chain_new_context (context, enable_net_done_cb, self);
4163         if (!chain) {
4164                 error = g_error_new_literal (NM_MANAGER_ERROR,
4165                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4166                                              "Unable to authenticate request.");
4167                 goto done;
4168         }
4169
4170         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4171         nm_auth_chain_set_data (chain, "enable", GUINT_TO_POINTER (enable), NULL);
4172         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, TRUE);
4173
4174 done:
4175         if (error)
4176                 g_dbus_method_invocation_take_error (context, error);
4177 }
4178
4179 /* Permissions */
4180
4181 static void
4182 get_perm_add_result (NMAuthChain *chain, GVariantBuilder *results, const char *permission)
4183 {
4184         NMAuthCallResult result;
4185
4186         result = nm_auth_chain_get_result (chain, permission);
4187         if (result == NM_AUTH_CALL_RESULT_YES)
4188                 g_variant_builder_add (results, "{ss}", permission, "yes");
4189         else if (result == NM_AUTH_CALL_RESULT_NO)
4190                 g_variant_builder_add (results, "{ss}", permission, "no");
4191         else if (result == NM_AUTH_CALL_RESULT_AUTH)
4192                 g_variant_builder_add (results, "{ss}", permission, "auth");
4193         else {
4194                 nm_log_dbg (LOGD_CORE, "unknown auth chain result %d", result);
4195         }
4196 }
4197
4198 static void
4199 get_permissions_done_cb (NMAuthChain *chain,
4200                          GError *error,
4201                          GDBusMethodInvocation *context,
4202                          gpointer user_data)
4203 {
4204         NMManager *self = NM_MANAGER (user_data);
4205         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4206         GError *ret_error;
4207         GVariantBuilder results;
4208
4209         g_assert (context);
4210
4211         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4212         if (error) {
4213                 _LOGD (LOGD_CORE, "Permissions request failed: %s", error->message);
4214                 ret_error = g_error_new (NM_MANAGER_ERROR,
4215                                          NM_MANAGER_ERROR_PERMISSION_DENIED,
4216                                          "Permissions request failed: %s",
4217                                          error->message);
4218                 g_dbus_method_invocation_take_error (context, ret_error);
4219         } else {
4220                 g_variant_builder_init (&results, G_VARIANT_TYPE ("a{ss}"));
4221
4222                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
4223                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SLEEP_WAKE);
4224                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
4225                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
4226                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
4227                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4228                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
4229                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
4230                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
4231                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
4232                 get_perm_add_result (chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
4233
4234                 g_dbus_method_invocation_return_value (context,
4235                                                        g_variant_new ("(a{ss})", &results));
4236         }
4237
4238         nm_auth_chain_unref (chain);
4239 }
4240
4241 static void
4242 impl_manager_get_permissions (NMManager *self,
4243                               GDBusMethodInvocation *context)
4244 {
4245         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4246         NMAuthChain *chain;
4247         GError *error = NULL;
4248
4249         chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self);
4250         if (!chain) {
4251                 error = g_error_new_literal (NM_MANAGER_ERROR,
4252                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4253                                              "Unable to authenticate request.");
4254                 g_dbus_method_invocation_take_error (context, error);
4255                 return;
4256         }
4257
4258         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4259         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
4260         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
4261         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
4262         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
4263         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
4264         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
4265         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
4266         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
4267         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
4268         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
4269         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
4270 }
4271
4272 static void
4273 impl_manager_get_state (NMManager *self,
4274                         GDBusMethodInvocation *context)
4275 {
4276         nm_manager_update_state (self);
4277         g_dbus_method_invocation_return_value (context,
4278                                                g_variant_new ("(u)", NM_MANAGER_GET_PRIVATE (self)->state));
4279 }
4280
4281 static void
4282 impl_manager_set_logging (NMManager *self,
4283                           GDBusMethodInvocation *context,
4284                           const char *level,
4285                           const char *domains)
4286 {
4287         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4288         GError *error = NULL;
4289         gulong caller_uid = G_MAXULONG;
4290
4291         if (!nm_bus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) {
4292                 error = g_error_new_literal (NM_MANAGER_ERROR,
4293                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4294                                              "Failed to get request UID.");
4295                 goto done;
4296         }
4297
4298         if (0 != caller_uid) {
4299                 error = g_error_new_literal (NM_MANAGER_ERROR,
4300                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4301                                              "Permission denied");
4302                 goto done;
4303         }
4304
4305         if (nm_logging_setup (level, domains, NULL, &error)) {
4306                 _LOGI (LOGD_CORE, "logging: level '%s' domains '%s'",
4307                        nm_logging_level_to_string (), nm_logging_domains_to_string ());
4308         }
4309
4310 done:
4311         if (error)
4312                 g_dbus_method_invocation_take_error (context, error);
4313         else
4314                 g_dbus_method_invocation_return_value (context, NULL);
4315 }
4316
4317 static void
4318 impl_manager_get_logging (NMManager *manager,
4319                           GDBusMethodInvocation *context)
4320 {
4321         g_dbus_method_invocation_return_value (context,
4322                                                g_variant_new ("(ss)",
4323                                                               nm_logging_level_to_string (),
4324                                                               nm_logging_domains_to_string ()));
4325 }
4326
4327 static void
4328 connectivity_check_done (GObject *object,
4329                          GAsyncResult *result,
4330                          gpointer user_data)
4331 {
4332         GDBusMethodInvocation *context = user_data;
4333         NMConnectivityState state;
4334         GError *error = NULL;
4335
4336         state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
4337         if (error)
4338                 g_dbus_method_invocation_take_error (context, error);
4339         else {
4340                 g_dbus_method_invocation_return_value (context,
4341                                                        g_variant_new ("(u)", state));
4342         }
4343 }
4344
4345
4346 static void
4347 check_connectivity_auth_done_cb (NMAuthChain *chain,
4348                                  GError *auth_error,
4349                                  GDBusMethodInvocation *context,
4350                                  gpointer user_data)
4351 {
4352         NMManager *self = NM_MANAGER (user_data);
4353         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4354         GError *error = NULL;
4355         NMAuthCallResult result;
4356
4357         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4358
4359         result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4360
4361         if (auth_error) {
4362                 _LOGD (LOGD_CORE, "CheckConnectivity request failed: %s", auth_error->message);
4363                 error = g_error_new (NM_MANAGER_ERROR,
4364                                      NM_MANAGER_ERROR_PERMISSION_DENIED,
4365                                      "Connectivity check request failed: %s",
4366                                      auth_error->message);
4367         } else if (result != NM_AUTH_CALL_RESULT_YES) {
4368                 error = g_error_new_literal (NM_MANAGER_ERROR,
4369                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4370                                              "Not authorized to recheck connectivity");
4371         } else {
4372                 /* it's allowed */
4373                 nm_connectivity_check_async (priv->connectivity,
4374                                              connectivity_check_done,
4375                                              context);
4376         }
4377
4378         if (error)
4379                 g_dbus_method_invocation_take_error (context, error);
4380         nm_auth_chain_unref (chain);
4381 }
4382
4383 static void
4384 impl_manager_check_connectivity (NMManager *self,
4385                                  GDBusMethodInvocation *context)
4386 {
4387         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4388         NMAuthChain *chain;
4389         GError *error = NULL;
4390
4391         /* Validate the request */
4392         chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self);
4393         if (!chain) {
4394                 error = g_error_new_literal (NM_MANAGER_ERROR,
4395                                              NM_MANAGER_ERROR_PERMISSION_DENIED,
4396                                              "Unable to authenticate request.");
4397                 g_dbus_method_invocation_take_error (context, error);
4398                 return;
4399         }
4400
4401         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4402         nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
4403 }
4404
4405 static void
4406 start_factory (NMDeviceFactory *factory, gpointer user_data)
4407 {
4408         nm_device_factory_start (factory);
4409 }
4410
4411 gboolean
4412 nm_manager_start (NMManager *self, GError **error)
4413 {
4414         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4415         GSList *iter, *connections;
4416         guint i;
4417
4418         if (!nm_settings_start (priv->settings, error))
4419                 return FALSE;
4420
4421         g_signal_connect (NM_PLATFORM_GET,
4422                           NM_PLATFORM_SIGNAL_LINK_CHANGED,
4423                           G_CALLBACK (platform_link_cb),
4424                           self);
4425
4426         /* Set initial radio enabled/disabled state */
4427         for (i = 0; i < RFKILL_TYPE_MAX; i++) {
4428                 RadioState *rstate = &priv->radio_states[i];
4429                 gboolean enabled;
4430
4431                 if (!rstate->desc)
4432                         continue;
4433
4434                 /* recheck kernel rfkill state */
4435                 update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
4436
4437                 if (rstate->desc) {
4438                         _LOGI (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
4439                                rstate->desc,
4440                                (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
4441                                rstate->user_enabled ? "enabled" : "disabled");
4442                 }
4443                 enabled = radio_enabled_for_rstate (rstate, TRUE);
4444                 manager_update_radio_enabled (self, rstate, enabled);
4445         }
4446
4447         /* Log overall networking status - enabled/disabled */
4448         _LOGI (LOGD_CORE, "Networking is %s by state file",
4449                priv->net_enabled ? "enabled" : "disabled");
4450
4451         system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
4452         system_hostname_changed_cb (priv->settings, NULL, self);
4453
4454         /* Start device factories */
4455         nm_device_factory_manager_load_factories (_register_device_factory, self);
4456         nm_device_factory_manager_for_each_factory (start_factory, NULL);
4457
4458         platform_query_devices (self);
4459
4460         /* Load VPN plugins */
4461         priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
4462
4463         /* Connections added before the manager is started do not emit
4464          * connection-added signals thus devices have to be created manually.
4465          */
4466         _LOGD (LOGD_CORE, "creating virtual devices...");
4467         connections = nm_settings_get_connections (priv->settings);
4468         for (iter = connections; iter; iter = iter->next)
4469                 connection_changed (priv->settings, NM_CONNECTION (iter->data), self);
4470         g_slist_free (connections);
4471
4472         priv->devices_inited = TRUE;
4473
4474         check_if_startup_complete (self);
4475
4476         return TRUE;
4477 }
4478
4479 void
4480 nm_manager_stop (NMManager *self)
4481 {
4482         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4483
4484         /* Remove all devices */
4485         while (priv->devices)
4486                 remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
4487
4488         _active_connection_cleanup (self);
4489 }
4490
4491 static gboolean
4492 handle_firmware_changed (gpointer user_data)
4493 {
4494         NMManager *self = NM_MANAGER (user_data);
4495         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4496         GSList *iter;
4497
4498         priv->fw_changed_id = 0;
4499
4500         /* Try to re-enable devices with missing firmware */
4501         for (iter = priv->devices; iter; iter = iter->next) {
4502                 NMDevice *candidate = NM_DEVICE (iter->data);
4503                 NMDeviceState state = nm_device_get_state (candidate);
4504
4505                 if (   nm_device_get_firmware_missing (candidate)
4506                     && (state == NM_DEVICE_STATE_UNAVAILABLE)) {
4507                         _LOGI (LOGD_CORE, "(%s): firmware may now be available",
4508                                nm_device_get_iface (candidate));
4509
4510                         /* Re-set unavailable state to try bringing the device up again */
4511                         nm_device_state_changed (candidate,
4512                                                  NM_DEVICE_STATE_UNAVAILABLE,
4513                                                  NM_DEVICE_STATE_REASON_NONE);
4514                 }
4515         }
4516
4517         return FALSE;
4518 }
4519
4520 static void
4521 connectivity_changed (NMConnectivity *connectivity,
4522                       GParamSpec *pspec,
4523                       gpointer user_data)
4524 {
4525         NMManager *self = NM_MANAGER (user_data);
4526
4527         _LOGD (LOGD_CORE, "connectivity checking indicates %s",
4528                nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
4529
4530         nm_manager_update_state (self);
4531         g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY);
4532 }
4533
4534 static void
4535 firmware_dir_changed (GFileMonitor *monitor,
4536                       GFile *file,
4537                       GFile *other_file,
4538                       GFileMonitorEvent event_type,
4539                       gpointer user_data)
4540 {
4541         NMManager *self = NM_MANAGER (user_data);
4542         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4543
4544         switch (event_type) {
4545         case G_FILE_MONITOR_EVENT_CREATED:
4546         case G_FILE_MONITOR_EVENT_CHANGED:
4547         case G_FILE_MONITOR_EVENT_MOVED:
4548         case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
4549         case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
4550                 if (!priv->fw_changed_id) {
4551                         priv->fw_changed_id = g_timeout_add_seconds (4, handle_firmware_changed, self);
4552                         _LOGI (LOGD_CORE, "kernel firmware directory '%s' changed",
4553                                KERNEL_FIRMWARE_DIR);
4554                 }
4555                 break;
4556         default:
4557                 break;
4558         }
4559 }
4560
4561 static void
4562 connection_metered_changed (GObject *object,
4563                             NMMetered metered,
4564                             gpointer user_data)
4565 {
4566         nm_manager_update_metered (NM_MANAGER (user_data));
4567 }
4568
4569 static void
4570 policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4571 {
4572         NMManager *self = NM_MANAGER (user_data);
4573         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4574         NMDevice *best;
4575         NMActiveConnection *ac;
4576
4577         /* Note: this assumes that it's not possible for the IP4 default
4578          * route to be going over the default-ip6-device. If that changes,
4579          * we need something more complicated here.
4580          */
4581         best = nm_policy_get_default_ip4_device (priv->policy);
4582         if (!best)
4583                 best = nm_policy_get_default_ip6_device (priv->policy);
4584
4585         if (best)
4586                 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
4587         else
4588                 ac = NULL;
4589
4590         if (ac != priv->primary_connection) {
4591                 if (priv->primary_connection) {
4592                         g_signal_handlers_disconnect_by_func (priv->primary_connection,
4593                                                               G_CALLBACK (connection_metered_changed),
4594                                                               self);
4595                         g_clear_object (&priv->primary_connection);
4596                 }
4597
4598                 priv->primary_connection = ac ? g_object_ref (ac) : NULL;
4599
4600                 if (priv->primary_connection) {
4601                         g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
4602                                           G_CALLBACK (connection_metered_changed), self);
4603                 }
4604                 _LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4605                 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
4606                 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE);
4607                 nm_manager_update_metered (self);
4608         }
4609 }
4610
4611 static void
4612 policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4613 {
4614         NMManager *self = NM_MANAGER (user_data);
4615         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4616         NMDevice *activating, *best;
4617         NMActiveConnection *ac;
4618
4619         /* We only look at activating-ip6-device if activating-ip4-device
4620          * AND default-ip4-device are NULL; if default-ip4-device is
4621          * non-NULL, then activating-ip6-device is irrelevant, since while
4622          * that device might become the new default-ip6-device, it can't
4623          * become primary-connection while default-ip4-device is set to
4624          * something else.
4625          */
4626         activating = nm_policy_get_activating_ip4_device (priv->policy);
4627         best = nm_policy_get_default_ip4_device (priv->policy);
4628         if (!activating && !best)
4629                 activating = nm_policy_get_activating_ip6_device (priv->policy);
4630
4631         if (activating)
4632                 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
4633         else
4634                 ac = NULL;
4635
4636         if (ac != priv->activating_connection) {
4637                 g_clear_object (&priv->activating_connection);
4638                 priv->activating_connection = ac ? g_object_ref (ac) : NULL;
4639                 _LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
4640                 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVATING_CONNECTION);
4641         }
4642 }
4643
4644 #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
4645
4646 typedef struct {
4647         NMManager *self;
4648         GDBusConnection *connection;
4649         GDBusMessage *message;
4650         NMAuthSubject *subject;
4651         const char *permission;
4652         const char *audit_op;
4653         char *audit_prop_value;
4654         GType interface_type;
4655         const char *glib_propname;
4656 } PropertyFilterData;
4657
4658 static void
4659 free_property_filter_data (PropertyFilterData *pfd)
4660 {
4661         g_object_unref (pfd->self);
4662         g_object_unref (pfd->connection);
4663         g_object_unref (pfd->message);
4664         g_clear_object (&pfd->subject);
4665         g_free (pfd->audit_prop_value);
4666         g_slice_free (PropertyFilterData, pfd);
4667 }
4668
4669 static void
4670 prop_set_auth_done_cb (NMAuthChain *chain,
4671                        GError *error,
4672                        GDBusMethodInvocation *context, /* NULL */
4673                        gpointer user_data)
4674 {
4675         PropertyFilterData *pfd = user_data;
4676         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4677         NMAuthCallResult result;
4678         GDBusMessage *reply = NULL;
4679         const char *error_message;
4680         gs_unref_object NMExportedObject *object = NULL;
4681         const NMGlobalDnsConfig *global_dns;
4682         gs_unref_variant GVariant *value = NULL;
4683         GVariant *args;
4684
4685         priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4686         result = nm_auth_chain_get_result (chain, pfd->permission);
4687         if (error || (result != NM_AUTH_CALL_RESULT_YES)) {
4688                 reply = g_dbus_message_new_method_error (pfd->message,
4689                                                          NM_PERM_DENIED_ERROR,
4690                                                          (error_message = "Not authorized to perform this operation"));
4691                 if (error)
4692                         error_message = error->message;
4693                 goto done;
4694         }
4695
4696         object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr,
4697                                                                            g_dbus_message_get_path (pfd->message)));
4698         if (!object) {
4699                 reply = g_dbus_message_new_method_error (pfd->message,
4700                                                          "org.freedesktop.DBus.Error.UnknownObject",
4701                                                          (error_message = "Object doesn't exist."));
4702                 goto done;
4703         }
4704
4705         /* do some extra type checking... */
4706         if (!nm_exported_object_get_interface_by_type (object, pfd->interface_type)) {
4707                 reply = g_dbus_message_new_method_error (pfd->message,
4708                                                          "org.freedesktop.DBus.Error.InvalidArgs",
4709                                                          (error_message = "Object is of unexpected type."));
4710                 goto done;
4711         }
4712
4713         args = g_dbus_message_get_body (pfd->message);
4714         g_variant_get (args, "(&s&sv)", NULL, NULL, &value);
4715         g_assert (pfd->glib_propname);
4716
4717         if (!strcmp (pfd->glib_propname, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) {
4718                 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{sv}")));
4719                 global_dns = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config));
4720
4721                 if (global_dns && !nm_global_dns_config_is_internal (global_dns)) {
4722                         reply = g_dbus_message_new_method_error (pfd->message,
4723                                                                  NM_PERM_DENIED_ERROR,
4724                                                                  (error_message = "Global DNS configuration already set via configuration file"));
4725                         goto done;
4726                 }
4727                 /* ... but set the property on the @object itself. It would be correct to set the property
4728                  * on the skeleton interface, but as it is now, the result is the same. */
4729                 g_object_set (object, pfd->glib_propname, value, NULL);
4730         } else {
4731                 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
4732                 /* the same here */
4733                 g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL);
4734         }
4735
4736         reply = g_dbus_message_new_method_reply (pfd->message);
4737         g_dbus_message_set_body (reply, g_variant_new_tuple (NULL, 0));
4738         error_message = NULL;
4739 done:
4740         nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message);
4741
4742         g_dbus_connection_send_message (pfd->connection, reply,
4743                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4744                                         NULL, NULL);
4745         g_object_unref (reply);
4746         nm_auth_chain_unref (chain);
4747
4748         free_property_filter_data (pfd);
4749 }
4750
4751 static gboolean
4752 do_set_property_check (gpointer user_data)
4753 {
4754         PropertyFilterData *pfd = user_data;
4755         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
4756         GDBusMessage *reply = NULL;
4757         NMAuthChain *chain;
4758         const char *error_message = NULL;
4759
4760         pfd->subject = nm_auth_subject_new_unix_process_from_message (pfd->connection, pfd->message);
4761         if (!pfd->subject) {
4762                 reply = g_dbus_message_new_method_error (pfd->message,
4763                                                          NM_PERM_DENIED_ERROR,
4764                                                          (error_message = "Could not determine request UID."));
4765                 goto out;
4766         }
4767
4768         /* Validate the user request */
4769         chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd);
4770         if (!chain) {
4771                 reply = g_dbus_message_new_method_error (pfd->message,
4772                                                          NM_PERM_DENIED_ERROR,
4773                                                          (error_message = "Could not authenticate request."));
4774                 goto out;
4775         }
4776
4777         priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4778         nm_auth_chain_add_call (chain, pfd->permission, TRUE);
4779
4780 out:
4781         if (reply) {
4782                 nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, FALSE, pfd->subject, error_message);
4783                 g_dbus_connection_send_message (pfd->connection, reply,
4784                                                 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
4785                                                 NULL, NULL);
4786                 g_object_unref (reply);
4787                 free_property_filter_data (pfd);
4788         }
4789
4790         return FALSE;
4791 }
4792
4793 static GDBusMessage *
4794 prop_filter (GDBusConnection *connection,
4795              GDBusMessage *message,
4796              gboolean incoming,
4797              gpointer user_data)
4798 {
4799         gs_unref_object NMManager *self = NULL;
4800         GVariant *args;
4801         const char *propiface = NULL;
4802         const char *propname = NULL;
4803         const char *glib_propname = NULL, *permission = NULL;
4804         const char *audit_op = NULL;
4805         GType interface_type = G_TYPE_INVALID;
4806         PropertyFilterData *pfd;
4807         const GVariantType *expected_type = G_VARIANT_TYPE_BOOLEAN;
4808         gs_unref_variant GVariant *value = NULL;
4809
4810         self = g_weak_ref_get (user_data);
4811         if (!self)
4812                 return message;
4813
4814         /* The sole purpose of this function is to validate property accesses on the
4815          * NMManager object since gdbus doesn't give us this functionality.
4816          */
4817
4818         /* Only filter org.freedesktop.DBus.Properties.Set calls */
4819         if (   !incoming
4820             || g_dbus_message_get_message_type (message) != G_DBUS_MESSAGE_TYPE_METHOD_CALL
4821             || g_strcmp0 (g_dbus_message_get_interface (message), DBUS_INTERFACE_PROPERTIES) != 0
4822             || g_strcmp0 (g_dbus_message_get_member (message), "Set") != 0)
4823                 return message;
4824
4825         args = g_dbus_message_get_body (message);
4826         if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)")))
4827                 return message;
4828         g_variant_get (args, "(&s&sv)", &propiface, &propname, &value);
4829
4830         /* Only filter calls to filtered properties, on existing objects */
4831         if (!strcmp (propiface, NM_DBUS_INTERFACE)) {
4832                 if (!strcmp (propname, "WirelessEnabled")) {
4833                         glib_propname = NM_MANAGER_WIRELESS_ENABLED;
4834                         permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI;
4835                         audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4836                 } else if (!strcmp (propname, "WwanEnabled")) {
4837                         glib_propname = NM_MANAGER_WWAN_ENABLED;
4838                         permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
4839                         audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4840                 } else if (!strcmp (propname, "WimaxEnabled")) {
4841                         glib_propname = NM_MANAGER_WIMAX_ENABLED;
4842                         permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
4843                         audit_op = NM_AUDIT_OP_RADIO_CONTROL;
4844                 } else if (!strcmp (propname, "GlobalDnsConfiguration")) {
4845                         glib_propname = NM_MANAGER_GLOBAL_DNS_CONFIGURATION;
4846                         permission = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
4847                         audit_op = NM_AUDIT_OP_NET_CONTROL;
4848                         expected_type = G_VARIANT_TYPE ("a{sv}");
4849                 } else
4850                         return message;
4851                 interface_type = NMDBUS_TYPE_MANAGER_SKELETON;
4852         } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)) {
4853                 if (!strcmp (propname, "Autoconnect")) {
4854                         glib_propname = NM_DEVICE_AUTOCONNECT;
4855                         permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4856                         audit_op = NM_AUDIT_OP_DEVICE_AUTOCONNECT;
4857                 } else if (!strcmp (propname, "Managed")) {
4858                         glib_propname = NM_DEVICE_MANAGED;
4859                         permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4860                         audit_op = NM_AUDIT_OP_DEVICE_MANAGED;
4861                 } else
4862                         return message;
4863                 interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
4864         } else
4865                 return message;
4866
4867         if (!g_variant_is_of_type (value, expected_type))
4868                 return message;
4869
4870         /* This filter function is called from a gdbus worker thread which we can't
4871          * make other D-Bus calls from. In particular, we cannot call
4872          * org.freedesktop.DBus.GetConnectionUnixUser to find the remote UID.
4873          */
4874         pfd = g_slice_new0 (PropertyFilterData);
4875         pfd->self = self;
4876         self = NULL;
4877         pfd->connection = g_object_ref (connection);
4878         pfd->message = message;
4879         pfd->permission = permission;
4880         pfd->interface_type = interface_type;
4881         pfd->glib_propname = glib_propname;
4882         pfd->audit_op = audit_op;
4883         if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
4884                 pfd->audit_prop_value = g_strdup_printf ("%s:%d", pfd->glib_propname,
4885                                                          g_variant_get_boolean (value));
4886         } else
4887                 pfd->audit_prop_value = g_strdup (pfd->glib_propname);
4888
4889         g_idle_add (do_set_property_check, pfd);
4890
4891         return NULL;
4892 }
4893
4894 /******************************************************************************/
4895
4896 static int
4897 _set_prop_filter_free2 (gpointer user_data)
4898 {
4899         g_slice_free (GWeakRef, user_data);
4900         return G_SOURCE_REMOVE;
4901 }
4902
4903 static void
4904 _set_prop_filter_free (gpointer user_data)
4905 {
4906         g_weak_ref_clear (user_data);
4907
4908         /* Delay the final deletion of the user_data. There is a race when
4909          * calling g_dbus_connection_remove_filter() that the callback and user_data
4910          * might have been copied and being executed after the destroy function
4911          * runs (bgo #704568).
4912          * This doesn't really fix the race, but it should work well enough. */
4913         g_timeout_add_seconds (2, _set_prop_filter_free2, user_data);
4914 }
4915
4916 static void
4917 _set_prop_filter (NMManager *self, GDBusConnection *connection)
4918 {
4919         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4920
4921         nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id));
4922
4923         if (priv->prop_filter.connection == connection)
4924                 return;
4925
4926         if (priv->prop_filter.connection) {
4927                 g_dbus_connection_remove_filter (priv->prop_filter.connection, priv->prop_filter.id);
4928                 priv->prop_filter.id = 0;
4929                 g_clear_object (&priv->prop_filter.connection);
4930         }
4931         if (connection) {
4932                 GWeakRef *wptr;
4933
4934                 wptr = g_slice_new (GWeakRef);
4935                 g_weak_ref_init  (wptr, self);
4936                 priv->prop_filter.id = g_dbus_connection_add_filter (connection, prop_filter, wptr, _set_prop_filter_free);
4937                 priv->prop_filter.connection = g_object_ref (connection);
4938         }
4939 }
4940
4941 /******************************************************************************/
4942
4943 static void
4944 authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data)
4945 {
4946         /* Let clients know they should re-check their authorization */
4947         g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
4948 }
4949
4950 #define KERN_RFKILL_OP_CHANGE_ALL 3
4951 #define KERN_RFKILL_TYPE_WLAN     1
4952 #define KERN_RFKILL_TYPE_WWAN     5
4953 struct rfkill_event {
4954         __u32 idx;
4955         __u8  type;
4956         __u8  op;
4957         __u8  soft, hard;
4958 } __attribute__((packed));
4959
4960 static void
4961 rfkill_change (const char *desc, RfKillType rtype, gboolean enabled)
4962 {
4963         int fd;
4964         struct rfkill_event event;
4965         ssize_t len;
4966
4967         g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
4968
4969         errno = 0;
4970         fd = open ("/dev/rfkill", O_RDWR);
4971         if (fd < 0) {
4972                 if (errno == EACCES)
4973                         nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device", desc);
4974                 return;
4975         }
4976
4977         if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
4978                 nm_log_warn (LOGD_RFKILL, "(%s): failed to set killswitch device for "
4979                              "non-blocking operation", desc);
4980                 close (fd);
4981                 return;
4982         }
4983
4984         memset (&event, 0, sizeof (event));
4985         event.op = KERN_RFKILL_OP_CHANGE_ALL;
4986         switch (rtype) {
4987         case RFKILL_TYPE_WLAN:
4988                 event.type = KERN_RFKILL_TYPE_WLAN;
4989                 break;
4990         case RFKILL_TYPE_WWAN:
4991                 event.type = KERN_RFKILL_TYPE_WWAN;
4992                 break;
4993         default:
4994                 g_assert_not_reached ();
4995         }
4996         event.soft = enabled ? 0 : 1;
4997
4998         len = write (fd, &event, sizeof (event));
4999         if (len < 0) {
5000                 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
5001                              desc, errno, g_strerror (errno));
5002         } else if (len == sizeof (event)) {
5003                 nm_log_info (LOGD_RFKILL, "%s hardware radio set %s",
5004                              desc, enabled ? "enabled" : "disabled");
5005         } else {
5006                 /* Failed to write full structure */
5007                 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
5008         }
5009
5010         close (fd);
5011 }
5012
5013 static void
5014 manager_radio_user_toggled (NMManager *self,
5015                             RadioState *rstate,
5016                             gboolean enabled)
5017 {
5018         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5019         GError *error = NULL;
5020         gboolean old_enabled, new_enabled;
5021
5022         /* Don't touch devices if asleep/networking disabled */
5023         if (manager_sleeping (self))
5024                 return;
5025
5026         if (rstate->desc) {
5027                 _LOGD (LOGD_RFKILL, "(%s): setting radio %s by user",
5028                        rstate->desc,
5029                        enabled ? "enabled" : "disabled");
5030         }
5031
5032         /* Update enabled key in state file */
5033         if (priv->state_file) {
5034                 if (!write_value_to_state_file (priv->state_file,
5035                                                 "main", rstate->key,
5036                                                 G_TYPE_BOOLEAN, (gpointer) &enabled,
5037                                                 &error)) {
5038                         _LOGW (LOGD_CORE, "writing to state file %s failed: %s",
5039                                priv->state_file,
5040                                error->message);
5041                         g_clear_error (&error);
5042                 }
5043         }
5044
5045         /* When the user toggles the radio, their request should override any
5046          * daemon (like ModemManager) enabled state that can be changed.  For WWAN
5047          * for example, we want the WwanEnabled property to reflect the daemon state
5048          * too so that users can toggle the modem powered, but we don't want that
5049          * daemon state to affect whether or not the user *can* turn it on, which is
5050          * what the kernel rfkill state does.  So we ignore daemon enabled state
5051          * when determining what the new state should be since it shouldn't block
5052          * the user's request.
5053          */
5054         old_enabled = radio_enabled_for_rstate (rstate, TRUE);
5055         rstate->user_enabled = enabled;
5056         new_enabled = radio_enabled_for_rstate (rstate, FALSE);
5057         if (new_enabled != old_enabled) {
5058                 /* Try to change the kernel rfkill state */
5059                 if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN)
5060                         rfkill_change (rstate->desc, rstate->rtype, new_enabled);
5061
5062                 manager_update_radio_enabled (self, rstate, new_enabled);
5063         }
5064 }
5065
5066 static gboolean
5067 periodic_update_active_connection_timestamps (gpointer user_data)
5068 {
5069         NMManager *manager = NM_MANAGER (user_data);
5070         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5071         GSList *iter;
5072
5073         for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
5074                 NMActiveConnection *ac = iter->data;
5075                 NMSettingsConnection *connection;
5076
5077                 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
5078                         connection = nm_active_connection_get_settings_connection (ac);
5079                         nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
5080                 }
5081         }
5082
5083         return TRUE;
5084 }
5085
5086 static void
5087 dbus_connection_changed_cb (NMBusManager *dbus_mgr,
5088                             GDBusConnection *connection,
5089                             gpointer user_data)
5090 {
5091         _set_prop_filter (NM_MANAGER (user_data), connection);
5092 }
5093
5094 /**********************************************************************/
5095
5096 NM_DEFINE_SINGLETON_REGISTER (NMManager);
5097
5098 NMManager *
5099 nm_manager_get (void)
5100 {
5101         g_return_val_if_fail (singleton_instance, NULL);
5102         return singleton_instance;
5103 }
5104
5105 NMConnectionProvider *
5106 nm_connection_provider_get (void)
5107 {
5108         NMConnectionProvider *p;
5109
5110         g_return_val_if_fail (singleton_instance, NULL);
5111
5112         p = NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton_instance)->settings);
5113         g_return_val_if_fail (p, NULL);
5114         return p;
5115 }
5116
5117 NMManager *
5118 nm_manager_setup (const char *state_file,
5119                   gboolean initial_net_enabled,
5120                   gboolean initial_wifi_enabled,
5121                   gboolean initial_wwan_enabled)
5122 {
5123         NMManager *self;
5124
5125         g_return_val_if_fail (!singleton_instance, singleton_instance);
5126
5127         self = g_object_new (NM_TYPE_MANAGER,
5128                              NM_MANAGER_NETWORKING_ENABLED, initial_net_enabled,
5129                              NM_MANAGER_WIRELESS_ENABLED, initial_wifi_enabled,
5130                              NM_MANAGER_WWAN_ENABLED, initial_wwan_enabled,
5131                              NM_MANAGER_STATE_FILE, state_file,
5132                              NULL);
5133         nm_assert (NM_IS_MANAGER (self));
5134         singleton_instance = self;
5135
5136         nm_singleton_instance_register ();
5137         _LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance);
5138
5139         nm_exported_object_export ((NMExportedObject *) self);
5140
5141         return self;
5142 }
5143
5144 static void
5145 constructed (GObject *object)
5146 {
5147         NMManager *self = NM_MANAGER (object);
5148         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5149         NMConfigData *config_data;
5150
5151         G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
5152
5153         _set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr));
5154
5155         priv->settings = nm_settings_new ();
5156         g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE,
5157                           G_CALLBACK (settings_startup_complete_changed), self);
5158         g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
5159                           G_CALLBACK (system_unmanaged_devices_changed_cb), self);
5160         g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
5161                           G_CALLBACK (system_hostname_changed_cb), self);
5162         g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
5163                           G_CALLBACK (connection_changed), self);
5164         g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
5165                           G_CALLBACK (connection_changed), self);
5166         g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
5167                           G_CALLBACK (connection_removed), self);
5168
5169         priv->policy = nm_policy_new (self, priv->settings);
5170         g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
5171                           G_CALLBACK (policy_default_device_changed), self);
5172         g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
5173                           G_CALLBACK (policy_default_device_changed), self);
5174         g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
5175                           G_CALLBACK (policy_activating_device_changed), self);
5176         g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
5177                           G_CALLBACK (policy_activating_device_changed), self);
5178
5179         priv->config = g_object_ref (nm_config_get ());
5180         g_signal_connect (G_OBJECT (priv->config),
5181                           NM_CONFIG_SIGNAL_CONFIG_CHANGED,
5182                           G_CALLBACK (_config_changed_cb),
5183                           self);
5184
5185         config_data = nm_config_get_data (priv->config);
5186         priv->connectivity = nm_connectivity_new (nm_config_data_get_connectivity_uri (config_data),
5187                                                   nm_config_data_get_connectivity_interval (config_data),
5188                                                   nm_config_data_get_connectivity_response (config_data));
5189         g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
5190                           G_CALLBACK (connectivity_changed), self);
5191
5192         priv->rfkill_mgr = nm_rfkill_manager_new ();
5193         g_signal_connect (priv->rfkill_mgr,
5194                           "rfkill-changed",
5195                           G_CALLBACK (rfkill_manager_rfkill_changed_cb),
5196                           self);
5197
5198         /* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state
5199          * in case the BIOS doesn't save rfkill state, and to be consistent with user
5200          * changes to the WirelessEnabled/WWANEnabled properties which toggle kernel
5201          * rfkill.
5202          */
5203         rfkill_change (priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled);
5204         rfkill_change (priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, priv->radio_states[RFKILL_TYPE_WWAN].user_enabled);
5205 }
5206
5207 static void
5208 nm_manager_init (NMManager *self)
5209 {
5210         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5211         guint i;
5212         GFile *file;
5213
5214         /* Initialize rfkill structures and states */
5215         memset (priv->radio_states, 0, sizeof (priv->radio_states));
5216
5217         priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
5218         priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
5219         priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
5220         priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
5221         priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
5222         priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
5223
5224         priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
5225         priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
5226         priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
5227         priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
5228         priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
5229         priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
5230
5231         for (i = 0; i < RFKILL_TYPE_MAX; i++)
5232                 priv->radio_states[i].hw_enabled = TRUE;
5233
5234         priv->sleeping = FALSE;
5235         priv->state = NM_STATE_DISCONNECTED;
5236         priv->startup = TRUE;
5237
5238         priv->dbus_mgr = g_object_ref (nm_bus_manager_get ());
5239         g_signal_connect (priv->dbus_mgr,
5240                           NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED,
5241                           G_CALLBACK (dbus_connection_changed_cb),
5242                           self);
5243
5244         /* sleep/wake handling */
5245         priv->sleep_monitor = g_object_ref (nm_sleep_monitor_get ());
5246         g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING,
5247                           G_CALLBACK (sleeping_cb), self);
5248         g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_RESUMING,
5249                           G_CALLBACK (resuming_cb), self);
5250
5251         /* Listen for authorization changes */
5252         g_signal_connect (nm_auth_manager_get (),
5253                           NM_AUTH_MANAGER_SIGNAL_CHANGED,
5254                           G_CALLBACK (authority_changed_cb),
5255                           self);
5256
5257
5258         /* Monitor the firmware directory */
5259         if (strlen (KERNEL_FIRMWARE_DIR)) {
5260                 file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/");
5261                 priv->fw_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
5262                 g_object_unref (file);
5263         }
5264
5265         if (priv->fw_monitor) {
5266                 g_signal_connect (priv->fw_monitor, "changed",
5267                                   G_CALLBACK (firmware_dir_changed),
5268                                   self);
5269                 _LOGI (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
5270                              KERNEL_FIRMWARE_DIR);
5271         } else {
5272                 _LOGW (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
5273                        KERNEL_FIRMWARE_DIR);
5274         }
5275
5276         /* Update timestamps in active connections */
5277         priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, self);
5278
5279         priv->metered = NM_METERED_UNKNOWN;
5280 }
5281
5282 static gboolean
5283 device_is_real (GObject *device, gpointer user_data)
5284 {
5285         return nm_device_is_real (NM_DEVICE (device));
5286 }
5287
5288 static void
5289 get_property (GObject *object, guint prop_id,
5290               GValue *value, GParamSpec *pspec)
5291 {
5292         NMManager *self = NM_MANAGER (object);
5293         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5294         NMConfigData *config_data;
5295         const NMGlobalDnsConfig *dns_config;
5296         const char *type;
5297
5298         switch (prop_id) {
5299         case PROP_VERSION:
5300                 g_value_set_string (value, VERSION);
5301                 break;
5302         case PROP_STATE:
5303                 nm_manager_update_state (self);
5304                 g_value_set_uint (value, priv->state);
5305                 break;
5306         case PROP_STARTUP:
5307                 g_value_set_boolean (value, priv->startup);
5308                 break;
5309         case PROP_NETWORKING_ENABLED:
5310                 g_value_set_boolean (value, priv->net_enabled);
5311                 break;
5312         case PROP_WIRELESS_ENABLED:
5313                 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
5314                 break;
5315         case PROP_WIRELESS_HARDWARE_ENABLED:
5316                 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
5317                 break;
5318         case PROP_WWAN_ENABLED:
5319                 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
5320                 break;
5321         case PROP_WWAN_HARDWARE_ENABLED:
5322                 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
5323                 break;
5324         case PROP_WIMAX_ENABLED:
5325                 g_value_set_boolean (value, FALSE);
5326                 break;
5327         case PROP_WIMAX_HARDWARE_ENABLED:
5328                 g_value_set_boolean (value, FALSE);
5329                 break;
5330         case PROP_ACTIVE_CONNECTIONS:
5331                 nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
5332                 break;
5333         case PROP_CONNECTIVITY:
5334                 g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
5335                 break;
5336         case PROP_PRIMARY_CONNECTION:
5337                 nm_utils_g_value_set_object_path (value, priv->primary_connection);
5338                 break;
5339         case PROP_PRIMARY_CONNECTION_TYPE:
5340                 type = NULL;
5341                 if (priv->primary_connection) {
5342                         NMConnection *con;
5343
5344                         con = nm_active_connection_get_applied_connection (priv->primary_connection);
5345                         if (con)
5346                                 type = nm_connection_get_connection_type (con);
5347                 }
5348                 g_value_set_string (value, type ? type : "");
5349                 break;
5350         case PROP_ACTIVATING_CONNECTION:
5351                 nm_utils_g_value_set_object_path (value, priv->activating_connection);
5352                 break;
5353         case PROP_HOSTNAME:
5354                 g_value_set_string (value, priv->hostname);
5355                 break;
5356         case PROP_SLEEPING:
5357                 g_value_set_boolean (value, priv->sleeping);
5358                 break;
5359         case PROP_DEVICES:
5360                 nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
5361                 break;
5362         case PROP_METERED:
5363                 g_value_set_uint (value, priv->metered);
5364                 break;
5365         case PROP_GLOBAL_DNS_CONFIGURATION:
5366                 config_data = nm_config_get_data (priv->config);
5367                 dns_config = nm_config_data_get_global_dns_config (config_data);
5368                 nm_global_dns_config_to_dbus (dns_config, value);
5369                 break;
5370         case PROP_ALL_DEVICES:
5371                 nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
5372                 break;
5373         default:
5374                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5375                 break;
5376         }
5377 }
5378
5379 static void
5380 set_property (GObject *object, guint prop_id,
5381               const GValue *value, GParamSpec *pspec)
5382 {
5383         NMManager *self = NM_MANAGER (object);
5384         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
5385         NMGlobalDnsConfig *dns_config;
5386         GError *error = NULL;
5387
5388         switch (prop_id) {
5389         case PROP_STATE_FILE:
5390                 /* construct-only */
5391                 priv->state_file = g_value_dup_string (value);
5392                 break;
5393         case PROP_NETWORKING_ENABLED:
5394                 /* construct-only */
5395                 priv->net_enabled = g_value_get_boolean (value);
5396                 break;
5397         case PROP_WIRELESS_ENABLED:
5398                 if (!priv->rfkill_mgr) {
5399                         /* called during object construction. */
5400                         priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = g_value_get_boolean (value);
5401                 } else {
5402                         manager_radio_user_toggled (NM_MANAGER (object),
5403                                                     &priv->radio_states[RFKILL_TYPE_WLAN],
5404                                                     g_value_get_boolean (value));
5405                 }
5406                 break;
5407         case PROP_WWAN_ENABLED:
5408                 if (!priv->rfkill_mgr) {
5409                         /* called during object construction. */
5410                         priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = g_value_get_boolean (value);
5411                 } else {
5412                         manager_radio_user_toggled (NM_MANAGER (object),
5413                                                     &priv->radio_states[RFKILL_TYPE_WWAN],
5414                                                     g_value_get_boolean (value));
5415                 }
5416                 break;
5417         case PROP_WIMAX_ENABLED:
5418                 /* WIMAX is depreacted. This does nothing. */
5419                 break;
5420         case PROP_GLOBAL_DNS_CONFIGURATION:
5421                 dns_config = nm_global_dns_config_from_dbus (value, &error);
5422                 if (!error)
5423                         nm_config_set_global_dns (priv->config, dns_config, &error);
5424
5425                 nm_global_dns_config_free (dns_config);
5426
5427                 if (error) {
5428                         _LOGD (LOGD_CORE, "set global DNS failed with error: %s", error->message);
5429                         g_error_free (error);
5430                 }
5431                 break;
5432         default:
5433                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5434                 break;
5435         }
5436 }
5437
5438 static void
5439 _deinit_device_factory (NMDeviceFactory *factory, gpointer user_data)
5440 {
5441         g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NM_MANAGER (user_data));
5442 }
5443
5444 static void
5445 dispose (GObject *object)
5446 {
5447         NMManager *manager = NM_MANAGER (object);
5448         NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
5449
5450         g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
5451         priv->auth_chains = NULL;
5452
5453         g_signal_handlers_disconnect_by_func (nm_auth_manager_get (),
5454                                               G_CALLBACK (authority_changed_cb),
5455                                               manager);
5456
5457         g_assert (priv->devices == NULL);
5458
5459         nm_clear_g_source (&priv->ac_cleanup_id);
5460
5461         while (priv->active_connections)
5462                 active_connection_remove (manager, NM_ACTIVE_CONNECTION (priv->active_connections->data));
5463         g_clear_pointer (&priv->active_connections, g_slist_free);
5464         g_clear_object (&priv->primary_connection);
5465         g_clear_object (&priv->activating_connection);
5466
5467         if (priv->config) {
5468                 g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
5469                 g_clear_object (&priv->config);
5470         }
5471         if (priv->connectivity) {
5472                 g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
5473                 g_clear_object (&priv->connectivity);
5474         }
5475
5476         g_free (priv->hostname);
5477
5478         if (priv->policy) {
5479                 g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, manager);
5480                 g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, manager);
5481                 g_clear_object (&priv->policy);
5482         }
5483
5484         if (priv->settings) {
5485                 g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, manager);
5486                 g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, manager);
5487                 g_signal_handlers_disconnect_by_func (priv->settings, system_hostname_changed_cb, manager);
5488                 g_signal_handlers_disconnect_by_func (priv->settings, connection_changed, manager);
5489                 g_signal_handlers_disconnect_by_func (priv->settings, connection_removed, manager);
5490                 g_clear_object (&priv->settings);
5491         }
5492
5493         g_clear_pointer (&priv->state_file, g_free);
5494         g_clear_object (&priv->vpn_manager);
5495
5496         /* Unregister property filter */
5497         if (priv->dbus_mgr) {
5498                 g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, manager);
5499                 g_clear_object (&priv->dbus_mgr);
5500         }
5501         _set_prop_filter (manager, NULL);
5502
5503         if (priv->sleep_monitor) {
5504                 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, sleeping_cb, manager);
5505                 g_signal_handlers_disconnect_by_func (priv->sleep_monitor, resuming_cb, manager);
5506                 g_clear_object (&priv->sleep_monitor);
5507         }
5508
5509         if (priv->fw_monitor) {
5510                 g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager);
5511
5512                 nm_clear_g_source (&priv->fw_changed_id);
5513
5514                 g_file_monitor_cancel (priv->fw_monitor);
5515                 g_clear_object (&priv->fw_monitor);
5516         }
5517
5518         if (priv->rfkill_mgr) {
5519                 g_signal_handlers_disconnect_by_func (priv->rfkill_mgr, rfkill_manager_rfkill_changed_cb, manager);
5520                 g_clear_object (&priv->rfkill_mgr);
5521         }
5522
5523         nm_device_factory_manager_for_each_factory (_deinit_device_factory, manager);
5524
5525         nm_clear_g_source (&priv->timestamp_update_id);
5526
5527         G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
5528 }
5529
5530 static void
5531 nm_manager_class_init (NMManagerClass *manager_class)
5532 {
5533         GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
5534         NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
5535
5536         g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
5537
5538         exported_object_class->export_path = NM_DBUS_PATH;
5539
5540         /* virtual methods */
5541         object_class->constructed = constructed;
5542         object_class->set_property = set_property;
5543         object_class->get_property = get_property;
5544         object_class->dispose = dispose;
5545
5546         /* properties */
5547         g_object_class_install_property
5548                 (object_class, PROP_VERSION,
5549                  g_param_spec_string (NM_MANAGER_VERSION, "", "",
5550                                       NULL,
5551                                       G_PARAM_READABLE |
5552                                       G_PARAM_STATIC_STRINGS));
5553
5554         g_object_class_install_property (object_class,
5555                                          PROP_STATE_FILE,
5556                                          g_param_spec_string (NM_MANAGER_STATE_FILE, "", "",
5557                                                               NULL,
5558                                                               G_PARAM_WRITABLE |
5559                                                               G_PARAM_CONSTRUCT_ONLY |
5560                                                               G_PARAM_STATIC_STRINGS));
5561
5562         g_object_class_install_property
5563                 (object_class, PROP_STATE,
5564                  g_param_spec_uint (NM_MANAGER_STATE, "", "",
5565                                     0, NM_STATE_DISCONNECTED, 0,
5566                                     G_PARAM_READABLE |
5567                                     G_PARAM_STATIC_STRINGS));
5568
5569         g_object_class_install_property
5570                 (object_class, PROP_STARTUP,
5571                  g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
5572                                        TRUE,
5573                                        G_PARAM_READABLE |
5574                                        G_PARAM_STATIC_STRINGS));
5575
5576         g_object_class_install_property
5577                 (object_class, PROP_NETWORKING_ENABLED,
5578                  g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
5579                                        TRUE,
5580                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
5581                                        G_PARAM_STATIC_STRINGS));
5582
5583         g_object_class_install_property
5584                 (object_class, PROP_WIRELESS_ENABLED,
5585                  g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
5586                                        TRUE,
5587                                        G_PARAM_READWRITE |
5588                                        G_PARAM_CONSTRUCT |
5589                                        G_PARAM_STATIC_STRINGS));
5590
5591         g_object_class_install_property
5592                 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
5593                  g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
5594                                        TRUE,
5595                                        G_PARAM_READABLE |
5596                                        G_PARAM_STATIC_STRINGS));
5597
5598         g_object_class_install_property
5599                 (object_class, PROP_WWAN_ENABLED,
5600                  g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
5601                                        TRUE,
5602                                        G_PARAM_READWRITE |
5603                                        G_PARAM_CONSTRUCT |
5604                                        G_PARAM_STATIC_STRINGS));
5605
5606         g_object_class_install_property
5607                 (object_class, PROP_WWAN_HARDWARE_ENABLED,
5608                  g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
5609                                        TRUE,
5610                                        G_PARAM_READABLE |
5611                                        G_PARAM_STATIC_STRINGS));
5612
5613         g_object_class_install_property
5614                 (object_class, PROP_WIMAX_ENABLED,
5615                  g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
5616                                        TRUE,
5617                                        G_PARAM_READWRITE |
5618                                        G_PARAM_STATIC_STRINGS));
5619
5620         g_object_class_install_property
5621                 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
5622                  g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
5623                                        TRUE,
5624                                        G_PARAM_READABLE |
5625                                        G_PARAM_STATIC_STRINGS));
5626
5627         g_object_class_install_property
5628                 (object_class, PROP_ACTIVE_CONNECTIONS,
5629                  g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
5630                                      G_TYPE_STRV,
5631                                      G_PARAM_READABLE |
5632                                      G_PARAM_STATIC_STRINGS));
5633
5634         g_object_class_install_property
5635                 (object_class, PROP_CONNECTIVITY,
5636                  g_param_spec_uint (NM_MANAGER_CONNECTIVITY, "", "",
5637                                     NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
5638                                     G_PARAM_READABLE |
5639                                     G_PARAM_STATIC_STRINGS));
5640
5641         g_object_class_install_property
5642                 (object_class, PROP_PRIMARY_CONNECTION,
5643                  g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION, "", "",
5644                                       NULL,
5645                                       G_PARAM_READABLE |
5646                                       G_PARAM_STATIC_STRINGS));
5647
5648         g_object_class_install_property
5649                 (object_class, PROP_PRIMARY_CONNECTION_TYPE,
5650                  g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "",
5651                                       NULL,
5652                                       G_PARAM_READABLE |
5653                                       G_PARAM_STATIC_STRINGS));
5654
5655
5656         g_object_class_install_property
5657                 (object_class, PROP_ACTIVATING_CONNECTION,
5658                  g_param_spec_string (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
5659                                       NULL,
5660                                       G_PARAM_READABLE |
5661                                       G_PARAM_STATIC_STRINGS));
5662
5663         /* Hostname is not exported over D-Bus */
5664         g_object_class_install_property
5665                 (object_class, PROP_HOSTNAME,
5666                  g_param_spec_string (NM_MANAGER_HOSTNAME, "", "",
5667                                       NULL,
5668                                       G_PARAM_READABLE |
5669                                       G_PARAM_STATIC_STRINGS));
5670
5671         /* Sleeping is not exported over D-Bus */
5672         g_object_class_install_property
5673                 (object_class, PROP_SLEEPING,
5674                  g_param_spec_boolean (NM_MANAGER_SLEEPING, "", "",
5675                                        FALSE,
5676                                        G_PARAM_READABLE |
5677                                        G_PARAM_STATIC_STRINGS));
5678
5679         g_object_class_install_property
5680                 (object_class, PROP_DEVICES,
5681                  g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
5682                                      G_TYPE_STRV,
5683                                      G_PARAM_READABLE |
5684                                      G_PARAM_STATIC_STRINGS));
5685
5686         /**
5687          * NMManager:metered:
5688          *
5689          * Whether the connectivity is metered.
5690          *
5691          * Since: 1.2
5692          **/
5693         g_object_class_install_property
5694                 (object_class, PROP_METERED,
5695                  g_param_spec_uint (NM_MANAGER_METERED, "", "",
5696                                     0, G_MAXUINT32, NM_METERED_UNKNOWN,
5697                                     G_PARAM_READABLE |
5698                                     G_PARAM_STATIC_STRINGS));
5699
5700         /**
5701          * NMManager:global-dns-configuration:
5702          *
5703          * The global DNS configuration.
5704          *
5705          * Since: 1.2
5706          **/
5707         g_object_class_install_property
5708                 (object_class, PROP_GLOBAL_DNS_CONFIGURATION,
5709                  g_param_spec_variant (NM_MANAGER_GLOBAL_DNS_CONFIGURATION, "", "",
5710                                        G_VARIANT_TYPE ("a{sv}"),
5711                                        NULL,
5712                                        G_PARAM_READWRITE |
5713                                        G_PARAM_STATIC_STRINGS));
5714
5715         /**
5716          * NMManager:all-devices:
5717          *
5718          * All devices, including those that are not realized.
5719          *
5720          * Since: 1.2
5721          **/
5722         g_object_class_install_property
5723                 (object_class, PROP_ALL_DEVICES,
5724                  g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
5725                                      G_TYPE_STRV,
5726                                      G_PARAM_READABLE |
5727                                      G_PARAM_STATIC_STRINGS));
5728
5729         /* signals */
5730
5731         /* D-Bus exported; emitted only for realized devices */
5732         signals[DEVICE_ADDED] =
5733                 g_signal_new ("device-added",
5734                               G_OBJECT_CLASS_TYPE (object_class),
5735                               G_SIGNAL_RUN_FIRST,
5736                               G_STRUCT_OFFSET (NMManagerClass, device_added),
5737                               NULL, NULL, NULL,
5738                               G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5739
5740         /* Emitted for both realized devices and placeholder devices */
5741         signals[INTERNAL_DEVICE_ADDED] =
5742                 g_signal_new ("internal-device-added",
5743                               G_OBJECT_CLASS_TYPE (object_class),
5744                               G_SIGNAL_RUN_FIRST, 0,
5745                               NULL, NULL, NULL,
5746                               G_TYPE_NONE, 1, G_TYPE_OBJECT);
5747
5748         /* D-Bus exported; emitted only for realized devices */
5749         signals[DEVICE_REMOVED] =
5750                 g_signal_new ("device-removed",
5751                               G_OBJECT_CLASS_TYPE (object_class),
5752                               G_SIGNAL_RUN_FIRST,
5753                               G_STRUCT_OFFSET (NMManagerClass, device_removed),
5754                               NULL, NULL, NULL,
5755                               G_TYPE_NONE, 1, NM_TYPE_DEVICE);
5756
5757         /* Emitted for both realized devices and placeholder devices */
5758         signals[INTERNAL_DEVICE_REMOVED] =
5759                 g_signal_new ("internal-device-removed",
5760                               G_OBJECT_CLASS_TYPE (object_class),
5761                               G_SIGNAL_RUN_FIRST, 0,
5762                               NULL, NULL, NULL,
5763                               G_TYPE_NONE, 1, G_TYPE_OBJECT);
5764
5765         signals[STATE_CHANGED] =
5766                 g_signal_new (NM_MANAGER_STATE_CHANGED,
5767                               G_OBJECT_CLASS_TYPE (object_class),
5768                               G_SIGNAL_RUN_FIRST,
5769                               G_STRUCT_OFFSET (NMManagerClass, state_changed),
5770                               NULL, NULL, NULL,
5771                               G_TYPE_NONE, 1, G_TYPE_UINT);
5772
5773         signals[CHECK_PERMISSIONS] =
5774                 g_signal_new ("check-permissions",
5775                               G_OBJECT_CLASS_TYPE (object_class),
5776                               G_SIGNAL_RUN_FIRST,
5777                               0, NULL, NULL, NULL,
5778                               G_TYPE_NONE, 0);
5779
5780         signals[USER_PERMISSIONS_CHANGED] =
5781                 g_signal_new ("user-permissions-changed",
5782                               G_OBJECT_CLASS_TYPE (object_class),
5783                               G_SIGNAL_RUN_FIRST,
5784                               0, NULL, NULL, NULL,
5785                               G_TYPE_NONE, 0);
5786
5787         signals[ACTIVE_CONNECTION_ADDED] =
5788                 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
5789                               G_OBJECT_CLASS_TYPE (object_class),
5790                               G_SIGNAL_RUN_FIRST,
5791                               0, NULL, NULL, NULL,
5792                               G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5793
5794         signals[ACTIVE_CONNECTION_REMOVED] =
5795                 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
5796                               G_OBJECT_CLASS_TYPE (object_class),
5797                               G_SIGNAL_RUN_FIRST,
5798                               0, NULL, NULL, NULL,
5799                               G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
5800
5801         signals[CONFIGURE_QUIT] =
5802                 g_signal_new (NM_MANAGER_CONFIGURE_QUIT,
5803                               G_OBJECT_CLASS_TYPE (object_class),
5804                               G_SIGNAL_RUN_FIRST,
5805                               0, NULL, NULL, NULL,
5806                               G_TYPE_NONE, 0);
5807
5808         nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class),
5809                                                 NMDBUS_TYPE_MANAGER_SKELETON,
5810                                                 "GetDevices", impl_manager_get_devices,
5811                                                 "GetAllDevices", impl_manager_get_all_devices,
5812                                                 "GetDeviceByIpIface", impl_manager_get_device_by_ip_iface,
5813                                                 "ActivateConnection", impl_manager_activate_connection,
5814                                                 "AddAndActivateConnection", impl_manager_add_and_activate_connection,
5815                                                 "DeactivateConnection", impl_manager_deactivate_connection,
5816                                                 "Sleep", impl_manager_sleep,
5817                                                 "Enable", impl_manager_enable,
5818                                                 "GetPermissions", impl_manager_get_permissions,
5819                                                 "SetLogging", impl_manager_set_logging,
5820                                                 "GetLogging", impl_manager_get_logging,
5821                                                 "CheckConnectivity", impl_manager_check_connectivity,
5822                                                 "state", impl_manager_get_state,
5823                                                 NULL);
5824 }
5825