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