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