76249a37a7cd4b9a6065f1f5d4ecc2369cc77902
[NetworkManager.git] / src / nm-policy.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) 2004 - 2013 Red Hat, Inc.
19  * Copyright (C) 2007 - 2008 Novell, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <netdb.h>
28
29 #include "nm-policy.h"
30 #include "NetworkManagerUtils.h"
31 #include "nm-activation-request.h"
32 #include "nm-device.h"
33 #include "nm-default-route-manager.h"
34 #include "nm-setting-ip4-config.h"
35 #include "nm-setting-connection.h"
36 #include "nm-platform.h"
37 #include "nm-dns-manager.h"
38 #include "nm-vpn-manager.h"
39 #include "nm-auth-utils.h"
40 #include "nm-firewall-manager.h"
41 #include "nm-dispatcher.h"
42 #include "nm-utils.h"
43 #include "nm-core-internal.h"
44 #include "nm-manager.h"
45 #include "nm-settings.h"
46 #include "nm-settings-connection.h"
47 #include "nm-dhcp4-config.h"
48 #include "nm-dhcp6-config.h"
49
50 #define _NMLOG_PREFIX_NAME    "policy"
51 #define _NMLOG(level, domain, ...) \
52     G_STMT_START { \
53         nm_log ((level), (domain), \
54                 "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
55                 _NMLOG_PREFIX_NAME": " \
56                 _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
57     } G_STMT_END
58
59 typedef struct {
60         NMManager *manager;
61         NMFirewallManager *firewall_manager;
62         guint update_state_id;
63         GSList *pending_activation_checks;
64         GSList *manager_ids;
65         GSList *settings_ids;
66         GSList *dev_ids;
67
68         GSList *pending_secondaries;
69
70         gulong fw_started_id;
71
72         NMSettings *settings;
73
74         NMDevice *default_device4, *activating_device4;
75         NMDevice *default_device6, *activating_device6;
76
77         GResolver *resolver;
78         GInetAddress *lookup_addr;
79         GCancellable *lookup_cancellable;
80         NMDnsManager *dns_manager;
81         gulong config_changed_id;
82
83         guint reset_retries_id;  /* idle handler for resetting the retries count */
84
85         char *orig_hostname; /* hostname at NM start time */
86         char *cur_hostname;  /* hostname we want to assign */
87         gboolean hostname_changed;  /* TRUE if NM ever set the hostname */
88 } NMPolicyPrivate;
89
90 #define NM_POLICY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_POLICY, NMPolicyPrivate))
91
92 G_DEFINE_TYPE (NMPolicy, nm_policy, G_TYPE_OBJECT)
93
94 NM_GOBJECT_PROPERTIES_DEFINE (NMPolicy,
95         PROP_DEFAULT_IP4_DEVICE,
96         PROP_DEFAULT_IP6_DEVICE,
97         PROP_ACTIVATING_IP4_DEVICE,
98         PROP_ACTIVATING_IP6_DEVICE,
99 );
100
101 static void schedule_activate_all (NMPolicy *policy);
102
103
104 static NMDevice *
105 get_best_ip4_device (NMPolicy *self, gboolean fully_activated)
106 {
107         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
108
109         return nm_default_route_manager_ip4_get_best_device (nm_default_route_manager_get (),
110                                                              nm_manager_get_devices (priv->manager),
111                                                              fully_activated,
112                                                              priv->default_device4);
113 }
114
115 static NMDevice *
116 get_best_ip6_device (NMPolicy *self, gboolean fully_activated)
117 {
118         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
119
120         return nm_default_route_manager_ip6_get_best_device (nm_default_route_manager_get (),
121                                                              nm_manager_get_devices (priv->manager),
122                                                              fully_activated,
123                                                              priv->default_device6);
124 }
125
126 #define FALLBACK_HOSTNAME4 "localhost.localdomain"
127
128 static void settings_set_hostname_cb (const char *hostname,
129                                       gboolean result,
130                                       gpointer user_data)
131 {
132         int ret = 0;
133
134         if (!result) {
135                 ret = sethostname (hostname, strlen (hostname));
136                 if (ret != 0) {
137                         int errsv = errno;
138
139                         _LOGW (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
140                                hostname, errsv, strerror (errsv));
141                         if (errsv == EPERM)
142                                 _LOGW (LOGD_DNS, "you should use hostnamed when systemd hardening is in effect!");
143                 }
144         }
145
146         if (!ret)
147                 nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL);
148 }
149
150 static void
151 _set_hostname (NMPolicy *policy,
152                const char *new_hostname,
153                const char *msg)
154 {
155         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
156         char old_hostname[HOST_NAME_MAX + 1];
157         const char *name;
158         int ret;
159
160         /* The incoming hostname *can* be NULL, which will get translated to
161          * 'localhost.localdomain' or such in the hostname policy code, but we
162          * keep cur_hostname = NULL in the case because we need to know that
163          * there was no valid hostname to start with.
164          */
165
166         /* Clear lookup addresses if we have a hostname, so that we don't
167          * restart the reverse lookup thread later.
168          */
169         if (new_hostname)
170                 g_clear_object (&priv->lookup_addr);
171
172         /* Don't change the hostname or update DNS this is the first time we're
173          * trying to change the hostname, and it's not actually changing.
174          */
175         if (   priv->orig_hostname
176             && (priv->hostname_changed == FALSE)
177             && g_strcmp0 (priv->orig_hostname, new_hostname) == 0)
178                 return;
179
180         /* Don't change the hostname or update DNS if the hostname isn't actually
181          * going to change.
182          */
183         if (g_strcmp0 (priv->cur_hostname, new_hostname) == 0)
184                 return;
185
186         g_free (priv->cur_hostname);
187         priv->cur_hostname = g_strdup (new_hostname);
188         priv->hostname_changed = TRUE;
189
190         /* Notify the DNS manager of the hostname change so that the domain part, if
191          * present, can be added to the search list.
192          */
193         nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname);
194
195          /* Finally, set kernel hostname */
196
197         if (!priv->cur_hostname)
198                 name = FALLBACK_HOSTNAME4;
199         else if (!priv->cur_hostname[0]) {
200                 g_warn_if_reached ();
201                 name = FALLBACK_HOSTNAME4;
202         } else
203                 name = priv->cur_hostname;
204
205         old_hostname[HOST_NAME_MAX] = '\0';
206         errno = 0;
207         ret = gethostname (old_hostname, HOST_NAME_MAX);
208         if (ret != 0) {
209                 _LOGW (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
210                        errno, strerror (errno));
211         } else {
212                 /* Don't set the hostname if it isn't actually changing */
213                 if (nm_streq (name, old_hostname))
214                         return;
215         }
216
217         _LOGI (LOGD_DNS, "setting system hostname to '%s' (%s)", name, msg);
218
219         /* Ask NMSettings to update the transient hostname using its
220          * systemd-hostnamed proxy */
221         nm_settings_set_transient_hostname (priv->settings,
222                                             name,
223                                             settings_set_hostname_cb,
224                                             NULL);
225 }
226
227 static void
228 lookup_callback (GObject *source,
229                  GAsyncResult *result,
230                  gpointer user_data)
231 {
232         NMPolicy *policy = (NMPolicy *) user_data;
233         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
234         const char *hostname;
235         GError *error = NULL;
236
237         hostname = g_resolver_lookup_by_address_finish (G_RESOLVER (source), result, &error);
238         if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
239                 /* Don't touch policy; it may have been freed already */
240                 g_error_free (error);
241                 return;
242         }
243
244         if (hostname)
245                 _set_hostname (policy, hostname, "from address lookup");
246         else {
247                 _set_hostname (policy, NULL, error->message);
248                 g_error_free (error);
249         }
250
251         g_clear_object (&priv->lookup_cancellable);
252 }
253
254 static void
255 update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
256 {
257         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
258         char *configured_hostname = NULL;
259         const char *dhcp_hostname, *p;
260         NMIP4Config *ip4_config;
261         NMIP6Config *ip6_config;
262
263         g_return_if_fail (policy != NULL);
264
265         if (priv->lookup_cancellable) {
266                 g_cancellable_cancel (priv->lookup_cancellable);
267                 g_clear_object (&priv->lookup_cancellable);
268         }
269
270         /* Hostname precedence order:
271          *
272          * 1) a configured hostname (from settings)
273          * 2) automatic hostname from the default device's config (DHCP, VPN, etc)
274          * 3) the original hostname when NM started
275          * 4) reverse-DNS of the best device's IPv4 address
276          *
277          */
278
279         /* Try a persistent hostname first */
280         g_object_get (G_OBJECT (priv->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
281         if (configured_hostname && nm_utils_is_specific_hostname (configured_hostname)) {
282                 _set_hostname (policy, configured_hostname, "from system configuration");
283                 g_free (configured_hostname);
284                 return;
285         }
286         g_free (configured_hostname);
287
288         /* Try automatically determined hostname from the best device's IP config */
289         if (!best4)
290                 best4 = get_best_ip4_device (policy, TRUE);
291         if (!best6)
292                 best6 = get_best_ip6_device (policy, TRUE);
293
294         if (!best4 && !best6) {
295                 /* No best device; fall back to original hostname or if there wasn't
296                  * one, 'localhost.localdomain'
297                  */
298                 _set_hostname (policy, priv->orig_hostname, "no default device");
299                 return;
300         }
301
302         if (best4) {
303                 NMDhcp4Config *dhcp4_config;
304
305                 /* Grab a hostname out of the device's DHCP4 config */
306                 dhcp4_config = nm_device_get_dhcp4_config (best4);
307                 if (dhcp4_config) {
308                         p = dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name");
309                         if (dhcp_hostname && strlen (dhcp_hostname)) {
310                                 /* Sanity check; strip leading spaces */
311                                 while (*p) {
312                                         if (!g_ascii_isspace (*p++)) {
313                                                 _set_hostname (policy, p-1, "from DHCPv4");
314                                                 return;
315                                         }
316                                 }
317                                 _LOGW (LOGD_DNS, "DHCPv4-provided hostname '%s' looks invalid; ignoring it",
318                                        dhcp_hostname);
319                         }
320                 }
321         } else if (best6) {
322                 NMDhcp6Config *dhcp6_config;
323
324                 /* Grab a hostname out of the device's DHCP6 config */
325                 dhcp6_config = nm_device_get_dhcp6_config (best6);
326                 if (dhcp6_config) {
327                         p = dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name");
328                         if (dhcp_hostname && strlen (dhcp_hostname)) {
329                                 /* Sanity check; strip leading spaces */
330                                 while (*p) {
331                                         if (!g_ascii_isspace (*p++)) {
332                                                 _set_hostname (policy, p-1, "from DHCPv6");
333                                                 return;
334                                         }
335                                 }
336                                 _LOGW (LOGD_DNS, "DHCPv6-provided hostname '%s' looks invalid; ignoring it",
337                                        dhcp_hostname);
338                         }
339                 }
340         }
341
342         /* If no automatically-configured hostname, try using the hostname from
343          * when NM started up.
344          */
345         if (priv->orig_hostname) {
346                 _set_hostname (policy, priv->orig_hostname, "from system startup");
347                 return;
348         }
349
350         /* No configured hostname, no automatically determined hostname, and no
351          * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
352          */
353         ip4_config = best4 ? nm_device_get_ip4_config (best4) : NULL;
354         ip6_config = best6 ? nm_device_get_ip6_config (best6) : NULL;
355
356         if (ip4_config && nm_ip4_config_get_num_addresses (ip4_config) > 0) {
357                 const NMPlatformIP4Address *addr4;
358
359                 addr4 = nm_ip4_config_get_address (ip4_config, 0);
360                 g_clear_object (&priv->lookup_addr);
361                 priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr4->address,
362                                                                    G_SOCKET_FAMILY_IPV4);
363         } else if (ip6_config && nm_ip6_config_get_num_addresses (ip6_config) > 0) {
364                 const NMPlatformIP6Address *addr6;
365
366                 addr6 = nm_ip6_config_get_address (ip6_config, 0);
367                 g_clear_object (&priv->lookup_addr);
368                 priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr6->address,
369                                                                    G_SOCKET_FAMILY_IPV6);
370         } else {
371                 /* No valid IP config; fall back to localhost.localdomain */
372                 _set_hostname (policy, NULL, "no IP config");
373                 return;
374         }
375
376         priv->lookup_cancellable = g_cancellable_new ();
377         g_resolver_lookup_by_address_async (priv->resolver,
378                                             priv->lookup_addr,
379                                             priv->lookup_cancellable,
380                                             lookup_callback, policy);
381 }
382
383 static void
384 update_default_ac (NMPolicy *policy,
385                    NMActiveConnection *best,
386                    void (*set_active_func)(NMActiveConnection*, gboolean))
387 {
388         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
389         const GSList *connections, *iter;
390
391         /* Clear the 'default[6]' flag on all active connections that aren't the new
392          * default active connection.  We'll set the new default after; this ensures
393          * we don't ever have two marked 'default[6]' simultaneously.
394          */
395         connections = nm_manager_get_active_connections (priv->manager);
396         for (iter = connections; iter; iter = g_slist_next (iter)) {
397                 if (NM_ACTIVE_CONNECTION (iter->data) != best)
398                         set_active_func (NM_ACTIVE_CONNECTION (iter->data), FALSE);
399         }
400
401         /* Mark new default active connection */
402         if (best)
403                 set_active_func (best, TRUE);
404 }
405
406 static NMIP4Config *
407 get_best_ip4_config (NMPolicy *self,
408                      gboolean ignore_never_default,
409                      const char **out_ip_iface,
410                      NMActiveConnection **out_ac,
411                      NMDevice **out_device,
412                      NMVpnConnection **out_vpn)
413 {
414         return nm_default_route_manager_ip4_get_best_config (nm_default_route_manager_get (),
415                                                              ignore_never_default,
416                                                              out_ip_iface,
417                                                              out_ac,
418                                                              out_device,
419                                                              out_vpn);
420 }
421
422 static void
423 update_ip4_dns (NMPolicy *policy, NMDnsManager *dns_mgr)
424 {
425         NMIP4Config *ip4_config;
426         const char *ip_iface = NULL;
427         NMVpnConnection *vpn = NULL;
428         NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
429
430         ip4_config = get_best_ip4_config (policy, TRUE, &ip_iface, NULL, NULL, &vpn);
431         if (ip4_config) {
432                 if (vpn)
433                         dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
434
435                 /* Tell the DNS manager this config is preferred by re-adding it with
436                  * a different IP config type.
437                  */
438                 nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, ip4_config, dns_type);
439         }
440 }
441
442 static void
443 update_ip4_routing (NMPolicy *policy, gboolean force_update)
444 {
445         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
446         NMDevice *best = NULL, *default_device;
447         NMConnection *connection = NULL;
448         NMVpnConnection *vpn = NULL;
449         NMActiveConnection *best_ac = NULL;
450         const char *ip_iface = NULL;
451
452         /* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
453          * so we can get (vpn != NULL && best == NULL).
454          */
455         if (!get_best_ip4_config (policy, FALSE, &ip_iface, &best_ac, &best, &vpn)) {
456                 gboolean changed;
457
458                 changed = (priv->default_device4 != NULL);
459                 priv->default_device4 = NULL;
460                 if (changed)
461                         _notify (policy, PROP_DEFAULT_IP4_DEVICE);
462
463                 return;
464         }
465         g_assert ((best || vpn) && best_ac);
466
467         if (!force_update && best && (best == priv->default_device4))
468                 return;
469
470         if (best) {
471                 const GSList *connections, *iter;
472
473                 connections = nm_manager_get_active_connections (priv->manager);
474                 for (iter = connections; iter; iter = g_slist_next (iter)) {
475                         NMActiveConnection *active = iter->data;
476
477                         if (   NM_IS_VPN_CONNECTION (active)
478                             && nm_vpn_connection_get_ip4_config (NM_VPN_CONNECTION (active))
479                             && !nm_active_connection_get_device (active))
480                                 nm_active_connection_set_device (active, best);
481                 }
482         }
483
484         if (vpn)
485                 default_device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn));
486         else
487                 default_device = best;
488
489         update_default_ac (policy, best_ac, nm_active_connection_set_default);
490
491         if (default_device == priv->default_device4)
492                 return;
493
494         priv->default_device4 = default_device;
495         connection = nm_active_connection_get_applied_connection (best_ac);
496         _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS",
497                nm_connection_get_id (connection), ip_iface);
498         _notify (policy, PROP_DEFAULT_IP4_DEVICE);
499 }
500
501 static NMIP6Config *
502 get_best_ip6_config (NMPolicy *self,
503                      gboolean ignore_never_default,
504                      const char **out_ip_iface,
505                      NMActiveConnection **out_ac,
506                      NMDevice **out_device,
507                      NMVpnConnection **out_vpn)
508 {
509         return nm_default_route_manager_ip6_get_best_config (nm_default_route_manager_get (),
510                                                              ignore_never_default,
511                                                              out_ip_iface,
512                                                              out_ac,
513                                                              out_device,
514                                                              out_vpn);
515 }
516
517 static void
518 update_ip6_dns (NMPolicy *policy, NMDnsManager *dns_mgr)
519 {
520         NMIP6Config *ip6_config;
521         const char *ip_iface = NULL;
522         NMVpnConnection *vpn = NULL;
523         NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
524
525         ip6_config = get_best_ip6_config (policy, TRUE, &ip_iface, NULL, NULL, &vpn);
526         if (ip6_config) {
527                 if (vpn)
528                         dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
529
530                 /* Tell the DNS manager this config is preferred by re-adding it with
531                  * a different IP config type.
532                  */
533                 nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, ip6_config, dns_type);
534         }
535 }
536
537 static void
538 update_ip6_routing (NMPolicy *policy, gboolean force_update)
539 {
540         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
541         NMDevice *best = NULL, *default_device6;
542         NMConnection *connection = NULL;
543         NMVpnConnection *vpn = NULL;
544         NMActiveConnection *best_ac = NULL;
545         const char *ip_iface = NULL;
546
547         /* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
548          * so we can get (vpn != NULL && best == NULL).
549          */
550         if (!get_best_ip6_config (policy, FALSE, &ip_iface, &best_ac, &best, &vpn)) {
551                 gboolean changed;
552
553                 changed = (priv->default_device6 != NULL);
554                 priv->default_device6 = NULL;
555                 if (changed)
556                         _notify (policy, PROP_DEFAULT_IP6_DEVICE);
557
558                 return;
559         }
560         g_assert ((best || vpn) && best_ac);
561
562         if (!force_update && best && (best == priv->default_device6))
563                 return;
564
565         if (best) {
566                 const GSList *connections, *iter;
567
568                 connections = nm_manager_get_active_connections (priv->manager);
569                 for (iter = connections; iter; iter = g_slist_next (iter)) {
570                         NMActiveConnection *active = iter->data;
571
572                         if (   NM_IS_VPN_CONNECTION (active)
573                             && nm_vpn_connection_get_ip6_config (NM_VPN_CONNECTION (active))
574                             && !nm_active_connection_get_device (active))
575                                 nm_active_connection_set_device (active, best);
576                 }
577         }
578
579         if (vpn)
580                 default_device6 = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn));
581         else
582                 default_device6 = best;
583
584         update_default_ac (policy, best_ac, nm_active_connection_set_default6);
585
586         if (default_device6 == priv->default_device6)
587                 return;
588
589         priv->default_device6 = default_device6;
590         connection = nm_active_connection_get_applied_connection (best_ac);
591         _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS",
592                nm_connection_get_id (connection), ip_iface);
593         _notify (policy, PROP_DEFAULT_IP6_DEVICE);
594 }
595
596 static void
597 update_routing_and_dns (NMPolicy *policy, gboolean force_update)
598 {
599         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
600
601         nm_dns_manager_begin_updates (priv->dns_manager, __func__);
602
603         update_ip4_dns (policy, priv->dns_manager);
604         update_ip6_dns (policy, priv->dns_manager);
605
606         update_ip4_routing (policy, force_update);
607         update_ip6_routing (policy, force_update);
608
609         /* Update the system hostname */
610         update_system_hostname (policy, priv->default_device4, priv->default_device6);
611
612         nm_dns_manager_end_updates (priv->dns_manager, __func__);
613 }
614
615 static void
616 check_activating_devices (NMPolicy *policy)
617 {
618         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
619         GObject *object = G_OBJECT (policy);
620         NMDevice *best4, *best6 = NULL;
621
622         best4 = get_best_ip4_device (policy, FALSE);
623         best6 = get_best_ip6_device (policy, FALSE);
624
625         g_object_freeze_notify (object);
626
627         if (best4 != priv->activating_device4) {
628                 priv->activating_device4 = best4;
629                 _notify (policy, PROP_ACTIVATING_IP4_DEVICE);
630         }
631         if (best6 != priv->activating_device6) {
632                 priv->activating_device6 = best6;
633                 _notify (policy, PROP_ACTIVATING_IP6_DEVICE);
634         }
635
636         g_object_thaw_notify (object);
637 }
638
639 typedef struct {
640         NMPolicy *policy;
641         NMDevice *device;
642         guint autoactivate_id;
643 } ActivateData;
644
645 static void
646 activate_data_free (ActivateData *data)
647 {
648         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (data->policy);
649
650         nm_device_remove_pending_action (data->device, "autoactivate", TRUE);
651         priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
652
653         if (data->autoactivate_id)
654                 g_source_remove (data->autoactivate_id);
655         g_object_unref (data->device);
656         g_free (data);
657 }
658
659 static gboolean
660 auto_activate_device (gpointer user_data)
661 {
662         ActivateData *data = (ActivateData *) user_data;
663         NMPolicy *policy;
664         NMPolicyPrivate *priv;
665         NMSettingsConnection *best_connection;
666         char *specific_object = NULL;
667         GPtrArray *connections;
668         GSList *connection_list;
669         guint i;
670
671         g_assert (data);
672         policy = data->policy;
673         priv = NM_POLICY_GET_PRIVATE (policy);
674
675         data->autoactivate_id = 0;
676
677         // FIXME: if a device is already activating (or activated) with a connection
678         // but another connection now overrides the current one for that device,
679         // deactivate the device and activate the new connection instead of just
680         // bailing if the device is already active
681         if (nm_device_get_act_request (data->device))
682                 goto out;
683
684         connection_list = nm_manager_get_activatable_connections (priv->manager);
685         if (!connection_list)
686                 goto out;
687
688         connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL);
689         g_slist_free (connection_list);
690
691         /* sort is stable (which is important at this point) so that connections
692          * with same priority are still sorted by last-connected-timestamp. */
693         g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority);
694
695         /* Find the first connection that should be auto-activated */
696         best_connection = NULL;
697         for (i = 0; i < connections->len; i++) {
698                 NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections->pdata[i]);
699
700                 if (!nm_settings_connection_can_autoconnect (candidate))
701                         continue;
702                 if (nm_device_can_auto_connect (data->device, (NMConnection *) candidate, &specific_object)) {
703                         best_connection = candidate;
704                         break;
705                 }
706         }
707         g_ptr_array_free (connections, TRUE);
708
709         if (best_connection) {
710                 GError *error = NULL;
711                 NMAuthSubject *subject;
712
713                 _LOGI (LOGD_DEVICE, "auto-activating connection '%s'",
714                        nm_settings_connection_get_id (best_connection));
715                 subject = nm_auth_subject_new_internal ();
716                 if (!nm_manager_activate_connection (priv->manager,
717                                                      best_connection,
718                                                      specific_object,
719                                                      data->device,
720                                                      subject,
721                                                      &error)) {
722                         _LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: (%d) %s",
723                                nm_settings_connection_get_id (best_connection),
724                                error->code,
725                                error->message);
726                         g_error_free (error);
727                 }
728                 g_object_unref (subject);
729         }
730
731  out:
732         activate_data_free (data);
733         return G_SOURCE_REMOVE;
734 }
735
736 static ActivateData *
737 find_pending_activation (GSList *list, NMDevice *device)
738 {
739         GSList *iter;
740
741         for (iter = list; iter; iter = g_slist_next (iter)) {
742                 if (((ActivateData *) iter->data)->device == device)
743                         return iter->data;
744         }
745         return NULL;
746 }
747
748 /*****************************************************************************/
749
750 typedef struct {
751         NMDevice *device;
752         GSList *secondaries;
753 } PendingSecondaryData;
754
755 static PendingSecondaryData *
756 pending_secondary_data_new (NMDevice *device, GSList *secondaries)
757 {
758         PendingSecondaryData *data;
759
760         data = g_malloc0 (sizeof (PendingSecondaryData));
761         data->device = g_object_ref (device);
762         data->secondaries = secondaries;
763         return data;
764 }
765
766 static void
767 pending_secondary_data_free (PendingSecondaryData *data)
768 {
769         g_object_unref (data->device);
770         g_slist_free_full (data->secondaries, g_object_unref);
771         memset (data, 0, sizeof (*data));
772         g_free (data);
773 }
774
775 static void
776 process_secondaries (NMPolicy *policy,
777                      NMActiveConnection *active,
778                      gboolean connected)
779 {
780         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
781         GSList *iter, *iter2, *next, *next2;
782
783         /* Loop through devices waiting for secondary connections to activate */
784         for (iter = priv->pending_secondaries; iter; iter = next) {
785                 PendingSecondaryData *secondary_data = (PendingSecondaryData *) iter->data;
786                 NMDevice *item_device = secondary_data->device;
787
788                 next = g_slist_next (iter);
789
790                 /* Look for 'active' in each device's secondary connections list */
791                 for (iter2 = secondary_data->secondaries; iter2; iter2 = next2) {
792                         NMActiveConnection *secondary_active = NM_ACTIVE_CONNECTION (iter2->data);
793
794                         next2 = g_slist_next (iter2);
795
796                         if (active != secondary_active)
797                                 continue;
798
799                         if (connected) {
800                                 _LOGD (LOGD_DEVICE, "secondary connection '%s' succeeded; active path '%s'",
801                                        nm_active_connection_get_settings_connection_id (active),
802                                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)));
803
804                                 /* Secondary connection activated */
805                                 secondary_data->secondaries = g_slist_remove (secondary_data->secondaries, secondary_active);
806                                 g_object_unref (secondary_active);
807                                 if (!secondary_data->secondaries) {
808                                         /* No secondary UUID remained -> remove the secondary data item */
809                                         priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data);
810                                         pending_secondary_data_free (secondary_data);
811                                         if (nm_device_get_state (item_device) == NM_DEVICE_STATE_SECONDARIES)
812                                                 nm_device_state_changed (item_device, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
813                                         break;
814                                 }
815                         } else {
816                                 _LOGD (LOGD_DEVICE, "secondary connection '%s' failed; active path '%s'",
817                                        nm_active_connection_get_settings_connection_id (active),
818                                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)));
819
820                                 /* Secondary connection failed -> do not watch other connections */
821                                 priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data);
822                                 pending_secondary_data_free (secondary_data);
823                                 if (   nm_device_get_state (item_device) == NM_DEVICE_STATE_SECONDARIES
824                                     || nm_device_get_state (item_device) == NM_DEVICE_STATE_ACTIVATED)
825                                         nm_device_state_changed (item_device, NM_DEVICE_STATE_FAILED,
826                                                                               NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED);
827                                 break;
828                         }
829                 }
830         }
831 }
832
833 static void
834 global_state_changed (NMManager *manager, NMState state, gpointer user_data)
835 {
836 }
837
838 static void
839 hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
840 {
841         update_system_hostname ((NMPolicy *) user_data, NULL, NULL);
842 }
843
844 static void
845 reset_autoconnect_all (NMPolicy *policy, NMDevice *device)
846 {
847         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
848         GSList *connections, *iter;
849
850         if (device) {
851                 _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections on %s",
852                        nm_device_get_iface (device));
853         } else
854                 _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections");
855
856         connections = nm_settings_get_connections (priv->settings);
857         for (iter = connections; iter; iter = g_slist_next (iter)) {
858                 if (!device || nm_device_check_connection_compatible (device, iter->data)) {
859                         nm_settings_connection_reset_autoconnect_retries (iter->data);
860                         nm_settings_connection_set_autoconnect_blocked_reason (iter->data, NM_DEVICE_STATE_REASON_NONE);
861                 }
862         }
863         g_slist_free (connections);
864 }
865
866 static void
867 reset_autoconnect_for_failed_secrets (NMPolicy *policy)
868 {
869         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
870         GSList *connections, *iter;
871
872         _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections with failed secrets");
873
874         connections = nm_settings_get_connections (priv->settings);
875         for (iter = connections; iter; iter = g_slist_next (iter)) {
876                 NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
877
878                 if (nm_settings_connection_get_autoconnect_blocked_reason (connection) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
879                         nm_settings_connection_reset_autoconnect_retries (connection);
880                         nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
881                 }
882         }
883         g_slist_free (connections);
884 }
885
886 static void
887 block_autoconnect_for_device (NMPolicy *policy, NMDevice *device)
888 {
889         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
890         GSList *connections, *iter;
891
892         _LOGD (LOGD_DEVICE, "blocking autoconnect for all connections on %s",
893                nm_device_get_iface (device));
894
895         /* NMDevice keeps its own autoconnect-able-ness state; we only need to
896          * explicitly block connections for software devices, where the NMDevice
897          * might be destroyed and recreated later.
898          */
899         if (!nm_device_is_software (device))
900                 return;
901
902         connections = nm_settings_get_connections (priv->settings);
903         for (iter = connections; iter; iter = g_slist_next (iter)) {
904                 if (nm_device_check_connection_compatible (device, iter->data)) {
905                         nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data),
906                                                                                NM_DEVICE_STATE_REASON_USER_REQUESTED);
907                 }
908         }
909 }
910
911 static void
912 sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
913 {
914         NMPolicy *policy = user_data;
915         gboolean sleeping = FALSE, enabled = FALSE;
916
917         g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
918         g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL);
919
920         /* Reset retries on all connections so they'll checked on wakeup */
921         if (sleeping || !enabled)
922                 reset_autoconnect_all (policy, NULL);
923 }
924
925 static void
926 schedule_activate_check (NMPolicy *policy, NMDevice *device)
927 {
928         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
929         ActivateData *data;
930         const GSList *active_connections, *iter;
931
932         if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP)
933                 return;
934
935         if (!nm_device_get_enabled (device))
936                 return;
937
938         if (!nm_device_autoconnect_allowed (device))
939                 return;
940
941         if (find_pending_activation (priv->pending_activation_checks, device))
942                 return;
943
944         active_connections = nm_manager_get_active_connections (priv->manager);
945         for (iter = active_connections; iter; iter = iter->next) {
946                 if (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (iter->data)) == device)
947                         return;
948         }
949
950         nm_device_add_pending_action (device, "autoactivate", TRUE);
951
952         data = g_malloc0 (sizeof (ActivateData));
953         data->policy = policy;
954         data->device = g_object_ref (device);
955         data->autoactivate_id = g_idle_add (auto_activate_device, data);
956         priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
957 }
958
959 static void
960 clear_pending_activate_check (NMPolicy *policy, NMDevice *device)
961 {
962         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
963         ActivateData *data;
964
965         data = find_pending_activation (priv->pending_activation_checks, device);
966         if (data && data->autoactivate_id)
967                 activate_data_free (data);
968 }
969
970 static gboolean
971 reset_connections_retries (gpointer user_data)
972 {
973         NMPolicy *policy = (NMPolicy *) user_data;
974         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
975         GSList *connections, *iter;
976         gint32 con_stamp, min_stamp, now;
977         gboolean changed = FALSE;
978
979         priv->reset_retries_id = 0;
980
981         min_stamp = 0;
982         now = nm_utils_get_monotonic_timestamp_s ();
983         connections = nm_settings_get_connections (priv->settings);
984         for (iter = connections; iter; iter = g_slist_next (iter)) {
985                 NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (iter->data);
986
987                 con_stamp = nm_settings_connection_get_autoconnect_retry_time (connection);
988                 if (con_stamp == 0)
989                         continue;
990
991                 if (con_stamp <= now) {
992                         nm_settings_connection_reset_autoconnect_retries (connection);
993                         changed = TRUE;
994                 } else if (min_stamp == 0 || min_stamp > con_stamp)
995                         min_stamp = con_stamp;
996         }
997         g_slist_free (connections);
998
999         /* Schedule the handler again if there are some stamps left */
1000         if (min_stamp != 0)
1001                 priv->reset_retries_id = g_timeout_add_seconds (min_stamp - now, reset_connections_retries, policy);
1002
1003         /* If anything changed, try to activate the newly re-enabled connections */
1004         if (changed)
1005                 schedule_activate_all (policy);
1006
1007         return FALSE;
1008 }
1009
1010 static void schedule_activate_all (NMPolicy *policy);
1011
1012 static void
1013 activate_slave_connections (NMPolicy *policy, NMDevice *device)
1014 {
1015         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1016         const char *master_device, *master_uuid_settings = NULL, *master_uuid_applied = NULL;
1017         GSList *connections, *iter;
1018         NMActRequest *req;
1019
1020         master_device = nm_device_get_iface (device);
1021         g_assert (master_device);
1022
1023         req = nm_device_get_act_request (device);
1024         if (req) {
1025                 NMConnection *con;
1026
1027                 con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req));
1028                 if (con)
1029                         master_uuid_applied = nm_connection_get_uuid (con);
1030                 con = NM_CONNECTION (nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req)));
1031                 if (con) {
1032                         master_uuid_settings = nm_connection_get_uuid (con);
1033                         if (!g_strcmp0 (master_uuid_settings, master_uuid_applied))
1034                                 master_uuid_settings = NULL;
1035                 }
1036         }
1037
1038         connections = nm_settings_get_connections (priv->settings);
1039         for (iter = connections; iter; iter = g_slist_next (iter)) {
1040                 NMConnection *slave;
1041                 NMSettingConnection *s_slave_con;
1042                 const char *slave_master;
1043
1044                 slave = NM_CONNECTION (iter->data);
1045                 g_assert (slave);
1046
1047                 s_slave_con = nm_connection_get_setting_connection (slave);
1048                 g_assert (s_slave_con);
1049                 slave_master = nm_setting_connection_get_master (s_slave_con);
1050                 if (!slave_master)
1051                         continue;
1052
1053                 if (   !g_strcmp0 (slave_master, master_device)
1054                     || !g_strcmp0 (slave_master, master_uuid_applied)
1055                     || !g_strcmp0 (slave_master, master_uuid_settings))
1056                         nm_settings_connection_reset_autoconnect_retries (NM_SETTINGS_CONNECTION (slave));
1057         }
1058
1059         g_slist_free (connections);
1060
1061         schedule_activate_all (policy);
1062 }
1063
1064 static gboolean
1065 activate_secondary_connections (NMPolicy *policy,
1066                                 NMConnection *connection,
1067                                 NMDevice *device)
1068 {
1069         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1070         NMSettingConnection *s_con;
1071         NMSettingsConnection *settings_con;
1072         NMActiveConnection *ac;
1073         PendingSecondaryData *secondary_data;
1074         GSList *secondary_ac_list = NULL;
1075         GError *error = NULL;
1076         guint32 i;
1077         gboolean success = TRUE;
1078
1079         s_con = nm_connection_get_setting_connection (connection);
1080         g_assert (s_con);
1081
1082         for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) {
1083                 const char *sec_uuid = nm_setting_connection_get_secondary (s_con, i);
1084                 NMActRequest *req;
1085
1086                 settings_con = nm_settings_get_connection_by_uuid (priv->settings, sec_uuid);
1087                 if (!settings_con) {
1088                         _LOGW (LOGD_DEVICE, "secondary connection '%s' auto-activation failed: The connection doesn't exist.",
1089                                sec_uuid);
1090                         success = FALSE;
1091                         break;
1092                 }
1093                 if (!nm_connection_is_type (NM_CONNECTION (settings_con), NM_SETTING_VPN_SETTING_NAME)) {
1094                         _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: The connection is not a VPN.",
1095                                nm_settings_connection_get_id (settings_con), sec_uuid);
1096                         success = FALSE;
1097                         break;
1098                 }
1099
1100                 req = nm_device_get_act_request (device);
1101                 g_assert (req);
1102
1103                 _LOGD (LOGD_DEVICE, "activating secondary connection '%s (%s)' for base connection '%s (%s)'",
1104                        nm_settings_connection_get_id (settings_con), sec_uuid,
1105                        nm_connection_get_id (connection), nm_connection_get_uuid (connection));
1106                 ac = nm_manager_activate_connection (priv->manager,
1107                                                      settings_con,
1108                                                      nm_exported_object_get_path (NM_EXPORTED_OBJECT (req)),
1109                                                      device,
1110                                                      nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)),
1111                                                      &error);
1112                 if (ac)
1113                         secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac));
1114                 else {
1115                         _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: (%d) %s",
1116                                nm_settings_connection_get_id (settings_con), sec_uuid,
1117                                error->code,
1118                                error->message);
1119                         g_clear_error (&error);
1120                         success = FALSE;
1121                         break;
1122                 }
1123         }
1124
1125         if (success && secondary_ac_list != NULL) {
1126                 secondary_data = pending_secondary_data_new (device, secondary_ac_list);
1127                 priv->pending_secondaries = g_slist_append (priv->pending_secondaries, secondary_data);
1128         } else
1129                 g_slist_free_full (secondary_ac_list, g_object_unref);
1130
1131         return success;
1132 }
1133
1134 static void
1135 device_state_changed (NMDevice *device,
1136                       NMDeviceState new_state,
1137                       NMDeviceState old_state,
1138                       NMDeviceStateReason reason,
1139                       gpointer user_data)
1140 {
1141         NMPolicy *policy = (NMPolicy *) user_data;
1142         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1143
1144         NMSettingsConnection *connection = nm_device_get_settings_connection (device);
1145
1146         const char *ip_iface = nm_device_get_ip_iface (device);
1147         NMIP4Config *ip4_config;
1148         NMIP6Config *ip6_config;
1149         NMSettingConnection *s_con = NULL;
1150
1151         switch (new_state) {
1152         case NM_DEVICE_STATE_FAILED:
1153                 /* Mark the connection invalid if it failed during activation so that
1154                  * it doesn't get automatically chosen over and over and over again.
1155                  */
1156                 if (   connection
1157                     && old_state >= NM_DEVICE_STATE_PREPARE
1158                     && old_state <= NM_DEVICE_STATE_ACTIVATED) {
1159                         guint32 tries = nm_settings_connection_get_autoconnect_retries (connection);
1160
1161                         if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
1162                                 _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets",
1163                                        nm_settings_connection_get_id (connection));
1164
1165                                 nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NO_SECRETS);
1166                         } else if (tries > 0) {
1167                                 _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left",
1168                                        nm_settings_connection_get_id (connection), tries);
1169                                 nm_settings_connection_set_autoconnect_retries (connection, tries - 1);
1170                         }
1171
1172                         if (nm_settings_connection_get_autoconnect_retries (connection) == 0) {
1173                                 _LOGI (LOGD_DEVICE, "disabling autoconnect for connection '%s'.",
1174                                        nm_settings_connection_get_id (connection));
1175                                 /* Schedule a handler to reset retries count */
1176                                 if (!priv->reset_retries_id) {
1177                                         gint32 retry_time = nm_settings_connection_get_autoconnect_retry_time (connection);
1178
1179                                         g_warn_if_fail (retry_time != 0);
1180                                         priv->reset_retries_id = g_timeout_add_seconds (MAX (0, retry_time - nm_utils_get_monotonic_timestamp_s ()), reset_connections_retries, policy);
1181                                 }
1182                         }
1183                         nm_connection_clear_secrets (NM_CONNECTION (connection));
1184                 }
1185                 break;
1186         case NM_DEVICE_STATE_ACTIVATED:
1187                 if (connection) {
1188                         /* Reset auto retries back to default since connection was successful */
1189                         nm_settings_connection_reset_autoconnect_retries (connection);
1190
1191                         /* And clear secrets so they will always be requested from the
1192                          * settings service when the next connection is made.
1193                          */
1194
1195                         nm_connection_clear_secrets (NM_CONNECTION (connection));
1196                 }
1197
1198                 /* Add device's new IPv4 and IPv6 configs to DNS */
1199
1200                 nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1201
1202                 ip4_config = nm_device_get_ip4_config (device);
1203                 if (ip4_config)
1204                         nm_dns_manager_add_ip4_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1205                 ip6_config = nm_device_get_ip6_config (device);
1206                 if (ip6_config)
1207                         nm_dns_manager_add_ip6_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1208
1209                 update_routing_and_dns (policy, FALSE);
1210
1211                 nm_dns_manager_end_updates (priv->dns_manager, __func__);
1212                 break;
1213         case NM_DEVICE_STATE_UNMANAGED:
1214         case NM_DEVICE_STATE_UNAVAILABLE:
1215                 if (old_state > NM_DEVICE_STATE_DISCONNECTED)
1216                         update_routing_and_dns (policy, FALSE);
1217                 break;
1218         case NM_DEVICE_STATE_DEACTIVATING:
1219                 if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
1220                         if (!nm_device_get_autoconnect (device)) {
1221                                 /* The device was disconnected; block all connections on it */
1222                                 block_autoconnect_for_device (policy, device);
1223                         } else {
1224                                 if (connection) {
1225                                         /* The connection was deactivated, so block just this connection */
1226                                         _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s' by user request",
1227                                                nm_settings_connection_get_id (connection));
1228                                         nm_settings_connection_set_autoconnect_blocked_reason (connection,
1229                                                                                                NM_DEVICE_STATE_REASON_USER_REQUESTED);
1230                                 }
1231                         }
1232                 }
1233                 break;
1234         case NM_DEVICE_STATE_DISCONNECTED:
1235                 /* Reset retry counts for a device's connections when carrier on; if cable
1236                  * was unplugged and plugged in again, we should try to reconnect.
1237                  */
1238                 if (reason == NM_DEVICE_STATE_REASON_CARRIER && old_state == NM_DEVICE_STATE_UNAVAILABLE)
1239                         reset_autoconnect_all (policy, device);
1240
1241                 if (old_state > NM_DEVICE_STATE_DISCONNECTED)
1242                         update_routing_and_dns (policy, FALSE);
1243
1244                 /* Device is now available for auto-activation */
1245                 schedule_activate_check (policy, device);
1246                 break;
1247
1248         case NM_DEVICE_STATE_PREPARE:
1249                 /* Reset auto-connect retries of all slaves and schedule them for
1250                  * activation. */
1251                 activate_slave_connections (policy, device);
1252                 break;
1253         case NM_DEVICE_STATE_IP_CONFIG:
1254                 /* We must have secrets if we got here. */
1255                 if (connection)
1256                         nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NONE);
1257                 break;
1258         case NM_DEVICE_STATE_SECONDARIES:
1259                 if (connection)
1260                         s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
1261                 if (s_con && nm_setting_connection_get_num_secondaries (s_con) > 0) {
1262                         /* Make routes and DNS up-to-date before activating dependent connections */
1263                         update_routing_and_dns (policy, FALSE);
1264
1265                         /* Activate secondary (VPN) connections */
1266                         if (!activate_secondary_connections (policy, NM_CONNECTION (connection), device))
1267                                 nm_device_queue_state (device, NM_DEVICE_STATE_FAILED,
1268                                                        NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED);
1269                 } else
1270                         nm_device_queue_state (device, NM_DEVICE_STATE_ACTIVATED,
1271                                                NM_DEVICE_STATE_REASON_NONE);
1272                 break;
1273
1274         default:
1275                 break;
1276         }
1277
1278         check_activating_devices (policy);
1279 }
1280
1281 static void
1282 device_ip4_config_changed (NMDevice *device,
1283                            NMIP4Config *new_config,
1284                            NMIP4Config *old_config,
1285                            gpointer user_data)
1286 {
1287         NMPolicy *policy = user_data;
1288         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1289         const char *ip_iface = nm_device_get_ip_iface (device);
1290
1291         nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1292
1293         /* Ignore IP config changes while the device is activating, because we'll
1294          * catch all the changes when the device moves to ACTIVATED state.
1295          * Prevents unecessary changes to DNS information.
1296          */
1297         if (!nm_device_is_activating (device)) {
1298                 if (old_config != new_config) {
1299                         if (old_config)
1300                                 nm_dns_manager_remove_ip4_config (priv->dns_manager, old_config);
1301                         if (new_config)
1302                                 nm_dns_manager_add_ip4_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1303                 }
1304                 update_ip4_dns (policy, priv->dns_manager);
1305                 update_ip4_routing (policy, TRUE);
1306         } else {
1307                 /* Old configs get removed immediately */
1308                 if (old_config)
1309                         nm_dns_manager_remove_ip4_config (priv->dns_manager, old_config);
1310         }
1311
1312         nm_dns_manager_end_updates (priv->dns_manager, __func__);
1313 }
1314
1315 static void
1316 device_ip6_config_changed (NMDevice *device,
1317                            NMIP6Config *new_config,
1318                            NMIP6Config *old_config,
1319                            gpointer user_data)
1320 {
1321         NMPolicy *policy = user_data;
1322         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1323         const char *ip_iface = nm_device_get_ip_iface (device);
1324
1325         nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1326
1327         /* Ignore IP config changes while the device is activating, because we'll
1328          * catch all the changes when the device moves to ACTIVATED state.
1329          * Prevents unecessary changes to DNS information.
1330          */
1331         if (!nm_device_is_activating (device)) {
1332                 if (old_config != new_config) {
1333                         if (old_config)
1334                                 nm_dns_manager_remove_ip6_config (priv->dns_manager, old_config);
1335                         if (new_config)
1336                                 nm_dns_manager_add_ip6_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1337                 }
1338                 update_ip6_dns (policy, priv->dns_manager);
1339                 update_ip6_routing (policy, TRUE);
1340         } else {
1341                 /* Old configs get removed immediately */
1342                 if (old_config)
1343                         nm_dns_manager_remove_ip6_config (priv->dns_manager, old_config);
1344         }
1345
1346         nm_dns_manager_end_updates (priv->dns_manager, __func__);
1347 }
1348
1349 static void
1350 device_autoconnect_changed (NMDevice *device,
1351                             GParamSpec *pspec,
1352                             gpointer user_data)
1353 {
1354         if (nm_device_autoconnect_allowed (device))
1355                 schedule_activate_check ((NMPolicy *) user_data, device);
1356 }
1357
1358 static void
1359 device_recheck_auto_activate (NMDevice *device, gpointer user_data)
1360 {
1361         schedule_activate_check (NM_POLICY (user_data), device);
1362 }
1363
1364 typedef struct {
1365         gulong id;
1366         NMDevice *device;
1367 } DeviceSignalId;
1368
1369 static void
1370 _connect_device_signal (NMPolicy *policy,
1371                         NMDevice *device,
1372                         const char *name,
1373                         gpointer callback,
1374                         gboolean after)
1375 {
1376         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1377         DeviceSignalId *data;
1378
1379         data = g_slice_new0 (DeviceSignalId);
1380         g_assert (data);
1381         if (after)
1382                 data->id = g_signal_connect_after (device, name, callback, policy);
1383         else
1384                 data->id = g_signal_connect (device, name, callback, policy);
1385         data->device = device;
1386         priv->dev_ids = g_slist_prepend (priv->dev_ids, data);
1387 }
1388
1389 static void
1390 device_added (NMManager *manager, NMDevice *device, gpointer user_data)
1391 {
1392         NMPolicy *policy = (NMPolicy *) user_data;
1393
1394         /* Connect state-changed with _after, so that the handler is invoked after other handlers. */
1395         _connect_device_signal (policy, device, NM_DEVICE_STATE_CHANGED, device_state_changed, TRUE);
1396         _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed, FALSE);
1397         _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed, FALSE);
1398         _connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed, FALSE);
1399         _connect_device_signal (policy, device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, device_recheck_auto_activate, FALSE);
1400 }
1401
1402 static void
1403 device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
1404 {
1405         NMPolicy *policy = (NMPolicy *) user_data;
1406         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1407         GSList *iter;
1408
1409         /* Clear any idle callbacks for this device */
1410         clear_pending_activate_check (policy, device);
1411
1412         /* Clear any signal handlers for this device */
1413         iter = priv->dev_ids;
1414         while (iter) {
1415                 DeviceSignalId *data = iter->data;
1416                 GSList *next = g_slist_next (iter);
1417
1418                 if (data->device == device) {
1419                         g_signal_handler_disconnect (data->device, data->id);
1420                         g_slice_free (DeviceSignalId, data);
1421                         priv->dev_ids = g_slist_delete_link (priv->dev_ids, iter);
1422                 }
1423                 iter = next;
1424         }
1425
1426         /* Don't update routing and DNS here as we've already handled that
1427          * for devices that need it when the device's state changed to UNMANAGED.
1428          */
1429 }
1430
1431 /**************************************************************************/
1432
1433 static void
1434 vpn_connection_activated (NMPolicy *policy, NMVpnConnection *vpn)
1435 {
1436         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1437         NMIP4Config *ip4_config;
1438         NMIP6Config *ip6_config;
1439         const char *ip_iface;
1440
1441         nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1442
1443         ip_iface = nm_vpn_connection_get_ip_iface (vpn);
1444
1445         /* Add the VPN connection's IP configs from DNS */
1446
1447         ip4_config = nm_vpn_connection_get_ip4_config (vpn);
1448         if (ip4_config)
1449                 nm_dns_manager_add_ip4_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_VPN);
1450
1451         ip6_config = nm_vpn_connection_get_ip6_config (vpn);
1452         if (ip6_config)
1453                 nm_dns_manager_add_ip6_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_VPN);
1454
1455         update_routing_and_dns (policy, TRUE);
1456
1457         nm_dns_manager_end_updates (priv->dns_manager, __func__);
1458 }
1459
1460 static void
1461 vpn_connection_deactivated (NMPolicy *policy, NMVpnConnection *vpn)
1462 {
1463         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1464         NMIP4Config *ip4_config;
1465         NMIP6Config *ip6_config;
1466
1467         nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1468
1469         ip4_config = nm_vpn_connection_get_ip4_config (vpn);
1470         if (ip4_config) {
1471                 /* Remove the VPN connection's IP4 config from DNS */
1472                 nm_dns_manager_remove_ip4_config (priv->dns_manager, ip4_config);
1473         }
1474
1475         ip6_config = nm_vpn_connection_get_ip6_config (vpn);
1476         if (ip6_config) {
1477                 /* Remove the VPN connection's IP6 config from DNS */
1478                 nm_dns_manager_remove_ip6_config (priv->dns_manager, ip6_config);
1479         }
1480
1481         update_routing_and_dns (policy, TRUE);
1482
1483         nm_dns_manager_end_updates (priv->dns_manager, __func__);
1484 }
1485
1486 static void
1487 vpn_connection_state_changed (NMVpnConnection *vpn,
1488                               NMVpnConnectionState new_state,
1489                               NMVpnConnectionState old_state,
1490                               NMVpnConnectionStateReason reason,
1491                               NMPolicy *policy)
1492 {
1493         if (new_state == NM_VPN_CONNECTION_STATE_ACTIVATED)
1494                 vpn_connection_activated (policy, vpn);
1495         else if (new_state >= NM_VPN_CONNECTION_STATE_FAILED) {
1496                 /* Only clean up IP/DNS if the connection ever got past IP_CONFIG */
1497                 if (old_state >= NM_VPN_CONNECTION_STATE_IP_CONFIG_GET &&
1498                     old_state <= NM_VPN_CONNECTION_STATE_ACTIVATED)
1499                         vpn_connection_deactivated (policy, vpn);
1500         }
1501 }
1502
1503 static void
1504 vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *policy)
1505 {
1506         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1507         NMActiveConnection *ac = NM_ACTIVE_CONNECTION (vpn);
1508         NMSettingsConnection *connection = nm_active_connection_get_settings_connection (ac);
1509         GError *error = NULL;
1510
1511         /* Attempt to reconnect VPN connections that failed after being connected */
1512         if (!nm_manager_activate_connection (priv->manager,
1513                                              connection,
1514                                              NULL,
1515                                              NULL,
1516                                              nm_active_connection_get_subject (ac),
1517                                              &error)) {
1518                 _LOGW (LOGD_DEVICE, "VPN '%s' reconnect failed: %s",
1519                        nm_settings_connection_get_id (connection),
1520                        error->message ? error->message : "unknown");
1521                 g_clear_error (&error);
1522         }
1523 }
1524
1525 static void
1526 active_connection_state_changed (NMActiveConnection *active,
1527                                  GParamSpec *pspec,
1528                                  NMPolicy *policy)
1529 {
1530         NMActiveConnectionState state = nm_active_connection_get_state (active);
1531
1532         if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
1533                 process_secondaries (policy, active, TRUE);
1534         else if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
1535                 process_secondaries (policy, active, FALSE);
1536 }
1537
1538 static void
1539 active_connection_added (NMManager *manager,
1540                          NMActiveConnection *active,
1541                          gpointer user_data)
1542 {
1543         NMPolicy *policy = NM_POLICY (user_data);
1544
1545         if (NM_IS_VPN_CONNECTION (active)) {
1546                 g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED,
1547                                   G_CALLBACK (vpn_connection_state_changed),
1548                                   policy);
1549                 g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE,
1550                                   G_CALLBACK (vpn_connection_retry_after_failure),
1551                                   policy);
1552         }
1553
1554         g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE,
1555                           G_CALLBACK (active_connection_state_changed),
1556                           policy);
1557 }
1558
1559 static void
1560 active_connection_removed (NMManager *manager,
1561                            NMActiveConnection *active,
1562                            gpointer user_data)
1563 {
1564         NMPolicy *policy = NM_POLICY (user_data);
1565
1566         g_signal_handlers_disconnect_by_func (active,
1567                                               vpn_connection_state_changed,
1568                                               policy);
1569         g_signal_handlers_disconnect_by_func (active,
1570                                               vpn_connection_retry_after_failure,
1571                                               policy);
1572         g_signal_handlers_disconnect_by_func (active,
1573                                               active_connection_state_changed,
1574                                               policy);
1575 }
1576
1577 /**************************************************************************/
1578
1579 static void
1580 schedule_activate_all (NMPolicy *policy)
1581 {
1582         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1583         const GSList *iter;
1584
1585         for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter))
1586                 schedule_activate_check (policy, NM_DEVICE (iter->data));
1587 }
1588
1589 static void
1590 connection_added (NMSettings *settings,
1591                   NMSettingsConnection *connection,
1592                   gpointer user_data)
1593 {
1594         NMPolicy *policy = NM_POLICY (user_data);
1595
1596         schedule_activate_all (policy);
1597 }
1598
1599 static void
1600 firewall_started (NMFirewallManager *manager,
1601                   gpointer user_data)
1602 {
1603         NMPolicy *policy = (NMPolicy *) user_data;
1604         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1605         const GSList *iter;
1606
1607         /* add interface of each device to correct zone */
1608         for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter))
1609                 nm_device_update_firewall_zone (iter->data);
1610 }
1611
1612 static void
1613 dns_config_changed (NMDnsManager *dns_manager, gpointer user_data)
1614 {
1615         NMPolicy *policy = (NMPolicy *) user_data;
1616         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1617
1618         /* Restart a thread for reverse-DNS lookup after we are signalled that
1619          * DNS changed. Because the result from a previous run may not be right
1620          * (race in updating DNS and doing the reverse lookup).
1621          */
1622
1623         /* Stop a lookup thread if any. */
1624         if (priv->lookup_cancellable) {
1625                 g_cancellable_cancel (priv->lookup_cancellable);
1626                 g_clear_object (&priv->lookup_cancellable);
1627         }
1628
1629         /* Re-start the hostname lookup thread if we don't have hostname yet. */
1630         if (priv->lookup_addr) {
1631                 char *str = NULL;
1632
1633                 _LOGD (LOGD_DNS, "restarting reverse-lookup thread for address %s",
1634                        (str = g_inet_address_to_string (priv->lookup_addr)));
1635                 g_free (str);
1636
1637                 priv->lookup_cancellable = g_cancellable_new ();
1638                 g_resolver_lookup_by_address_async (priv->resolver,
1639                                                     priv->lookup_addr,
1640                                                     priv->lookup_cancellable,
1641                                                     lookup_callback, policy);
1642         }
1643 }
1644
1645 static void
1646 connection_updated (NMSettings *settings,
1647                     NMConnection *connection,
1648                     gpointer user_data)
1649 {
1650         schedule_activate_all ((NMPolicy *) user_data);
1651 }
1652
1653 static void
1654 connection_updated_by_user (NMSettings *settings,
1655                             NMSettingsConnection *connection,
1656                             gpointer user_data)
1657 {
1658         NMPolicy *policy = (NMPolicy *) user_data;
1659         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1660         const GSList *iter;
1661         NMDevice *device = NULL;
1662
1663         /* find device with given connection */
1664         for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) {
1665                 NMDevice *dev = NM_DEVICE (iter->data);
1666
1667                 if (nm_device_get_settings_connection (dev) == connection) {
1668                         device = dev;
1669                         break;
1670                 }
1671         }
1672
1673         if (device)
1674                 nm_device_reapply_settings_immediately (device);
1675
1676         /* Reset auto retries back to default since connection was updated */
1677         nm_settings_connection_reset_autoconnect_retries (connection);
1678 }
1679
1680 static void
1681 _deactivate_if_active (NMManager *manager, NMSettingsConnection *connection)
1682 {
1683         const GSList *active, *iter;
1684
1685         active = nm_manager_get_active_connections (manager);
1686         for (iter = active; iter; iter = g_slist_next (iter)) {
1687                 NMActiveConnection *ac = iter->data;
1688                 NMActiveConnectionState state = nm_active_connection_get_state (ac);
1689                 GError *error = NULL;
1690
1691                 if (nm_active_connection_get_settings_connection (ac) == connection &&
1692                     (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
1693                         if (!nm_manager_deactivate_connection (manager,
1694                                                                nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac)),
1695                                                                NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
1696                                                                &error)) {
1697                                 _LOGW (LOGD_DEVICE, "connection '%s' disappeared, but error deactivating it: (%d) %s",
1698                                        nm_settings_connection_get_id (connection),
1699                                        error ? error->code : -1,
1700                                        error ? error->message : "(unknown)");
1701                                 g_clear_error (&error);
1702                         }
1703                 }
1704         }
1705 }
1706
1707 static void
1708 connection_removed (NMSettings *settings,
1709                     NMSettingsConnection *connection,
1710                     gpointer user_data)
1711 {
1712         NMPolicy *policy = user_data;
1713         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1714
1715         _deactivate_if_active (priv->manager, connection);
1716 }
1717
1718 static void
1719 connection_visibility_changed (NMSettings *settings,
1720                                NMSettingsConnection *connection,
1721                                gpointer user_data)
1722 {
1723         NMPolicy *policy = user_data;
1724         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1725
1726         if (nm_settings_connection_is_visible (connection))
1727                 schedule_activate_all (policy);
1728         else
1729                 _deactivate_if_active (priv->manager, connection);
1730 }
1731
1732 static void
1733 secret_agent_registered (NMSettings *settings,
1734                          NMSecretAgent *agent,
1735                          gpointer user_data)
1736 {
1737         NMPolicy *policy = NM_POLICY (user_data);
1738
1739         /* The registered secret agent may provide some missing secrets. Thus we
1740          * reset retries count here and schedule activation, so that the
1741          * connections failed due to missing secrets may re-try auto-connection.
1742          */
1743         reset_autoconnect_for_failed_secrets (policy);
1744         schedule_activate_all (policy);
1745 }
1746
1747 NMDevice *
1748 nm_policy_get_default_ip4_device (NMPolicy *policy)
1749 {
1750         return NM_POLICY_GET_PRIVATE (policy)->default_device4;
1751 }
1752
1753 NMDevice *
1754 nm_policy_get_default_ip6_device (NMPolicy *policy)
1755 {
1756         return NM_POLICY_GET_PRIVATE (policy)->default_device6;
1757 }
1758
1759 NMDevice *
1760 nm_policy_get_activating_ip4_device (NMPolicy *policy)
1761 {
1762         return NM_POLICY_GET_PRIVATE (policy)->activating_device4;
1763 }
1764
1765 NMDevice *
1766 nm_policy_get_activating_ip6_device (NMPolicy *policy)
1767 {
1768         return NM_POLICY_GET_PRIVATE (policy)->activating_device6;
1769 }
1770
1771 /*****************************************************************************/
1772
1773 static void
1774 get_property (GObject *object, guint prop_id,
1775               GValue *value, GParamSpec *pspec)
1776 {
1777         NMPolicy *policy = NM_POLICY (object);
1778         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1779
1780         switch (prop_id) {
1781         case PROP_DEFAULT_IP4_DEVICE:
1782                 g_value_set_object (value, priv->default_device4);
1783                 break;
1784         case PROP_DEFAULT_IP6_DEVICE:
1785                 g_value_set_object (value, priv->default_device6);
1786                 break;
1787         case PROP_ACTIVATING_IP4_DEVICE:
1788                 g_value_set_object (value, priv->activating_device4);
1789                 break;
1790         case PROP_ACTIVATING_IP6_DEVICE:
1791                 g_value_set_object (value, priv->activating_device6);
1792                 break;
1793         default:
1794                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1795                 break;
1796         }
1797 }
1798
1799 /*****************************************************************************/
1800
1801 static void
1802 _connect_manager_signal (NMPolicy *policy, const char *name, gpointer callback)
1803 {
1804         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1805         gulong id;
1806
1807         id = g_signal_connect (priv->manager, name, callback, policy);
1808         priv->manager_ids = g_slist_prepend (priv->manager_ids, (gpointer) id);
1809 }
1810
1811 static void
1812 _connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback)
1813 {
1814         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1815         gulong id;
1816
1817         id = g_signal_connect (priv->settings, name, callback, policy);
1818         priv->settings_ids = g_slist_prepend (priv->settings_ids, (gpointer) id);
1819 }
1820
1821 static void
1822 nm_policy_init (NMPolicy *policy)
1823 {
1824 }
1825
1826 NMPolicy *
1827 nm_policy_new (NMManager *manager, NMSettings *settings)
1828 {
1829         NMPolicy *policy;
1830         NMPolicyPrivate *priv;
1831         static gboolean initialized = FALSE;
1832         char hostname[HOST_NAME_MAX + 2];
1833
1834         g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
1835         g_return_val_if_fail (initialized == FALSE, NULL);
1836
1837         policy = g_object_new (NM_TYPE_POLICY, NULL);
1838         priv = NM_POLICY_GET_PRIVATE (policy);
1839         priv->manager = manager;
1840         priv->settings = g_object_ref (settings);
1841         priv->update_state_id = 0;
1842
1843         /* Grab hostname on startup and use that if nothing provides one */
1844         memset (hostname, 0, sizeof (hostname));
1845         if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) {
1846                 /* only cache it if it's a valid hostname */
1847                 if (*hostname && nm_utils_is_specific_hostname (hostname))
1848                         priv->orig_hostname = g_strdup (hostname);
1849         }
1850
1851         priv->firewall_manager = g_object_ref (nm_firewall_manager_get ());
1852
1853         priv->fw_started_id = g_signal_connect (priv->firewall_manager, "started",
1854                                                 G_CALLBACK (firewall_started), policy);
1855
1856         priv->dns_manager = g_object_ref (nm_dns_manager_get ());
1857         nm_dns_manager_set_initial_hostname (priv->dns_manager, priv->orig_hostname);
1858         priv->config_changed_id = g_signal_connect (priv->dns_manager, "config-changed",
1859                                                     G_CALLBACK (dns_config_changed), policy);
1860
1861         priv->resolver = g_resolver_get_default ();
1862
1863         _connect_manager_signal (policy, NM_MANAGER_STATE_CHANGED, global_state_changed);
1864         _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed);
1865         _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed);
1866         _connect_manager_signal (policy, "notify::" NM_MANAGER_NETWORKING_ENABLED, sleeping_changed);
1867         _connect_manager_signal (policy, "internal-device-added", device_added);
1868         _connect_manager_signal (policy, "internal-device-removed", device_removed);
1869         _connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_ADDED, active_connection_added);
1870         _connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_REMOVED, active_connection_removed);
1871
1872         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
1873         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
1874         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER, connection_updated_by_user);
1875         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed);
1876         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
1877                                   connection_visibility_changed);
1878         _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_AGENT_REGISTERED, secret_agent_registered);
1879
1880         initialized = TRUE;
1881         return policy;
1882 }
1883
1884 static void
1885 dispose (GObject *object)
1886 {
1887         NMPolicy *policy = NM_POLICY (object);
1888         NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1889         const GSList *connections, *iter;
1890
1891         /* Tell any existing hostname lookup thread to die. */
1892         if (priv->lookup_cancellable) {
1893                 g_cancellable_cancel (priv->lookup_cancellable);
1894                 g_clear_object (&priv->lookup_cancellable);
1895         }
1896         g_clear_object (&priv->lookup_addr);
1897         g_clear_object (&priv->resolver);
1898
1899         while (priv->pending_activation_checks)
1900                 activate_data_free (priv->pending_activation_checks->data);
1901
1902         g_slist_free_full (priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free);
1903         priv->pending_secondaries = NULL;
1904
1905         if (priv->firewall_manager) {
1906                 g_assert (priv->fw_started_id);
1907                 g_signal_handler_disconnect (priv->firewall_manager, priv->fw_started_id);
1908                 priv->fw_started_id = 0;
1909                 g_clear_object (&priv->firewall_manager);
1910         }
1911
1912         if (priv->dns_manager) {
1913                 g_signal_handler_disconnect (priv->dns_manager, priv->config_changed_id);
1914                 g_clear_object (&priv->dns_manager);
1915         }
1916
1917         for (iter = priv->manager_ids; iter; iter = g_slist_next (iter))
1918                 g_signal_handler_disconnect (priv->manager, (gulong) iter->data);
1919         g_clear_pointer (&priv->manager_ids, g_slist_free);
1920
1921         for (iter = priv->settings_ids; iter; iter = g_slist_next (iter))
1922                 g_signal_handler_disconnect (priv->settings, (gulong) iter->data);
1923         g_clear_pointer (&priv->settings_ids, g_slist_free);
1924
1925         for (iter = priv->dev_ids; iter; iter = g_slist_next (iter)) {
1926                 DeviceSignalId *data = iter->data;
1927
1928                 g_signal_handler_disconnect (data->device, data->id);
1929                 g_slice_free (DeviceSignalId, data);
1930         }
1931         g_clear_pointer (&priv->dev_ids, g_slist_free);
1932
1933         /* The manager should have disposed of ActiveConnections already, which
1934          * will have called active_connection_removed() and thus we don't need
1935          * to clean anything up.  Assert that this is TRUE.
1936          */
1937         connections = nm_manager_get_active_connections (priv->manager);
1938         g_assert (connections == NULL);
1939
1940         nm_clear_g_source (&priv->reset_retries_id);
1941
1942         g_clear_pointer (&priv->orig_hostname, g_free);
1943         g_clear_pointer (&priv->cur_hostname, g_free);
1944
1945         g_clear_object (&priv->settings);
1946
1947         G_OBJECT_CLASS (nm_policy_parent_class)->dispose (object);
1948 }
1949
1950 static void
1951 nm_policy_class_init (NMPolicyClass *policy_class)
1952 {
1953         GObjectClass *object_class = G_OBJECT_CLASS (policy_class);
1954
1955         g_type_class_add_private (policy_class, sizeof (NMPolicyPrivate));
1956
1957         object_class->get_property = get_property;
1958         object_class->dispose = dispose;
1959
1960         obj_properties[PROP_DEFAULT_IP4_DEVICE] =
1961             g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE, "", "",
1962                                  NM_TYPE_DEVICE,
1963                                  G_PARAM_READABLE |
1964                                  G_PARAM_STATIC_STRINGS);
1965         obj_properties[PROP_DEFAULT_IP6_DEVICE] =
1966             g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE, "", "",
1967                                  NM_TYPE_DEVICE,
1968                                  G_PARAM_READABLE |
1969                                  G_PARAM_STATIC_STRINGS);
1970         obj_properties[PROP_ACTIVATING_IP4_DEVICE] =
1971             g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE, "", "",
1972                                  NM_TYPE_DEVICE,
1973                                  G_PARAM_READABLE |
1974                                  G_PARAM_STATIC_STRINGS);
1975         obj_properties[PROP_ACTIVATING_IP6_DEVICE] =
1976             g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE, "", "",
1977                                  NM_TYPE_DEVICE,
1978                                  G_PARAM_READABLE |
1979                                  G_PARAM_STATIC_STRINGS);
1980         g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
1981 }