1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Copyright (C) 2007 - 2009 Novell, Inc.
19 * Copyright (C) 2007 - 2012 Red Hat, Inc.
20 */
21
22 #include <config.h>
23
24 #include <stdlib.h>
25 #include <netinet/ether.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <dbus/dbus-glib-lowlevel.h>
33 #include <dbus/dbus-glib.h>
34 #include <gio/gio.h>
35 #include <glib/gi18n.h>
36
37 #include "nm-glib-compat.h"
38 #include "nm-manager.h"
39 #include "nm-logging.h"
40 #include "nm-dbus-manager.h"
41 #include "nm-vpn-manager.h"
42 #include "nm-modem-manager.h"
43 #include "nm-device-bt.h"
44 #include "nm-device.h"
45 #include "nm-device-ethernet.h"
46 #include "nm-device-wifi.h"
47 #include "nm-device-olpc-mesh.h"
48 #include "nm-device-modem.h"
49 #include "nm-device-infiniband.h"
50 #include "nm-device-bond.h"
51 #include "nm-device-team.h"
52 #include "nm-device-bridge.h"
53 #include "nm-device-vlan.h"
54 #include "nm-device-adsl.h"
55 #include "nm-device-generic.h"
56 #include "nm-device-veth.h"
57 #include "nm-device-tun.h"
58 #include "nm-device-macvlan.h"
59 #include "nm-device-gre.h"
60 #include "nm-setting-private.h"
61 #include "nm-setting-bluetooth.h"
62 #include "nm-setting-connection.h"
63 #include "nm-setting-wireless.h"
64 #include "nm-setting-vpn.h"
65 #include "nm-dbus-glib-types.h"
66 #include "nm-platform.h"
67 #include "nm-atm-manager.h"
68 #include "nm-rfkill-manager.h"
69 #include "nm-hostname-provider.h"
70 #include "nm-bluez-manager.h"
71 #include "nm-bluez-common.h"
72 #include "nm-settings.h"
73 #include "nm-settings-connection.h"
74 #include "nm-manager-auth.h"
75 #include "NetworkManagerUtils.h"
76 #include "nm-utils.h"
77 #include "nm-device-factory.h"
78 #include "nm-enum-types.h"
79 #include "nm-sleep-monitor.h"
80 #include "nm-connectivity.h"
81 #include "nm-policy.h"
82
83
84 #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
85 #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
86
87 static gboolean impl_manager_get_devices (NMManager *manager,
88 GPtrArray **devices,
89 GError **err);
90
91 static gboolean impl_manager_get_device_by_ip_iface (NMManager *self,
92 const char *iface,
93 char **out_object_path,
94 GError **error);
95
96 static void impl_manager_activate_connection (NMManager *manager,
97 const char *connection_path,
98 const char *device_path,
99 const char *specific_object_path,
100 DBusGMethodInvocation *context);
101
102 static void impl_manager_add_and_activate_connection (NMManager *manager,
103 GHashTable *settings,
104 const char *device_path,
105 const char *specific_object_path,
106 DBusGMethodInvocation *context);
107
108 static void impl_manager_deactivate_connection (NMManager *manager,
109 const char *connection_path,
110 DBusGMethodInvocation *context);
111
112 static void impl_manager_sleep (NMManager *manager,
113 gboolean do_sleep,
114 DBusGMethodInvocation *context);
115
116 static void impl_manager_enable (NMManager *manager,
117 gboolean enable,
118 DBusGMethodInvocation *context);
119
120 static void impl_manager_get_permissions (NMManager *manager,
121 DBusGMethodInvocation *context);
122
123 static gboolean impl_manager_get_state (NMManager *manager,
124 guint32 *state,
125 GError **error);
126
127 static gboolean impl_manager_set_logging (NMManager *manager,
128 const char *level,
129 const char *domains,
130 GError **error);
131
132 static void impl_manager_get_logging (NMManager *manager,
133 char **level,
134 char **domains);
135
136 static void impl_manager_check_connectivity (NMManager *manager,
137 DBusGMethodInvocation *context);
138
139 #include "nm-manager-glue.h"
140
141 static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
142 NMBluezDevice *bt_device,
143 const char *bdaddr,
144 const char *name,
145 const char *object_path,
146 guint32 uuids,
147 NMManager *manager);
148
149 static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
150 const char *bdaddr,
151 const char *object_path,
152 gpointer user_data);
153
154 static void add_device (NMManager *self, NMDevice *device);
155 static void remove_device (NMManager *self, NMDevice *device, gboolean quitting);
156
157 static void hostname_provider_init (NMHostnameProvider *provider_class);
158
159 static NMActiveConnection *internal_activate_device (NMManager *manager,
160 NMDevice *device,
161 NMConnection *connection,
162 const char *specific_object,
163 gboolean user_requested,
164 gulong sender_uid,
165 const char *dbus_sender,
166 gboolean assumed,
167 NMActiveConnection *master,
168 GError **error);
169
170 static NMDevice *find_device_by_ip_iface (NMManager *self, const gchar *iface);
171
172 static void rfkill_change_wifi (const char *desc, gboolean enabled);
173
174 static void
175 platform_link_added_cb (NMPlatform *platform,
176 int ifindex,
177 NMPlatformLink *plink,
178 NMPlatformReason reason,
179 gpointer user_data);
180
181 #define SSD_POKE_INTERVAL 120
182 #define ORIGDEV_TAG "originating-device"
183
184 typedef struct PendingActivation PendingActivation;
185 typedef void (*PendingActivationFunc) (PendingActivation *pending,
186 GError *error);
187
188 struct PendingActivation {
189 NMManager *manager;
190
191 DBusGMethodInvocation *context;
192 PendingActivationFunc callback;
193 NMAuthChain *chain;
194 const char *wifi_shared_permission;
195
196 char *connection_path;
197 NMConnection *connection;
198 char *specific_object_path;
199 char *device_path;
200 };
201
202 typedef struct {
203 gboolean user_enabled;
204 gboolean daemon_enabled;
205 gboolean sw_enabled;
206 gboolean hw_enabled;
207 RfKillType rtype;
208 const char *desc;
209 const char *key;
210 const char *prop;
211 const char *hw_prop;
212 RfKillState (*other_enabled_func) (NMManager *);
213 RfKillState (*daemon_enabled_func) (NMManager *);
214 } RadioState;
215
216 typedef struct {
217 char *state_file;
218
219 GSList *active_connections;
220 guint ac_cleanup_id;
221 NMActiveConnection *primary_connection;
222 NMActiveConnection *activating_connection;
223
224 GSList *devices;
225 NMState state;
226 NMConnectivity *connectivity;
227
228 NMPolicy *policy;
229
230 NMDBusManager *dbus_mgr;
231 guint dbus_connection_changed_id;
232 NMAtmManager *atm_mgr;
233 NMRfkillManager *rfkill_mgr;
234 NMBluezManager *bluez_mgr;
235
236 /* List of NMDeviceFactoryFunc pointers sorted in priority order */
237 GSList *factories;
238
239 NMSettings *settings;
240 char *hostname;
241
242 RadioState radio_states[RFKILL_TYPE_MAX];
243 gboolean sleeping;
244 gboolean net_enabled;
245
246 NMVPNManager *vpn_manager;
247
248 NMModemManager *modem_manager;
249 guint modem_added_id;
250 guint modem_removed_id;
251
252 DBusGProxy *aipd_proxy;
253 NMSleepMonitor *sleep_monitor;
254
255 GSList *auth_chains;
256
257 /* Firmware dir monitor */
258 GFileMonitor *fw_monitor;
259 guint fw_monitor_id;
260 guint fw_changed_id;
261
262 guint timestamp_update_id;
263
264 GHashTable *nm_bridges;
265
266 /* Track auto-activation for software devices */
267 GHashTable *noauto_sw_devices;
268
269 gboolean startup;
270 gboolean disposed;
271 } NMManagerPrivate;
272
273 #define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
274
275 G_DEFINE_TYPE_EXTENDED (NMManager, nm_manager, G_TYPE_OBJECT, 0,
276 G_IMPLEMENT_INTERFACE (NM_TYPE_HOSTNAME_PROVIDER,
277 hostname_provider_init))
278
279 enum {
280 DEVICE_ADDED,
281 DEVICE_REMOVED,
282 STATE_CHANGED,
283 CHECK_PERMISSIONS,
284 USER_PERMISSIONS_CHANGED,
285 ACTIVE_CONNECTION_ADDED,
286 ACTIVE_CONNECTION_REMOVED,
287
288 LAST_SIGNAL
289 };
290
291 static guint signals[LAST_SIGNAL] = { 0 };
292
293 enum {
294 PROP_0,
295 PROP_VERSION,
296 PROP_STATE,
297 PROP_STARTUP,
298 PROP_NETWORKING_ENABLED,
299 PROP_WIRELESS_ENABLED,
300 PROP_WIRELESS_HARDWARE_ENABLED,
301 PROP_WWAN_ENABLED,
302 PROP_WWAN_HARDWARE_ENABLED,
303 PROP_WIMAX_ENABLED,
304 PROP_WIMAX_HARDWARE_ENABLED,
305 PROP_ACTIVE_CONNECTIONS,
306 PROP_CONNECTIVITY,
307 PROP_PRIMARY_CONNECTION,
308 PROP_ACTIVATING_CONNECTION,
309
310 /* Not exported */
311 PROP_HOSTNAME,
312 PROP_SLEEPING,
313
314 LAST_PROP
315 };
316
317
318 /************************************************************************/
319
320 #define NM_MANAGER_ERROR (nm_manager_error_quark ())
321
322 static GQuark
323 nm_manager_error_quark (void)
324 {
325 static GQuark quark = 0;
326 if (!quark)
327 quark = g_quark_from_static_string ("nm-manager-error");
328 return quark;
329 }
330
331 /************************************************************************/
332
333 static void active_connection_state_changed (NMActiveConnection *active,
334 GParamSpec *pspec,
335 NMManager *self);
336
337 static void
338 active_connection_removed (NMManager *self, NMActiveConnection *active)
339 {
340 g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
341 g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
342 g_object_unref (active);
343 }
344
345 static gboolean
346 _active_connection_cleanup (gpointer user_data)
347 {
348 NMManager *self = NM_MANAGER (user_data);
349 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
350 GSList *iter;
351 gboolean changed = FALSE;
352
353 priv->ac_cleanup_id = 0;
354
355 iter = priv->active_connections;
356 while (iter) {
357 NMActiveConnection *ac = iter->data;
358
359 iter = iter->next;
360 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
361 priv->active_connections = g_slist_remove (priv->active_connections, ac);
362 active_connection_removed (self, ac);
363 changed = TRUE;
364 }
365 }
366
367 if (changed)
368 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
369
370 return FALSE;
371 }
372
373 static void
374 active_connection_state_changed (NMActiveConnection *active,
375 GParamSpec *pspec,
376 NMManager *self)
377 {
378 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
379 NMActiveConnectionState state;
380
381 state = nm_active_connection_get_state (active);
382 if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
383 /* Destroy active connections from an idle handler to ensure that
384 * their last property change notifications go out, which wouldn't
385 * happen if we destroyed them immediately when their state was set
386 * to DEACTIVATED.
387 */
388 if (!priv->ac_cleanup_id)
389 priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
390 }
391 }
392
393 static void
394 active_connection_add (NMManager *self, NMActiveConnection *active)
395 {
396 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
397
398 g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
399
400 priv->active_connections = g_slist_prepend (priv->active_connections, active);
401 g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE,
402 G_CALLBACK (active_connection_state_changed),
403 self);
404
405 g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
406 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
407 }
408
409 const GSList *
410 nm_manager_get_active_connections (NMManager *manager)
411 {
412 return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
413 }
414
415 static NMActiveConnection *
416 active_connection_get_by_path (NMManager *manager, const char *path)
417 {
418 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
419 GSList *iter;
420
421 g_return_val_if_fail (manager != NULL, NULL);
422 g_return_val_if_fail (path != NULL, NULL);
423
424 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
425 NMActiveConnection *candidate = iter->data;
426
427 if (strcmp (path, nm_active_connection_get_path (candidate)) == 0)
428 return candidate;
429 }
430 return NULL;
431 }
432
433 /************************************************************************/
434
435 static NMDevice *
436 nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
437 {
438 GSList *iter;
439
440 g_return_val_if_fail (udi != NULL, NULL);
441
442 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
443 if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
444 return NM_DEVICE (iter->data);
445 }
446 return NULL;
447 }
448
449 static NMDevice *
450 nm_manager_get_device_by_path (NMManager *manager, const char *path)
451 {
452 GSList *iter;
453
454 g_return_val_if_fail (path != NULL, NULL);
455
456 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
457 if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path))
458 return NM_DEVICE (iter->data);
459 }
460 return NULL;
461 }
462
463 NMDevice *
464 nm_manager_get_device_by_master (NMManager *manager, const char *master, const char *driver)
465 {
466 GSList *iter;
467
468 g_return_val_if_fail (master != NULL, NULL);
469
470 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
471 NMDevice *device = NM_DEVICE (iter->data);
472
473 if (!strcmp (nm_device_get_iface (device), master) &&
474 (!driver || !strcmp (nm_device_get_driver (device), driver)))
475 return device;
476 }
477
478 return NULL;
479 }
480
481 NMDevice *
482 nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
483 {
484 GSList *iter;
485
486 for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
487 NMDevice *device = NM_DEVICE (iter->data);
488
489 if (nm_device_get_ifindex (device) == ifindex)
490 return device;
491 }
492
493 return NULL;
494 }
495
496 static gboolean
497 manager_sleeping (NMManager *self)
498 {
499 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
500
501 if (priv->sleeping || !priv->net_enabled)
502 return TRUE;
503 return FALSE;
504 }
505
506 static void
507 modem_added (NMModemManager *modem_manager,
508 NMModem *modem,
509 const char *driver,
510 gpointer user_data)
511 {
512 NMManager *self = NM_MANAGER (user_data);
513 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
514 NMDevice *replace_device, *device = NULL;
515 const char *modem_iface;
516 GSList *iter;
517
518 /* Don't rely only on the data port; use the control port if available */
519 modem_iface = nm_modem_get_data_port (modem);
520 if (!modem_iface)
521 modem_iface = nm_modem_get_control_port (modem);
522 g_return_if_fail (modem_iface);
523
524 replace_device = find_device_by_ip_iface (NM_MANAGER (user_data), modem_iface);
525 if (replace_device)
526 remove_device (NM_MANAGER (user_data), replace_device, FALSE);
527
528 /* Give Bluetooth DUN devices first chance to claim the modem */
529 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
530 if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) {
531 if (nm_device_bt_modem_added (NM_DEVICE_BT (iter->data), modem, driver))
532 return;
533 }
534 }
535
536 /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore
537 * it. The rfcomm port (and thus the modem) gets created automatically
538 * by the Bluetooth code during the connection process.
539 */
540 if (driver && !strcmp (driver, "bluetooth")) {
541 nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", modem_iface);
542 return;
543 }
544
545 /* Make the new modem device */
546 device = nm_device_modem_new (modem, driver);
547 if (device)
548 add_device (self, device);
549 }
550
551 static void
552 set_state (NMManager *manager, NMState state)
553 {
554 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
555 const char *state_str;
556
557 if (priv->state == state)
558 return;
559
560 priv->state = state;
561
562 switch (state) {
563 case NM_STATE_ASLEEP:
564 state_str = "ASLEEP";
565 break;
566 case NM_STATE_DISCONNECTED:
567 state_str = "DISCONNECTED";
568 break;
569 case NM_STATE_DISCONNECTING:
570 state_str = "DISCONNECTING";
571 break;
572 case NM_STATE_CONNECTING:
573 state_str = "CONNECTING";
574 break;
575 case NM_STATE_CONNECTED_LOCAL:
576 state_str = "CONNECTED_LOCAL";
577 break;
578 case NM_STATE_CONNECTED_SITE:
579 state_str = "CONNECTED_SITE";
580 break;
581 case NM_STATE_CONNECTED_GLOBAL:
582 state_str = "CONNECTED_GLOBAL";
583 break;
584 case NM_STATE_UNKNOWN:
585 default:
586 state_str = "UNKNOWN";
587 break;
588 }
589
590 nm_log_info (LOGD_CORE, "NetworkManager state is now %s", state_str);
591
592 g_object_notify (G_OBJECT (manager), NM_MANAGER_STATE);
593 g_signal_emit (manager, signals[STATE_CHANGED], 0, priv->state);
594 }
595
596 static void
597 checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
598 {
599 NMManager *manager = user_data;
600 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
601 NMConnectivityState connectivity;
602
603 if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
604 connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
605
606 if (connectivity == NM_CONNECTIVITY_FULL)
607 set_state (manager, NM_STATE_CONNECTED_GLOBAL);
608 else if ( connectivity == NM_CONNECTIVITY_PORTAL
609 || connectivity == NM_CONNECTIVITY_LIMITED)
610 set_state (manager, NM_STATE_CONNECTED_SITE);
611 }
612
613 g_object_unref (manager);
614 }
615
616 static void
617 nm_manager_update_state (NMManager *manager)
618 {
619 NMManagerPrivate *priv;
620 NMState new_state = NM_STATE_DISCONNECTED;
621 GSList *iter;
622 gboolean want_connectivity_check = FALSE;
623
624 g_return_if_fail (NM_IS_MANAGER (manager));
625
626 priv = NM_MANAGER_GET_PRIVATE (manager);
627
628 if (manager_sleeping (manager))
629 new_state = NM_STATE_ASLEEP;
630 else {
631 for (iter = priv->devices; iter; iter = iter->next) {
632 NMDevice *dev = NM_DEVICE (iter->data);
633 NMDeviceState state = nm_device_get_state (dev);
634
635 if (state == NM_DEVICE_STATE_ACTIVATED) {
636 nm_connectivity_set_online (priv->connectivity, TRUE);
637 if (nm_connectivity_get_state (priv->connectivity) != NM_CONNECTIVITY_FULL) {
638 new_state = NM_STATE_CONNECTING;
639 want_connectivity_check = TRUE;
640 } else {
641 new_state = NM_STATE_CONNECTED_GLOBAL;
642 break;
643 }
644 }
645
646 if (nm_device_is_activating (dev))
647 new_state = NM_STATE_CONNECTING;
648 else if (new_state != NM_STATE_CONNECTING) {
649 if (state == NM_DEVICE_STATE_DEACTIVATING)
650 new_state = NM_STATE_DISCONNECTING;
651 }
652 }
653 }
654
655 if (new_state == NM_STATE_CONNECTING && want_connectivity_check) {
656 nm_connectivity_check_async (priv->connectivity,
657 checked_connectivity,
658 g_object_ref (manager));
659 return;
660 }
661
662 nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
663 set_state (manager, new_state);
664 }
665
666 static void
667 manager_device_state_changed (NMDevice *device,
668 NMDeviceState new_state,
669 NMDeviceState old_state,
670 NMDeviceStateReason reason,
671 gpointer user_data)
672 {
673 NMManager *self = NM_MANAGER (user_data);
674
675 switch (new_state) {
676 case NM_DEVICE_STATE_UNMANAGED:
677 case NM_DEVICE_STATE_UNAVAILABLE:
678 case NM_DEVICE_STATE_DISCONNECTED:
679 case NM_DEVICE_STATE_PREPARE:
680 case NM_DEVICE_STATE_FAILED:
681 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
682 break;
683 default:
684 break;
685 }
686
687 nm_manager_update_state (self);
688 }
689
690 static void device_has_pending_action_changed (NMDevice *device,
691 GParamSpec *pspec,
692 NMManager *self);
693
694 static void
695 check_if_startup_complete (NMManager *self)
696 {
697 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
698 GSList *iter;
699
700 if (!priv->startup)
701 return;
702
703 for (iter = priv->devices; iter; iter = iter->next) {
704 NMDevice *dev = iter->data;
705
706 if (nm_device_has_pending_action (dev)) {
707 nm_log_dbg (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
708 nm_device_get_iface (dev));
709 return;
710 }
711 }
712
713 nm_log_info (LOGD_CORE, "startup complete");
714
715 priv->startup = FALSE;
716 g_object_notify (G_OBJECT (self), "startup");
717
718 /* We don't have to watch notify::has-pending-action any more. */
719 for (iter = priv->devices; iter; iter = iter->next) {
720 NMDevice *dev = iter->data;
721
722 g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
723 }
724 }
725
726 static void
727 device_has_pending_action_changed (NMDevice *device,
728 GParamSpec *pspec,
729 NMManager *self)
730 {
731 check_if_startup_complete (self);
732 }
733
734 static void
735 remove_device (NMManager *manager, NMDevice *device, gboolean quitting)
736 {
737 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
738
739 if (nm_device_get_managed (device)) {
740 /* When quitting, we want to leave up interfaces & connections
741 * that can be taken over again (ie, "assumed") when NM restarts
742 * so that '/etc/init.d/NetworkManager restart' will not distrupt
743 * networking for interfaces that support connection assumption.
744 * All other devices get unmanaged when NM quits so that their
745 * connections get torn down and the interface is deactivated.
746 */
747
748 if ( !nm_device_can_assume_connections (device)
749 || (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
750 || !quitting)
751 nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED);
752 }
753
754 g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, manager);
755
756 nm_settings_device_removed (priv->settings, device);
757 g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device);
758 g_object_unref (device);
759
760 priv->devices = g_slist_remove (priv->devices, device);
761
762 if (priv->startup)
763 check_if_startup_complete (manager);
764 }
765
766 static void
767 modem_removed (NMModemManager *modem_manager,
768 NMModem *modem,
769 gpointer user_data)
770 {
771 NMManager *self = NM_MANAGER (user_data);
772 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
773 NMDevice *found;
774 GSList *iter;
775
776 /* Give Bluetooth DUN devices first chance to handle the modem removal */
777 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
778 if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) {
779 if (nm_device_bt_modem_removed (NM_DEVICE_BT (iter->data), modem))
780 return;
781 }
782 }
783
784 /* Otherwise remove the standalone modem */
785 found = nm_manager_get_device_by_udi (self, nm_modem_get_path (modem));
786 if (found)
787 remove_device (self, found, FALSE);
788 }
789
790 static void
791 aipd_handle_event (DBusGProxy *proxy,
792 const char *event,
793 const char *iface,
794 const char *address,
795 gpointer user_data)
796 {
797 NMManager *manager = NM_MANAGER (user_data);
798 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
799 GSList *iter;
800 gboolean handled = FALSE;
801
802 if (!event || !iface) {
803 nm_log_warn (LOGD_AUTOIP4, "incomplete message received from avahi-autoipd");
804 return;
805 }
806
807 if ( (strcmp (event, "BIND") != 0)
808 && (strcmp (event, "CONFLICT") != 0)
809 && (strcmp (event, "UNBIND") != 0)
810 && (strcmp (event, "STOP") != 0)) {
811 nm_log_warn (LOGD_AUTOIP4, "unknown event '%s' received from avahi-autoipd", event);
812 return;
813 }
814
815 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
816 NMDevice *candidate = NM_DEVICE (iter->data);
817
818 if (!strcmp (nm_device_get_iface (candidate), iface)) {
819 nm_device_handle_autoip4_event (candidate, event, address);
820 handled = TRUE;
821 break;
822 }
823 }
824
825 if (!handled)
826 nm_log_warn (LOGD_AUTOIP4, "(%s): unhandled avahi-autoipd event", iface);
827 }
828
829 static const char *
830 hostname_provider_get_hostname (NMHostnameProvider *provider)
831 {
832 return NM_MANAGER_GET_PRIVATE (provider)->hostname;
833 }
834
835 static void
836 hostname_provider_init (NMHostnameProvider *provider_class)
837 {
838 provider_class->get_hostname = hostname_provider_get_hostname;
839 }
840
841 NMState
842 nm_manager_get_state (NMManager *manager)
843 {
844 g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
845
846 return NM_MANAGER_GET_PRIVATE (manager)->state;
847 }
848
849 static gboolean
850 might_be_vpn (NMConnection *connection)
851 {
852 NMSettingConnection *s_con;
853 const char *ctype = NULL;
854
855 if (nm_connection_get_setting_vpn (connection))
856 return TRUE;
857
858 /* Make sure it's not a VPN, which we can't autocomplete yet */
859 s_con = nm_connection_get_setting_connection (connection);
860 if (s_con)
861 ctype = nm_setting_connection_get_connection_type (s_con);
862
863 return (g_strcmp0 (ctype, NM_SETTING_VPN_SETTING_NAME) == 0);
864 }
865
866 static gboolean
867 try_complete_vpn (NMConnection *connection, GSList *existing, GError **error)
868 {
869 g_assert (might_be_vpn (connection) == TRUE);
870
871 if (!nm_connection_get_setting_vpn (connection)) {
872 g_set_error_literal (error,
873 NM_MANAGER_ERROR,
874 NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE,
875 "VPN connections require a 'vpn' setting");
876 return FALSE;
877 }
878
879 nm_utils_complete_generic (connection,
880 NM_SETTING_VPN_SETTING_NAME,
881 existing,
882 _("VPN connection %d"),
883 NULL,
884 FALSE); /* No IPv6 by default for now */
885
886 return TRUE;
887 }
888
889 static PendingActivation *
890 pending_activation_new (NMManager *manager,
891 DBusGMethodInvocation *context,
892 const char *device_path,
893 const char *connection_path,
894 GHashTable *settings,
895 const char *specific_object_path,
896 PendingActivationFunc callback,
897 GError **error)
898 {
899 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
900 PendingActivation *pending;
901 NMDevice *device = NULL;
902 NMConnection *connection = NULL;
903 GSList *all_connections = NULL;
904 gboolean success;
905
906 g_return_val_if_fail (manager != NULL, NULL);
907 g_return_val_if_fail (context != NULL, NULL);
908 g_return_val_if_fail (device_path != NULL, NULL);
909
910 /* A object path of "/" means NULL */
911 if (g_strcmp0 (specific_object_path, "/") == 0)
912 specific_object_path = NULL;
913 if (g_strcmp0 (device_path, "/") == 0)
914 device_path = NULL;
915
916 /* Create the partial connection from the given settings */
917 if (settings) {
918 if (device_path)
919 device = nm_manager_get_device_by_path (manager, device_path);
920 if (!device) {
921 g_set_error_literal (error,
922 NM_MANAGER_ERROR,
923 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
924 "Device not found");
925 return NULL;
926 }
927
928 connection = nm_connection_new ();
929 nm_connection_replace_settings (connection, settings, NULL);
930
931 all_connections = nm_settings_get_connections (priv->settings);
932
933 if (might_be_vpn (connection)) {
934 /* Try to fill the VPN's connection setting and name at least */
935 success = try_complete_vpn (connection, all_connections, error);
936 } else {
937 /* Let each device subclass complete the connection */
938 success = nm_device_complete_connection (device,
939 connection,
940 specific_object_path,
941 all_connections,
942 error);
943 }
944 g_slist_free (all_connections);
945
946 if (success == FALSE) {
947 g_object_unref (connection);
948 return NULL;
949 }
950 }
951
952 pending = g_slice_new0 (PendingActivation);
953 pending->manager = manager;
954 pending->context = context;
955 pending->callback = callback;
956
957 pending->connection_path = g_strdup (connection_path);
958 pending->connection = connection;
959
960 /* "/" is special-cased to NULL to get through D-Bus */
961 if (specific_object_path && strcmp (specific_object_path, "/"))
962 pending->specific_object_path = g_strdup (specific_object_path);
963 if (device_path && strcmp (device_path, "/"))
964 pending->device_path = g_strdup (device_path);
965
966 return pending;
967 }
968
969 static void
970 pending_auth_done (NMAuthChain *chain,
971 GError *error,
972 DBusGMethodInvocation *context,
973 gpointer user_data)
974 {
975 PendingActivation *pending = user_data;
976 NMAuthCallResult result;
977 GError *tmp_error = NULL;
978
979 /* Caller has had a chance to obtain authorization, so we only need to
980 * check for 'yes' here.
981 */
982 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
983 if (error)
984 tmp_error = g_error_copy (error);
985 else if (result != NM_AUTH_CALL_RESULT_YES) {
986 tmp_error = g_error_new_literal (NM_MANAGER_ERROR,
987 NM_MANAGER_ERROR_PERMISSION_DENIED,
988 "Not authorized to control networking.");
989 } else if (pending->wifi_shared_permission) {
990 result = nm_auth_chain_get_result (chain, pending->wifi_shared_permission);
991 if (result != NM_AUTH_CALL_RESULT_YES) {
992 tmp_error = g_error_new_literal (NM_MANAGER_ERROR,
993 NM_MANAGER_ERROR_PERMISSION_DENIED,
994 "Not authorized to share connections via wifi.");
995 }
996 }
997
998 pending->callback (pending, tmp_error);
999 g_clear_error (&tmp_error);
1000 }
1001
1002 static void
1003 pending_activation_check_authorized (PendingActivation *pending)
1004 {
1005 GError *error;
1006 const char *wifi_permission = NULL;
1007 NMConnection *connection;
1008 NMSettings *settings;
1009 const char *error_desc = NULL;
1010
1011 g_return_if_fail (pending != NULL);
1012
1013 /* By this point we have an auto-completed connection (for AddAndActivate)
1014 * or an existing connection (for Activate).
1015 */
1016 connection = pending->connection;
1017 if (!connection) {
1018 settings = NM_MANAGER_GET_PRIVATE (pending->manager)->settings;
1019 connection = (NMConnection *) nm_settings_get_connection_by_path (settings, pending->connection_path);
1020 }
1021
1022 if (!connection) {
1023 error = g_error_new_literal (NM_MANAGER_ERROR,
1024 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
1025 "Connection could not be found.");
1026 pending->callback (pending, error);
1027 g_error_free (error);
1028 return;
1029 }
1030
1031 /* First check if the user is allowed to use networking at all, giving
1032 * the user a chance to authenticate to gain the permission.
1033 */
1034 pending->chain = nm_auth_chain_new (pending->context,
1035 pending_auth_done,
1036 pending,
1037 &error_desc);
1038 if (pending->chain) {
1039 nm_auth_chain_add_call (pending->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
1040
1041 /* Shared wifi connections require special permissions too */
1042 wifi_permission = nm_utils_get_shared_wifi_permission (connection);
1043 if (wifi_permission) {
1044 pending->wifi_shared_permission = wifi_permission;
1045 nm_auth_chain_add_call (pending->chain, wifi_permission, TRUE);
1046 }
1047 } else {
1048 error = g_error_new_literal (NM_MANAGER_ERROR,
1049 NM_MANAGER_ERROR_PERMISSION_DENIED,
1050 error_desc);
1051 pending->callback (pending, error);
1052 g_error_free (error);
1053 }
1054 }
1055
1056 static void
1057 pending_activation_destroy (PendingActivation *pending,
1058 GError *error,
1059 NMActiveConnection *ac)
1060 {
1061 g_return_if_fail (pending != NULL);
1062
1063 if (error)
1064 dbus_g_method_return_error (pending->context, error);
1065 else if (ac) {
1066 if (pending->connection) {
1067 dbus_g_method_return (pending->context,
1068 pending->connection_path,
1069 nm_active_connection_get_path (ac));
1070 } else {
1071 dbus_g_method_return (pending->context,
1072 nm_active_connection_get_path (ac));
1073 }
1074 }
1075
1076 g_free (pending->connection_path);
1077 g_free (pending->specific_object_path);
1078 g_free (pending->device_path);
1079 if (pending->connection)
1080 g_object_unref (pending->connection);
1081
1082 if (pending->chain)
1083 nm_auth_chain_unref (pending->chain);
1084
1085 memset (pending, 0, sizeof (PendingActivation));
1086 g_slice_free (PendingActivation, pending);
1087 }
1088
1089 /*******************************************************************/
1090 /* Settings stuff via NMSettings */
1091 /*******************************************************************/
1092
1093 static NMDevice *
1094 get_device_from_hwaddr (NMManager *self, const GByteArray *setting_mac)
1095 {
1096 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1097 const guint8 *device_mac;
1098 guint device_mac_len;
1099 GSList *iter;
1100
1101 if (!setting_mac)
1102 return NULL;
1103
1104 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1105 NMDevice *device = iter->data;
1106
1107 device_mac = nm_device_get_hw_address (iter->data, &device_mac_len);
1108 if ( setting_mac->len == device_mac_len
1109 && memcmp (setting_mac->data, device_mac, device_mac_len) == 0)
1110 return device;
1111 }
1112 return NULL;
1113 }
1114
1115 static NMDevice *
1116 find_vlan_parent (NMManager *self,
1117 NMConnection *connection)
1118 {
1119 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1120 NMSettingVlan *s_vlan;
1121 NMSettingWired *s_wired;
1122 NMConnection *parent_connection;
1123 const char *parent_iface;
1124 NMDevice *parent = NULL;
1125 const GByteArray *setting_mac;
1126 GSList *iter;
1127
1128 /* The 'parent' property could be given by an interface name, a
1129 * connection UUID, or the MAC address of an NMSettingWired.
1130 */
1131 s_vlan = nm_connection_get_setting_vlan (connection);
1132 g_return_val_if_fail (s_vlan != NULL, NULL);
1133
1134 s_wired = nm_connection_get_setting_wired (connection);
1135 setting_mac = s_wired ? nm_setting_wired_get_mac_address (s_wired) : NULL;
1136
1137 parent_iface = nm_setting_vlan_get_parent (s_vlan);
1138 if (parent_iface) {
1139 parent = find_device_by_ip_iface (self, parent_iface);
1140 if (parent)
1141 return parent;
1142
1143 if (nm_utils_is_uuid (parent_iface)) {
1144 /* Try as a connection UUID */
1145 parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, parent_iface);
1146 if (parent_connection) {
1147 /* Check if the parent connection is activated on some device already */
1148 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1149 NMActRequest *req;
1150 NMConnection *candidate;
1151
1152 req = nm_device_get_act_request (NM_DEVICE (iter->data));
1153 if (req) {
1154 candidate = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (req));
1155 if (candidate == parent_connection)
1156 return NM_DEVICE (iter->data);
1157 }
1158 }
1159
1160 /* Check the hardware address of the parent connection */
1161 return get_device_from_hwaddr (self, setting_mac);
1162 }
1163 return NULL;
1164 }
1165 }
1166
1167 /* Try the hardware address from the VLAN connection's hardware setting */
1168 return get_device_from_hwaddr (self, setting_mac);
1169 }
1170
1171 static NMDevice *
1172 find_infiniband_parent (NMManager *self,
1173 NMConnection *connection)
1174 {
1175 NMSettingInfiniband *s_infiniband;
1176 const char *parent_iface;
1177 NMDevice *parent = NULL;
1178 const GByteArray *setting_mac;
1179
1180 s_infiniband = nm_connection_get_setting_infiniband (connection);
1181 g_return_val_if_fail (s_infiniband != NULL, NULL);
1182
1183 parent_iface = nm_setting_infiniband_get_parent (s_infiniband);
1184 if (parent_iface) {
1185 parent = find_device_by_ip_iface (self, parent_iface);
1186 if (parent)
1187 return parent;
1188 }
1189
1190 setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband);
1191 return get_device_from_hwaddr (self, setting_mac);
1192 }
1193
1194 /**
1195 * get_virtual_iface_name:
1196 * @self: the #NMManager
1197 * @connection: the #NMConnection representing a virtual interface
1198 * @out_parent: on success, the parent device if any
1199 *
1200 * Given @connection, returns the interface name that the connection
1201 * would represent. If the interface name is not given by the connection,
1202 * this may require constructing it based on information in the connection
1203 * and existing network interfaces.
1204 *
1205 * Returns: the expected interface name (caller takes ownership), or %NULL
1206 */
1207 static char *
1208 get_virtual_iface_name (NMManager *self,
1209 NMConnection *connection,
1210 NMDevice **out_parent)
1211 {
1212 NMDevice *parent = NULL;
1213
1214 if (out_parent)
1215 *out_parent = NULL;
1216
1217 if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
1218 return g_strdup (nm_connection_get_virtual_iface_name (connection));
1219
1220 if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME))
1221 return g_strdup (nm_connection_get_virtual_iface_name (connection));
1222
1223 if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME))
1224 return g_strdup (nm_connection_get_virtual_iface_name (connection));
1225
1226 if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) {
1227 NMSettingVlan *s_vlan;
1228 const char *ifname;
1229 char *vname;
1230
1231 s_vlan = nm_connection_get_setting_vlan (connection);
1232 g_return_val_if_fail (s_vlan != NULL, NULL);
1233
1234 parent = find_vlan_parent (self, connection);
1235 if (parent) {
1236 ifname = nm_connection_get_virtual_iface_name (connection);
1237
1238 if (!nm_device_supports_vlans (parent)) {
1239 nm_log_warn (LOGD_DEVICE, "(%s): No support for VLANs on interface %s of type %s",
1240 ifname ? ifname : nm_connection_get_id (connection),
1241 nm_device_get_ip_iface (parent),
1242 nm_device_get_type_desc (parent));
1243 return NULL;
1244 }
1245
1246 /* If the connection doesn't specify the interface name for the VLAN
1247 * device, we create one for it using the VLAN ID and the parent
1248 * interface's name.
1249 */
1250 if (ifname)
1251 vname = g_strdup (ifname);
1252 else {
1253 vname = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent),
1254 nm_setting_vlan_get_id (s_vlan));
1255 }
1256 if (out_parent)
1257 *out_parent = parent;
1258 return vname;
1259 }
1260 }
1261
1262 if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) {
1263 const char *ifname;
1264 char *name;
1265
1266 parent = find_infiniband_parent (self, connection);
1267 if (parent) {
1268 ifname = nm_connection_get_virtual_iface_name (connection);
1269 if (ifname)
1270 name = g_strdup (ifname);
1271 else {
1272 NMSettingInfiniband *s_infiniband;
1273 int p_key;
1274
1275 ifname = nm_device_get_iface (parent);
1276 s_infiniband = nm_connection_get_setting_infiniband (connection);
1277 p_key = nm_setting_infiniband_get_p_key (s_infiniband);
1278 name = g_strdup_printf ("%s.%04x", ifname, p_key);
1279 }
1280 if (out_parent)
1281 *out_parent = parent;
1282 return name;
1283 }
1284 }
1285
1286 return NULL;
1287 }
1288
1289 static gboolean
1290 connection_needs_virtual_device (NMConnection *connection)
1291 {
1292 if ( nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)
1293 || nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)
1294 || nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)
1295 || nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME))
1296 return TRUE;
1297
1298 if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) {
1299 NMSettingInfiniband *s_infiniband;
1300
1301 s_infiniband = nm_connection_get_setting_infiniband (connection);
1302 g_return_val_if_fail (s_infiniband != NULL, FALSE);
1303 if (nm_setting_infiniband_get_p_key (s_infiniband) != -1)
1304 return TRUE;
1305 }
1306
1307 return FALSE;
1308 }
1309
1310 /***************************/
1311
1312 /* FIXME: remove when we handle bridges non-destructively */
1313
1314 #define NM_BRIDGE_FILE NMRUNDIR "/nm-bridges"
1315
1316 static void
1317 read_nm_created_bridges (NMManager *self)
1318 {
1319 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1320 char *contents;
1321 char **lines, **iter;
1322 GTimeVal tv;
1323 glong ts;
1324
1325 if (!g_file_get_contents (NM_BRIDGE_FILE, &contents, NULL, NULL))
1326 return;
1327
1328 g_get_current_time (&tv);
1329
1330 lines = g_strsplit_set (contents, "\n", 0);
1331 g_free (contents);
1332
1333 for (iter = lines; iter && *iter; iter++) {
1334 if (g_str_has_prefix (*iter, "ts=")) {
1335 errno = 0;
1336 ts = strtol (*iter + 3, NULL, 10);
1337 /* allow 30 minutes time difference before we ignore the file */
1338 if (errno || ABS (tv.tv_sec - ts) > 1800)
1339 goto out;
1340 } else if (g_str_has_prefix (*iter, "iface="))
1341 g_hash_table_insert (priv->nm_bridges, g_strdup (*iter + 6), GUINT_TO_POINTER (1));
1342 }
1343
1344 out:
1345 g_strfreev (lines);
1346 unlink (NM_BRIDGE_FILE);
1347 }
1348
1349 static void
1350 write_nm_created_bridges (NMManager *self)
1351 {
1352 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1353 GString *br_list;
1354 GSList *iter;
1355 GError *error = NULL;
1356 GTimeVal tv;
1357 gboolean found = FALSE;
1358
1359 /* write out nm-created bridges list */
1360 br_list = g_string_sized_new (50);
1361
1362 /* Timestamp is first line */
1363 g_get_current_time (&tv);
1364 g_string_append_printf (br_list, "ts=%ld\n", tv.tv_sec);
1365
1366 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1367 NMDevice *device = iter->data;
1368
1369 if (nm_device_get_device_type (device) == NM_DEVICE_TYPE_BRIDGE) {
1370 g_string_append_printf (br_list, "iface=%s\n", nm_device_get_iface (device));
1371 found = TRUE;
1372 }
1373 }
1374
1375 if (found) {
1376 if (!g_file_set_contents (NM_BRIDGE_FILE, br_list->str, -1, &error)) {
1377 nm_log_warn (LOGD_BRIDGE, "Failed to write NetworkManager-created bridge list; "
1378 "on restart bridges may not be recognized. (%s)",
1379 error ? error->message : "unknown");
1380 g_clear_error (&error);
1381 }
1382 }
1383 g_string_free (br_list, TRUE);
1384 }
1385
1386 static gboolean
1387 bridge_created_by_nm (NMManager *self, const char *iface)
1388 {
1389 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1390
1391 return (priv->nm_bridges && g_hash_table_lookup (priv->nm_bridges, iface));
1392 }
1393
1394 /***************************/
1395
1396 /**
1397 * system_create_virtual_device:
1398 * @self: the #NMManager
1399 * @connection: the connection which might require a virtual device
1400 *
1401 * If @connection requires a virtual device and one does not yet exist for it,
1402 * creates that device.
1403 *
1404 * Returns: the #NMDevice if successfully created, %NULL if not
1405 */
1406 static NMDevice *
1407 system_create_virtual_device (NMManager *self, NMConnection *connection)
1408 {
1409 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1410 GSList *iter;
1411 char *iface = NULL;
1412 NMDevice *device = NULL, *parent = NULL;
1413
1414 iface = get_virtual_iface_name (self, connection, &parent);
1415 if (!iface) {
1416 nm_log_warn (LOGD_DEVICE, "(%s) failed to determine virtual interface name",
1417 nm_connection_get_id (connection));
1418 return NULL;
1419 }
1420
1421 /* Make sure we didn't create a device for this connection already */
1422 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1423 NMDevice *candidate = iter->data;
1424 GError *error = NULL;
1425
1426 if ( g_strcmp0 (nm_device_get_iface (candidate), iface) == 0
1427 || nm_device_check_connection_compatible (candidate, connection, &error)) {
1428 g_clear_error (&error);
1429 goto out;
1430 }
1431 g_clear_error (&error);
1432 }
1433
1434 /* Block notification of link added since we're creating the device
1435 * explicitly here, otherwise adding the platform/kernel device would
1436 * create it before this function can do the rest of the setup.
1437 */
1438 g_signal_handlers_block_by_func (nm_platform_get (), G_CALLBACK (platform_link_added_cb), self);
1439
1440 if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) {
1441 device = nm_device_bond_new_for_connection (connection);
1442 } else if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) {
1443 device = nm_device_team_new_for_connection (connection);
1444 } else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) {
1445 /* FIXME: remove when we handle bridges non-destructively */
1446 if (nm_platform_link_get_ifindex (iface) > 0 && !bridge_created_by_nm (self, iface)) {
1447 nm_log_warn (LOGD_DEVICE, "(%s): cannot use existing bridge for '%s'",
1448 iface, nm_connection_get_id (connection));
1449 } else
1450 device = nm_device_bridge_new_for_connection (connection);
1451 } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) {
1452 device = nm_device_vlan_new_for_connection (connection, parent);
1453 } else if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) {
1454 device = nm_device_infiniband_new_partition (connection, parent);
1455 }
1456
1457 if (device) {
1458 nm_device_set_is_nm_owned (device, TRUE);
1459 add_device (self, device);
1460 }
1461
1462 g_signal_handlers_unblock_by_func (nm_platform_get (), G_CALLBACK (platform_link_added_cb), self);
1463
1464 out:
1465 g_free (iface);
1466 return device;
1467 }
1468
1469 static void
1470 system_create_virtual_devices (NMManager *self)
1471 {
1472 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1473 GSList *iter, *connections;
1474
1475 nm_log_dbg (LOGD_CORE, "creating virtual devices...");
1476
1477 connections = nm_settings_get_connections (priv->settings);
1478 for (iter = connections; iter; iter = g_slist_next (iter)) {
1479 NMConnection *connection = iter->data;
1480 NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
1481
1482 g_assert (s_con);
1483 if (connection_needs_virtual_device (connection)) {
1484 /* We only create a virtual interface if the connection can autoconnect */
1485 if (nm_setting_connection_get_autoconnect (s_con))
1486 system_create_virtual_device (self, connection);
1487 }
1488 }
1489 g_slist_free (connections);
1490 }
1491
1492 static void
1493 connection_added (NMSettings *settings,
1494 NMSettingsConnection *settings_connection,
1495 NMManager *manager)
1496 {
1497 NMConnection *connection = NM_CONNECTION (settings_connection);
1498
1499 if (connection_needs_virtual_device (connection)) {
1500 NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
1501
1502 g_assert (s_con);
1503 if (nm_setting_connection_get_autoconnect (s_con))
1504 system_create_virtual_device (manager, connection);
1505 }
1506 }
1507
1508 static void
1509 connection_changed (NMSettings *settings,
1510 NMSettingsConnection *connection,
1511 NMManager *manager)
1512 {
1513 /* FIXME: Some virtual devices may need to be updated in the future. */
1514 }
1515
1516 static void
1517 connection_removed (NMSettings *settings,
1518 NMSettingsConnection *connection,
1519 NMManager *manager)
1520 {
1521 /*
1522 * Do not delete existing virtual devices to keep connectivity up.
1523 * Virtual devices are reused when NetworkManager is restarted.
1524 */
1525 }
1526
1527 static void
1528 system_unmanaged_devices_changed_cb (NMSettings *settings,
1529 GParamSpec *pspec,
1530 gpointer user_data)
1531 {
1532 NMManager *self = NM_MANAGER (user_data);
1533 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1534 const GSList *unmanaged_specs, *iter;
1535
1536 unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
1537 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1538 NMDevice *device = NM_DEVICE (iter->data);
1539 gboolean managed;
1540
1541 managed = !nm_device_spec_match_list (device, unmanaged_specs);
1542 nm_device_set_manager_managed (device,
1543 managed,
1544 managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED :
1545 NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
1546 }
1547 }
1548
1549 static void
1550 system_hostname_changed_cb (NMSettings *settings,
1551 GParamSpec *pspec,
1552 gpointer user_data)
1553 {
1554 NMManager *self = NM_MANAGER (user_data);
1555 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1556 char *hostname;
1557
1558 hostname = nm_settings_get_hostname (priv->settings);
1559 if (!hostname && !priv->hostname)
1560 return;
1561 if (hostname && priv->hostname && !strcmp (hostname, priv->hostname))
1562 return;
1563
1564 g_free (priv->hostname);
1565 priv->hostname = (hostname && strlen (hostname)) ? g_strdup (hostname) : NULL;
1566 g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
1567
1568 g_free (hostname);
1569 }
1570
1571 /*******************************************************************/
1572 /* General NMManager stuff */
1573 /*******************************************************************/
1574
1575 /* Store value into key-file; supported types: boolean, int, string */
1576 static gboolean
1577 write_value_to_state_file (const char *filename,
1578 const char *group,
1579 const char *key,
1580 GType value_type,
1581 gpointer value,
1582 GError **error)
1583 {
1584 GKeyFile *key_file;
1585 char *data;
1586 gsize len = 0;
1587 gboolean ret = FALSE;
1588
1589 g_return_val_if_fail (filename != NULL, FALSE);
1590 g_return_val_if_fail (group != NULL, FALSE);
1591 g_return_val_if_fail (key != NULL, FALSE);
1592 g_return_val_if_fail (value_type == G_TYPE_BOOLEAN ||
1593 value_type == G_TYPE_INT ||
1594 value_type == G_TYPE_STRING,
1595 FALSE);
1596
1597 key_file = g_key_file_new ();
1598
1599 g_key_file_set_list_separator (key_file, ',');
1600 g_key_file_load_from_file (key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
1601 switch (value_type) {
1602 case G_TYPE_BOOLEAN:
1603 g_key_file_set_boolean (key_file, group, key, *((gboolean *) value));
1604 break;
1605 case G_TYPE_INT:
1606 g_key_file_set_integer (key_file, group, key, *((gint *) value));
1607 break;
1608 case G_TYPE_STRING:
1609 g_key_file_set_string (key_file, group, key, *((const gchar **) value));
1610 break;
1611 }
1612
1613 data = g_key_file_to_data (key_file, &len, NULL);
1614 if (data) {
1615 ret = g_file_set_contents (filename, data, len, error);
1616 g_free (data);
1617 }
1618 g_key_file_free (key_file);
1619
1620 return ret;
1621 }
1622
1623 static gboolean
1624 radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
1625 {
1626 gboolean enabled;
1627
1628 enabled = rstate->user_enabled && rstate->hw_enabled;
1629 if (check_changeable) {
1630 enabled &= rstate->sw_enabled;
1631 if (rstate->daemon_enabled_func)
1632 enabled &= rstate->daemon_enabled;
1633 }
1634 return enabled;
1635 }
1636
1637 static gboolean
1638 radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
1639 {
1640 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1641
1642 return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
1643 }
1644
1645 static void
1646 manager_update_radio_enabled (NMManager *self,
1647 RadioState *rstate,
1648 gboolean enabled)
1649 {
1650 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1651 GSList *iter;
1652
1653 /* Do nothing for radio types not yet implemented */
1654 if (!rstate->prop)
1655 return;
1656
1657 g_object_notify (G_OBJECT (self), rstate->prop);
1658
1659 /* Don't touch devices if asleep/networking disabled */
1660 if (manager_sleeping (self))
1661 return;
1662
1663 /* enable/disable wireless devices as required */
1664 for (iter = priv->devices; iter; iter = iter->next) {
1665 NMDevice *device = NM_DEVICE (iter->data);
1666
1667 if (nm_device_get_rfkill_type (device) == rstate->rtype) {
1668 nm_log_dbg (LOGD_RFKILL, "(%s): setting radio %s",
1669 nm_device_get_iface (device),
1670 enabled ? "enabled" : "disabled");
1671 nm_device_set_enabled (device, enabled);
1672 }
1673 }
1674 }
1675
1676 static void
1677 manager_hidden_ap_found (NMDevice *device,
1678 NMAccessPoint *ap,
1679 gpointer user_data)
1680 {
1681 NMManager *manager = NM_MANAGER (user_data);
1682 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
1683 const struct ether_addr *bssid;
1684 GSList *iter;
1685 GSList *connections;
1686 gboolean done = FALSE;
1687
1688 g_return_if_fail (nm_ap_get_ssid (ap) == NULL);
1689
1690 bssid = nm_ap_get_address (ap);
1691 g_assert (bssid);
1692
1693 /* Look for this AP's BSSID in the seen-bssids list of a connection,
1694 * and if a match is found, copy over the SSID */
1695 connections = nm_settings_get_connections (priv->settings);
1696 for (iter = connections; iter && !done; iter = g_slist_next (iter)) {
1697 NMConnection *connection = NM_CONNECTION (iter->data);
1698 NMSettingWireless *s_wifi;
1699
1700 s_wifi = nm_connection_get_setting_wireless (connection);
1701 if (s_wifi) {
1702 if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid))
1703 nm_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi));
1704 }
1705 }
1706 g_slist_free (connections);
1707 }
1708
1709 static RfKillState
1710 nm_manager_get_ipw_rfkill_state (NMManager *self)
1711 {
1712 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1713 GSList *iter;
1714 RfKillState ipw_state = RFKILL_UNBLOCKED;
1715
1716 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1717 NMDevice *candidate = NM_DEVICE (iter->data);
1718 RfKillState candidate_state;
1719
1720 if (nm_device_get_device_type (candidate) == NM_DEVICE_TYPE_WIFI) {
1721 candidate_state = nm_device_wifi_get_ipw_rfkill_state (NM_DEVICE_WIFI (candidate));
1722
1723 if (candidate_state > ipw_state)
1724 ipw_state = candidate_state;
1725 }
1726 }
1727
1728 return ipw_state;
1729 }
1730
1731 static RfKillState
1732 nm_manager_get_modem_enabled_state (NMManager *self)
1733 {
1734 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1735 GSList *iter;
1736 RfKillState wwan_state = RFKILL_UNBLOCKED;
1737
1738 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
1739 NMDevice *candidate = NM_DEVICE (iter->data);
1740 RfKillState candidate_state = RFKILL_UNBLOCKED;
1741
1742 if (nm_device_get_rfkill_type (candidate) == RFKILL_TYPE_WWAN) {
1743 if (!nm_device_get_enabled (candidate))
1744 candidate_state = RFKILL_SOFT_BLOCKED;
1745
1746 if (candidate_state > wwan_state)
1747 wwan_state = candidate_state;
1748 }
1749 }
1750
1751 return wwan_state;
1752 }
1753
1754 static void
1755 update_rstate_from_rfkill (RadioState *rstate, RfKillState rfkill)
1756 {
1757 if (rfkill == RFKILL_UNBLOCKED) {
1758 rstate->sw_enabled = TRUE;
1759 rstate->hw_enabled = TRUE;
1760 } else if (rfkill == RFKILL_SOFT_BLOCKED) {
1761 rstate->sw_enabled = FALSE;
1762 rstate->hw_enabled = TRUE;
1763 } else if (rfkill == RFKILL_HARD_BLOCKED) {
1764 rstate->sw_enabled = FALSE;
1765 rstate->hw_enabled = FALSE;
1766 }
1767 }
1768
1769 static void
1770 manager_rfkill_update_one_type (NMManager *self,
1771 RadioState *rstate,
1772 RfKillType rtype)
1773 {
1774 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1775 RfKillState udev_state = RFKILL_UNBLOCKED;
1776 RfKillState other_state = RFKILL_UNBLOCKED;
1777 RfKillState composite;
1778 gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled;
1779 gboolean old_hwe, old_daemon_enabled = FALSE;
1780
1781 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
1782 old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1783 old_hwe = rstate->hw_enabled;
1784
1785 udev_state = nm_rfkill_manager_get_rfkill_state (priv->rfkill_mgr, rtype);
1786
1787 if (rstate->other_enabled_func)
1788 other_state = rstate->other_enabled_func (self);
1789
1790 /* The composite state is the "worst" of either udev or other states */
1791 if (udev_state == RFKILL_HARD_BLOCKED || other_state == RFKILL_HARD_BLOCKED)
1792 composite = RFKILL_HARD_BLOCKED;
1793 else if (udev_state == RFKILL_SOFT_BLOCKED || other_state == RFKILL_SOFT_BLOCKED)
1794 composite = RFKILL_SOFT_BLOCKED;
1795 else
1796 composite = RFKILL_UNBLOCKED;
1797
1798 update_rstate_from_rfkill (rstate, composite);
1799
1800 /* If the device has a management daemon that can affect enabled state, check that now */
1801 if (rstate->daemon_enabled_func) {
1802 old_daemon_enabled = rstate->daemon_enabled;
1803 rstate->daemon_enabled = (rstate->daemon_enabled_func (self) == RFKILL_UNBLOCKED);
1804 if (old_daemon_enabled != rstate->daemon_enabled) {
1805 nm_log_info (LOGD_RFKILL, "%s now %s by management service",
1806 rstate->desc,
1807 rstate->daemon_enabled ? "enabled" : "disabled");
1808 }
1809 }
1810
1811 /* Print out all states affecting device enablement */
1812 if (rstate->desc) {
1813 if (rstate->daemon_enabled_func) {
1814 nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d daemon-enabled %d",
1815 rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->daemon_enabled);
1816 } else {
1817 nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
1818 rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
1819 }
1820 }
1821
1822 /* Log new killswitch state */
1823 new_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
1824 if (old_rfkilled != new_rfkilled) {
1825 nm_log_info (LOGD_RFKILL, "%s now %s by radio killswitch",
1826 rstate->desc,
1827 new_rfkilled ? "enabled" : "disabled");
1828 }
1829
1830 /* Send out property changed signal for HW enabled */
1831 if (rstate->hw_enabled != old_hwe) {
1832 if (rstate->hw_prop)
1833 g_object_notify (G_OBJECT (self), rstate->hw_prop);
1834 }
1835
1836 /* And finally update the actual device radio state itself; respect the
1837 * daemon state here because this is never called from user-triggered
1838 * radio changes and we only want to ignore the daemon enabled state when
1839 * handling user radio change requests.
1840 */
1841 new_enabled = radio_enabled_for_rstate (rstate, TRUE);
1842 if (new_enabled != old_enabled)
1843 manager_update_radio_enabled (self, rstate, new_enabled);
1844 }
1845
1846 static void
1847 nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
1848 {
1849 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1850 guint i;
1851
1852 if (rtype != RFKILL_TYPE_UNKNOWN)
1853 manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
1854 else {
1855 /* Otherwise sync all radio types */
1856 for (i = 0; i < RFKILL_TYPE_MAX; i++)
1857 manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
1858 }
1859 }
1860
1861 static void
1862 manager_ipw_rfkill_state_changed (NMDeviceWifi *device,
1863 GParamSpec *pspec,
1864 gpointer user_data)
1865 {
1866 nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WLAN);
1867 }
1868
1869 static void
1870 manager_modem_enabled_changed (NMDevice *device, gpointer user_data)
1871 {
1872 nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WWAN);
1873 }
1874
1875 static void
1876 device_auth_done_cb (NMAuthChain *chain,
1877 GError *auth_error,
1878 DBusGMethodInvocation *context,
1879 gpointer user_data)
1880 {
1881 NMManager *self = NM_MANAGER (user_data);
1882 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1883 GError *error = NULL;
1884 NMAuthCallResult result;
1885 NMDevice *device;
1886 const char *permission;
1887 NMDeviceAuthRequestFunc callback;
1888
1889 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
1890
1891 permission = nm_auth_chain_get_data (chain, "requested-permission");
1892 g_assert (permission);
1893 callback = nm_auth_chain_get_data (chain, "callback");
1894 g_assert (callback);
1895 device = nm_auth_chain_get_data (chain, "device");
1896 g_assert (device);
1897
1898 result = nm_auth_chain_get_result (chain, permission);
1899
1900 if (auth_error) {
1901 /* translate the auth error into a manager permission denied error */
1902 nm_log_dbg (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
1903 error = g_error_new (NM_MANAGER_ERROR,
1904 NM_MANAGER_ERROR_PERMISSION_DENIED,
1905 "%s request failed: %s",
1906 permission, auth_error->message);
1907 } else if (result != NM_AUTH_CALL_RESULT_YES) {
1908 nm_log_dbg (LOGD_CORE, "%s request failed: not authorized", permission);
1909 error = g_error_new (NM_MANAGER_ERROR,
1910 NM_MANAGER_ERROR_PERMISSION_DENIED,
1911 "%s request failed: not authorized",
1912 permission);
1913 }
1914
1915 g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
1916
1917 callback (device,
1918 context,
1919 error,
1920 nm_auth_chain_get_data (chain, "user-data"));
1921
1922 g_clear_error (&error);
1923 nm_auth_chain_unref (chain);
1924 }
1925
1926 static void
1927 device_auth_request_cb (NMDevice *device,
1928 DBusGMethodInvocation *context,
1929 const char *permission,
1930 gboolean allow_interaction,
1931 NMDeviceAuthRequestFunc callback,
1932 gpointer user_data,
1933 NMManager *self)
1934 {
1935 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
1936 GError *error = NULL;
1937 NMAuthChain *chain;
1938 const char *error_desc = NULL;
1939
1940 /* Validate the request */
1941 chain = nm_auth_chain_new (context, device_auth_done_cb, self, &error_desc);
1942 if (chain) {
1943 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
1944
1945 nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
1946 nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
1947 nm_auth_chain_set_data (chain, "callback", callback, NULL);
1948 nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
1949 nm_auth_chain_add_call (chain, permission, allow_interaction);
1950 } else {
1951 error = g_error_new_literal (NM_MANAGER_ERROR,
1952 NM_MANAGER_ERROR_PERMISSION_DENIED,
1953 error_desc);
1954 callback (device, context, error, user_data);
1955 g_error_free (error);
1956 }
1957 }
1958
1959 /* This should really be moved to gsystem. */
1960 #define free_slist __attribute__ ((cleanup(local_slist_free)))
1961 static void
1962 local_slist_free (void *loc)
1963 {
1964 GSList **location = loc;
1965
1966 if (location)
1967 g_slist_free (*location);
1968 }
1969
1970 /**
1971 * get_connection:
1972 * @manager: #NMManager instance
1973 * @device: #NMDevice instance
1974 *
1975 * Returns one of the following:
1976 *
1977 * 1) An existing #NMSettingsConnection to be assumed.
1978 *
1979 * 2) A generated #NMConnection to be assumed. You can distinguish this
1980 * case using NM_IS_SETTINGS_CONNECTION().
1981 *
1982 * 3) %NULL when no connection was detected or the @device doesn't support
1983 * generating connections.
1984 *
1985 * Supports both nm-device's match_l2_config() and update_connection().
1986 */
1987 static NMConnection *
1988 get_connection (NMManager *manager, NMDevice *device)
1989 {
1990 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
1991 free_slist GSList *connections = nm_settings_get_connections (priv->settings);
1992 NMConnection *connection = NULL;
1993 GSList *iter;
1994
1995 /* We still support the older API to match a NMDevice object to an
1996 * existing connection using nm_device_find_assumable_connection().
1997 *
1998 * When the older API is still available for a particular device
1999 * type, we use it. To opt for the newer interface, the NMDevice
2000 * subclass must omit the match_l2_config virtual function
2001 * implementation.
2002 */
2003 if (NM_DEVICE_GET_CLASS (device)->match_l2_config) {
2004 NMConnection *candidate = nm_device_find_assumable_connection (device, connections);
2005
2006 if (candidate) {
2007 nm_log_info (LOGD_DEVICE, "(%s): Found matching connection '%s' (legacy API)",
2008 nm_device_get_iface (device),
2009 nm_connection_get_id (candidate));
2010 return candidate;
2011 }
2012 }
2013
2014 /* The core of the API is nm_device_generate_connection() function and
2015 * update_connection() virtual method and the convenient connection_type
2016 * class attribute. Subclasses supporting the new API must have
2017 * update_connection() implemented, otherwise nm_device_generate_connection()
2018 * returns NULL.
2019 */
2020 connection = nm_device_generate_connection (device);
2021 if (!connection) {
2022 nm_log_info (LOGD_DEVICE, "(%s): No existing connection detected.",
2023 nm_device_get_iface (device));
2024 return NULL;
2025 }
2026
2027 /* Now we need to compare the generated connection to each configured
2028 * connection. The comparison function is the heart of the connection
2029 * assumption implementation and it must compare the connections very
2030 * carefully to sort out various corner cases. Also, the comparison is
2031 * not entirely symmetric.
2032 *
2033 * When no configured connection matches the generated connection, we keep
2034 * the generated connection instead.
2035 */
2036 for (iter = connections; iter; iter = iter->next) {
2037 NMConnection *candidate = NM_CONNECTION (iter->data);
2038
2039 if (nm_connection_compare (connection, candidate, NM_SETTING_COMPARE_FLAG_CANDIDATE)) {
2040 nm_log_info (LOGD_DEVICE, "(%s): Found matching connection: '%s'",
2041 nm_device_get_iface (device),
2042 nm_connection_get_id (candidate));
2043 g_object_unref (connection);
2044 return candidate;
2045 }
2046 }
2047
2048 nm_log_info (LOGD_DEVICE, "(%s): Using generated connection: '%s'",
2049 nm_device_get_iface (device),
2050 nm_connection_get_id (connection));
2051 return connection;
2052 }
2053
2054 static void
2055 add_device (NMManager *self, NMDevice *device)
2056 {
2057 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2058 const char *iface, *driver, *type_desc;
2059 char *path;
2060 static guint32 devcount = 0;
2061 const GSList *unmanaged_specs;
2062 NMConnection *connection;
2063 gboolean enabled = FALSE;
2064 RfKillType rtype;
2065 NMDeviceType devtype;
2066
2067 iface = nm_device_get_ip_iface (device);
2068 g_assert (iface);
2069
2070 devtype = nm_device_get_device_type (device);
2071
2072 /* Ignore the device if we already know about it. But some modems will
2073 * provide pseudo-ethernet devices that NM has already claimed while
2074 * ModemManager is still detecting the modem's serial ports, so when the
2075 * MM modem object finally shows up it may have the same IP interface as the
2076 * ethernet interface we've already detected. In this case we skip the
2077 * check for an existing device with the same IP interface name and kill
2078 * the ethernet device later in favor of the modem device.
2079 */
2080 if ((devtype != NM_DEVICE_TYPE_MODEM) && find_device_by_ip_iface (self, iface)) {
2081 g_object_unref (device);
2082 return;
2083 }
2084
2085 nm_device_set_connection_provider (device, NM_CONNECTION_PROVIDER (priv->settings));
2086
2087 priv->devices = g_slist_append (priv->devices, device);
2088
2089 g_signal_connect (device, "state-changed",
2090 G_CALLBACK (manager_device_state_changed),
2091 self);
2092
2093 g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
2094 G_CALLBACK (device_auth_request_cb),
2095 self);
2096
2097 if (priv->startup) {
2098 g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
2099 G_CALLBACK (device_has_pending_action_changed),
2100 self);
2101 }
2102
2103 if (devtype == NM_DEVICE_TYPE_WIFI) {
2104 /* Attach to the access-point-added signal so that the manager can fill
2105 * non-SSID-broadcasting APs with an SSID.
2106 */
2107 g_signal_connect (device, "hidden-ap-found",
2108 G_CALLBACK (manager_hidden_ap_found),
2109 self);
2110
2111 /* Hook up rfkill handling for ipw-based cards until they get converted
2112 * to use the kernel's rfkill subsystem in 2.6.33.
2113 */
2114 g_signal_connect (device, "notify::" NM_DEVICE_WIFI_IPW_RFKILL_STATE,
2115 G_CALLBACK (manager_ipw_rfkill_state_changed),
2116 self);
2117 } else if (devtype == NM_DEVICE_TYPE_MODEM) {
2118 g_signal_connect (device, NM_DEVICE_MODEM_ENABLE_CHANGED,
2119 G_CALLBACK (manager_modem_enabled_changed),
2120 self);
2121 }
2122
2123 /* Update global rfkill state for this device type with the device's
2124 * rfkill state, and then set this device's rfkill state based on the
2125 * global state.
2126 */
2127 rtype = nm_device_get_rfkill_type (device);
2128 if (rtype != RFKILL_TYPE_UNKNOWN) {
2129 nm_manager_rfkill_update (self, rtype);
2130 enabled = radio_enabled_for_type (self, rtype, TRUE);
2131 nm_device_set_enabled (device, enabled);
2132 }
2133
2134 type_desc = nm_device_get_type_desc (device);
2135 g_assert (type_desc);
2136 driver = nm_device_get_driver (device);
2137 if (!driver)
2138 driver = "unknown";
2139 nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s' ifindex: %d)",
2140 iface, type_desc, driver, nm_device_get_ifindex (device));
2141
2142 path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++);
2143 nm_device_set_path (device, path);
2144 nm_dbus_manager_register_object (priv->dbus_mgr, path, device);
2145 nm_log_info (LOGD_CORE, "(%s): exported as %s", iface, path);
2146 g_free (path);
2147
2148 connection = get_connection (self, device);
2149
2150 /* Start the device if it's supposed to be managed */
2151 unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
2152 if ( !manager_sleeping (self)
2153 && !nm_device_spec_match_list (device, unmanaged_specs)) {
2154 nm_device_set_manager_managed (device,
2155 TRUE,
2156 connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED :
2157 NM_DEVICE_STATE_REASON_NOW_MANAGED);
2158 }
2159
2160 nm_settings_device_added (priv->settings, device);
2161 g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
2162
2163 /* New devices might be master interfaces for virtual interfaces; so we may
2164 * need to create new virtual interfaces now.
2165 */
2166 system_create_virtual_devices (self);
2167
2168 /* If the device has a connection it can assume, do that now */
2169 if (connection && nm_device_can_activate (device, connection)) {
2170 NMActiveConnection *ac;
2171 GError *error = NULL;
2172
2173 nm_log_dbg (LOGD_DEVICE, "(%s): will attempt to assume connection",
2174 nm_device_get_iface (device));
2175
2176 ac = internal_activate_device (self, device, connection, NULL, FALSE, 0, NULL, TRUE, NULL, &error);
2177 if (ac)
2178 active_connection_add (self, ac);
2179 else {
2180 nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s",
2181 nm_connection_get_path (connection),
2182 error ? error->code : -1,
2183 error && error->message ? error->message : "(unknown)");
2184 g_error_free (error);
2185 }
2186 }
2187 }
2188
2189 static void
2190 bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
2191 NMBluezDevice *bt_device,
2192 const char *bdaddr,
2193 const char *name,
2194 const char *object_path,
2195 guint32 capabilities,
2196 NMManager *manager)
2197 {
2198 NMDevice *device;
2199 gboolean has_dun = (capabilities & NM_BT_CAPABILITY_DUN);
2200 gboolean has_nap = (capabilities & NM_BT_CAPABILITY_NAP);
2201
2202 g_return_if_fail (bdaddr != NULL);
2203 g_return_if_fail (name != NULL);
2204 g_return_if_fail (object_path != NULL);
2205 g_return_if_fail (capabilities != NM_BT_CAPABILITY_NONE);
2206 g_return_if_fail (NM_IS_BLUEZ_DEVICE (bt_device));
2207
2208 /* Make sure the device is not already in the device list */
2209 if (nm_manager_get_device_by_udi (manager, object_path))
2210 return;
2211
2212 device = nm_device_bt_new (bt_device, object_path, bdaddr, name, capabilities);
2213 if (device) {
2214 nm_log_info (LOGD_HW, "BT device %s (%s) added (%s%s%s)",
2215 name,
2216 bdaddr,
2217 has_dun ? "DUN" : "",
2218 has_dun && has_nap ? " " : "",
2219 has_nap ? "NAP" : "");
2220
2221 add_device (manager, device);
2222 }
2223 }
2224
2225 static void
2226 bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
2227 const char *bdaddr,
2228 const char *object_path,
2229 gpointer user_data)
2230 {
2231 NMManager *self = NM_MANAGER (user_data);
2232 NMDevice *device;
2233
2234 g_return_if_fail (bdaddr != NULL);
2235 g_return_if_fail (object_path != NULL);
2236
2237 device = nm_manager_get_device_by_udi (self, object_path);
2238 if (device) {
2239 nm_log_info (LOGD_HW, "BT device %s removed", bdaddr);
2240 remove_device (self, device, FALSE);
2241 }
2242 }
2243
2244 static NMDevice *
2245 find_device_by_ip_iface (NMManager *self, const gchar *iface)
2246 {
2247 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2248 GSList *iter;
2249
2250 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2251 NMDevice *candidate = iter->data;
2252
2253 if (g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
2254 return candidate;
2255 }
2256 return NULL;
2257 }
2258
2259 static NMDevice *
2260 find_device_by_iface (NMManager *self, const gchar *iface)
2261 {
2262 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2263 GSList *iter;
2264
2265 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2266 NMDevice *candidate = iter->data;
2267
2268 if (g_strcmp0 (nm_device_get_iface (candidate), iface) == 0)
2269 return candidate;
2270 }
2271 return NULL;
2272 }
2273
2274 static NMDevice *
2275 find_device_by_ifindex (NMManager *self, guint32 ifindex)
2276 {
2277 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2278 GSList *iter;
2279
2280 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2281 NMDevice *candidate = NM_DEVICE (iter->data);
2282
2283 if (ifindex == nm_device_get_ifindex (candidate))
2284 return candidate;
2285 }
2286 return NULL;
2287 }
2288
2289 #define PLUGIN_PREFIX "libnm-device-plugin-"
2290
2291 typedef struct {
2292 NMDeviceType t;
2293 guint priority;
2294 NMDeviceFactoryCreateFunc create_func;
2295 } PluginInfo;
2296
2297 static gint
2298 plugin_sort (PluginInfo *a, PluginInfo *b)
2299 {
2300 /* Higher priority means sort earlier in the list (ie, return -1) */
2301 if (a->priority > b->priority)
2302 return -1;
2303 else if (a->priority < b->priority)
2304 return 1;
2305 return 0;
2306 }
2307
2308 static void
2309 load_device_factories (NMManager *self)
2310 {
2311 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2312 GDir *dir;
2313 GError *error = NULL;
2314 const char *item;
2315 char *path;
2316 GSList *list = NULL, *iter;
2317
2318 dir = g_dir_open (NMPLUGINDIR, 0, &error);
2319 if (!dir) {
2320 nm_log_warn (LOGD_HW, "Failed to open plugin directory %s: %s",
2321 NMPLUGINDIR,
2322 (error && error->message) ? error->message : "(unknown)");
2323 g_clear_error (&error);
2324 return;
2325 }
2326
2327 while ((item = g_dir_read_name (dir))) {
2328 GModule *plugin;
2329 NMDeviceFactoryCreateFunc create_func;
2330 NMDeviceFactoryPriorityFunc priority_func;
2331 NMDeviceFactoryTypeFunc type_func;
2332 PluginInfo *info = NULL;
2333 NMDeviceType plugin_type;
2334
2335 if (!g_str_has_prefix (item, PLUGIN_PREFIX))
2336 continue;
2337
2338 path = g_module_build_path (NMPLUGINDIR, item);
2339 g_assert (path);
2340 plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
2341 g_free (path);
2342
2343 if (!plugin) {
2344 nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ());
2345 continue;
2346 }
2347
2348 if (!g_module_symbol (plugin, "nm_device_factory_get_type", (gpointer) (&type_func))) {
2349 nm_log_warn (LOGD_HW, "(%s): failed to find device factory: %s", item, g_module_error ());
2350 g_module_close (plugin);
2351 continue;
2352 }
2353
2354 /* Make sure we don't double-load plugins */
2355 plugin_type = type_func ();
2356 for (iter = list; iter; iter = g_slist_next (iter)) {
2357 PluginInfo *candidate = iter->data;
2358
2359 if (plugin_type == candidate->t) {
2360 info = candidate;
2361 break;
2362 }
2363 }
2364 if (info) {
2365 g_module_close (plugin);
2366 continue;
2367 }
2368
2369 if (!g_module_symbol (plugin, "nm_device_factory_create_device", (gpointer) (&create_func))) {
2370 nm_log_warn (LOGD_HW, "(%s): failed to find device creator: %s", item, g_module_error ());
2371 g_module_close (plugin);
2372 continue;
2373 }
2374
2375 info = g_malloc0 (sizeof (*info));
2376 info->create_func = create_func;
2377 info->t = plugin_type;
2378
2379 /* Grab priority; higher number equals higher priority */
2380 if (g_module_symbol (plugin, "nm_device_factory_get_priority", (gpointer) (&priority_func)))
2381 info->priority = priority_func ();
2382 else {
2383 nm_log_dbg (LOGD_HW, "(%s): failed to find device factory priority func: %s",
2384 item, g_module_error ());
2385 }
2386
2387 g_module_make_resident (plugin);
2388 list = g_slist_insert_sorted (list, info, (GCompareFunc) plugin_sort);
2389
2390 nm_log_info (LOGD_HW, "Loaded device factory: %s", g_module_name (plugin));
2391 };
2392 g_dir_close (dir);
2393
2394 /* Ditch the priority info and copy the factory functions to our private data */
2395 for (iter = list; iter; iter = g_slist_next (iter)) {
2396 PluginInfo *info = iter->data;
2397
2398 priv->factories = g_slist_append (priv->factories, info->create_func);
2399 g_free (info);
2400 }
2401 g_slist_free (list);
2402 }
2403
2404 static void
2405 platform_link_added_cb (NMPlatform *platform,
2406 int ifindex,
2407 NMPlatformLink *plink,
2408 NMPlatformReason reason,
2409 gpointer user_data)
2410 {
2411 NMManager *self = NM_MANAGER (user_data);
2412 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2413 NMDevice *device = NULL;
2414 GSList *iter;
2415 GError *error = NULL;
2416
2417 g_return_if_fail (ifindex > 0);
2418
2419 if (find_device_by_ifindex (self, ifindex))
2420 return;
2421
2422 /* Try registered device factories */
2423 for (iter = priv->factories; iter; iter = g_slist_next (iter)) {
2424 NMDeviceFactoryCreateFunc create_func = iter->data;
2425
2426 g_clear_error (&error);
2427 device = (NMDevice *) create_func (plink, &error);
2428 if (device && NM_IS_DEVICE (device)) {
2429 g_assert_no_error (error);
2430 break; /* success! */
2431 }
2432
2433 if (error) {
2434 nm_log_warn (LOGD_HW, "%s: factory failed to create device: (%d) %s",
2435 plink->udi,
2436 error ? error->code : -1,
2437 error ? error->message : "(unknown)");
2438 g_clear_error (&error);
2439 return;
2440 }
2441 }
2442
2443 if (device == NULL) {
2444 int parent_ifindex = -1;
2445 NMDevice *parent;
2446
2447 switch (plink->type) {
2448 case NM_LINK_TYPE_ETHERNET:
2449 device = nm_device_ethernet_new (plink);
2450 break;
2451 case NM_LINK_TYPE_INFINIBAND:
2452 device = nm_device_infiniband_new (plink);
2453 break;
2454 case NM_LINK_TYPE_OLPC_MESH:
2455 device = nm_device_olpc_mesh_new (plink);
2456 break;
2457 case NM_LINK_TYPE_WIFI:
2458 device = nm_device_wifi_new (plink);
2459 break;
2460 case NM_LINK_TYPE_BOND:
2461 device = nm_device_bond_new (plink);
2462 break;
2463 case NM_LINK_TYPE_TEAM:
2464 device = nm_device_team_new (plink);
2465 break;
2466 case NM_LINK_TYPE_BRIDGE:
2467 /* FIXME: always create device when we handle bridges non-destructively */
2468 if (bridge_created_by_nm (self, plink->name))
2469 device = nm_device_bridge_new (plink);
2470 else
2471 nm_log_info (LOGD_BRIDGE, "(%s): ignoring bridge not created by NetworkManager", plink->name);
2472 break;
2473 case NM_LINK_TYPE_VLAN:
2474 /* Have to find the parent device */
2475 if (nm_platform_vlan_get_info (ifindex, &parent_ifindex, NULL)) {
2476 parent = find_device_by_ifindex (self, parent_ifindex);
2477 if (parent)
2478 device = nm_device_vlan_new (plink, parent);
2479 else {
2480 /* If udev signaled the VLAN interface before it signaled
2481 * the VLAN's parent at startup we may not know about the
2482 * parent device yet. But we'll find it on the second pass
2483 * from nm_manager_start().
2484 */
2485 nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", plink->name);
2486 }
2487 } else
2488 nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", plink->name);
2489 break;
2490 case NM_LINK_TYPE_VETH:
2491 device = nm_device_veth_new (plink);
2492 break;
2493 case NM_LINK_TYPE_TUN:
2494 case NM_LINK_TYPE_TAP:
2495 device = nm_device_tun_new (plink);
2496 break;
2497 case NM_LINK_TYPE_MACVLAN:
2498 case NM_LINK_TYPE_MACVTAP:
2499 device = nm_device_macvlan_new (plink);
2500 break;
2501 case NM_LINK_TYPE_GRE:
2502 case NM_LINK_TYPE_GRETAP:
2503 device = nm_device_gre_new (plink);
2504 break;
2505
2506 case NM_LINK_TYPE_WWAN_ETHERNET:
2507 /* WWAN pseudo-ethernet interfaces are handled automatically by
2508 * their NMDeviceModem and don't get a separate NMDevice object.
2509 */
2510 break;
2511
2512 case NM_LINK_TYPE_WIMAX:
2513 /* If the WiMAX plugin is not installed, we can't control the
2514 * interface, so ignore it.
2515 */
2516 break;
2517
2518 default:
2519 device = nm_device_generic_new (plink);
2520 break;
2521 }
2522 }
2523
2524 if (device)
2525 add_device (self, device);
2526 }
2527
2528 static void
2529 platform_link_removed_cb (NMPlatform *platform,
2530 int ifindex,
2531 NMPlatformLink *plink,
2532 NMPlatformReason reason,
2533 gpointer user_data)
2534 {
2535 NMManager *self = NM_MANAGER (user_data);
2536 NMDevice *device;
2537
2538 device = find_device_by_ifindex (self, ifindex);
2539 if (device)
2540 remove_device (self, device, FALSE);
2541 }
2542
2543 static void
2544 atm_device_added_cb (NMAtmManager *atm_mgr,
2545 const char *iface,
2546 const char *sysfs_path,
2547 const char *driver,
2548 gpointer user_data)
2549 {
2550 NMManager *self = NM_MANAGER (user_data);
2551 NMDevice *device;
2552
2553 g_return_if_fail (iface != NULL);
2554 g_return_if_fail (sysfs_path != NULL);
2555
2556 device = find_device_by_iface (self, iface);
2557 if (device)
2558 return;
2559
2560 device = nm_device_adsl_new (sysfs_path, iface, driver);
2561 if (device)
2562 add_device (self, device);
2563 }
2564
2565 static void
2566 atm_device_removed_cb (NMAtmManager *manager,
2567 const char *iface,
2568 gpointer user_data)
2569 {
2570 NMManager *self = NM_MANAGER (user_data);
2571 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2572 NMDevice *device = NULL;
2573 GSList *iter;
2574
2575 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2576 if (g_strcmp0 (nm_device_get_iface (NM_DEVICE (iter->data)), iface) == 0) {
2577 device = iter->data;
2578 break;
2579 }
2580 }
2581
2582 if (device)
2583 remove_device (self, device, FALSE);
2584 }
2585
2586 static void
2587 rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
2588 RfKillType rtype,
2589 RfKillState udev_state,
2590 gpointer user_data)
2591 {
2592 nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
2593 }
2594
2595 GSList *
2596 nm_manager_get_devices (NMManager *manager)
2597 {
2598 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2599
2600 return NM_MANAGER_GET_PRIVATE (manager)->devices;
2601 }
2602
2603 static gboolean
2604 impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err)
2605 {
2606 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
2607 GSList *iter;
2608
2609 *devices = g_ptr_array_sized_new (g_slist_length (priv->devices));
2610
2611 for (iter = priv->devices; iter; iter = iter->next)
2612 g_ptr_array_add (*devices, g_strdup (nm_device_get_path (NM_DEVICE (iter->data))));
2613
2614 return TRUE;
2615 }
2616
2617 static gboolean
2618 impl_manager_get_device_by_ip_iface (NMManager *self,
2619 const char *iface,
2620 char **out_object_path,
2621 GError **error)
2622 {
2623 NMDevice *device;
2624 const char *path = NULL;
2625
2626 device = find_device_by_ip_iface (self, iface);
2627 if (device) {
2628 path = nm_device_get_path (device);
2629 if (path)
2630 *out_object_path = g_strdup (path);
2631 }
2632
2633 if (path == NULL) {
2634 g_set_error_literal (error,
2635 NM_MANAGER_ERROR,
2636 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2637 "No device found for the requested iface.");
2638 }
2639
2640 return path ? TRUE : FALSE;
2641 }
2642
2643 static NMActiveConnection *
2644 internal_activate_device (NMManager *manager,
2645 NMDevice *device,
2646 NMConnection *connection,
2647 const char *specific_object,
2648 gboolean user_requested,
2649 gulong sender_uid,
2650 const char *dbus_sender,
2651 gboolean assumed,
2652 NMActiveConnection *master,
2653 GError **error)
2654 {
2655 NMActRequest *req;
2656 NMDevice *master_device = NULL;
2657
2658 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2659 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2660 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
2661
2662 /* Ensure the requested connection is compatible with the device */
2663 if (!nm_device_check_connection_compatible (device, connection, error))
2664 return NULL;
2665
2666 /* Tear down any existing connection */
2667 if (nm_device_get_act_request (device)) {
2668 nm_log_info (LOGD_DEVICE, "(%s): disconnecting for new activation request.",
2669 nm_device_get_iface (device));
2670 nm_device_state_changed (device,
2671 NM_DEVICE_STATE_DISCONNECTED,
2672 NM_DEVICE_STATE_REASON_NONE);
2673 }
2674
2675 if (master)
2676 master_device = nm_active_connection_get_device (master);
2677
2678 req = nm_act_request_new (connection,
2679 specific_object,
2680 user_requested,
2681 sender_uid,
2682 dbus_sender,
2683 device,
2684 master_device);
2685 g_assert (req);
2686 nm_device_activate (device, req);
2687
2688 return NM_ACTIVE_CONNECTION (req);
2689 }
2690
2691 /**
2692 * find_master:
2693 * @self: #NMManager object
2694 * @connection: the #NMConnection to find the master connection and device for
2695 * @device: the #NMDevice, if any, which will activate @connection
2696 * @out_master_connection: on success, the master connection of @connection if
2697 * that master connection was found
2698 * @out_master_device: on success, the master device of @connection if that
2699 * master device was found
2700 *
2701 * Given an #NMConnection, attempts to find its master connection and/or its
2702 * master device. This function may return a master connection, a master device,
2703 * or both. If only a connection is returned, that master connection is not
2704 * currently active on any device. If only a device is returned, that device
2705 * is not currently activated with any connection. If both are returned, then
2706 * the device is currently activated or activating with the returned master
2707 * connection.
2708 *
2709 * Returns: %TRUE if the master device and/or connection could be found or if
2710 * the connection did not require a master, %FALSE otherwise
2711 **/
2712 static gboolean
2713 find_master (NMManager *self,
2714 NMConnection *connection,
2715 NMDevice *device,
2716 NMConnection **out_master_connection,
2717 NMDevice **out_master_device)
2718 {
2719 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2720 NMSettingConnection *s_con;
2721 const char *master;
2722 NMDevice *master_device = NULL;
2723 NMConnection *master_connection = NULL;
2724 GSList *iter, *connections = NULL;
2725
2726 s_con = nm_connection_get_setting_connection (connection);
2727 g_assert (s_con);
2728 master = nm_setting_connection_get_master (s_con);
2729
2730 if (master == NULL)
2731 return TRUE; /* success, but no master */
2732
2733 /* Try as an interface name first */
2734 master_device = find_device_by_ip_iface (self, master);
2735 if (master_device) {
2736 /* A device obviously can't be its own master */
2737 if (master_device == device)
2738 return FALSE;
2739 } else {
2740 /* Try master as a connection UUID */
2741 master_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, master);
2742 if (master_connection) {
2743 /* Check if the master connection is activated on some device already */
2744 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2745 NMDevice *candidate = NM_DEVICE (iter->data);
2746
2747 if (candidate == device)
2748 continue;
2749
2750 if (nm_device_get_connection (candidate) == master_connection) {
2751 master_device = candidate;
2752 break;
2753 }
2754 }
2755 } else {
2756 /* Might be a virtual interface that hasn't been created yet, so
2757 * look through the interface names of connections that require
2758 * virtual interfaces and see if one of their virtual interface
2759 * names matches the master.
2760 */
2761 connections = nm_settings_get_connections (priv->settings);
2762 for (iter = connections; iter && !master_connection; iter = g_slist_next (iter)) {
2763 NMConnection *candidate = iter->data;
2764 char *vname;
2765
2766 if (connection_needs_virtual_device (candidate)) {
2767 vname = get_virtual_iface_name (self, candidate, NULL);
2768 if (g_strcmp0 (master, vname) == 0)
2769 master_connection = candidate;
2770 g_free (vname);
2771 }
2772 }
2773 g_slist_free (connections);
2774 }
2775 }
2776
2777 if (out_master_connection)
2778 *out_master_connection = master_connection;
2779 if (out_master_device)
2780 *out_master_device = master_device;
2781
2782 return master_device || master_connection;
2783 }
2784
2785 static gboolean
2786 is_compatible_with_slave (NMConnection *master, NMConnection *slave)
2787 {
2788 NMSettingConnection *s_con;
2789
2790 g_return_val_if_fail (master, FALSE);
2791 g_return_val_if_fail (slave, FALSE);
2792
2793 s_con = nm_connection_get_setting_connection (slave);
2794 g_assert (s_con);
2795
2796 return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
2797 }
2798
2799 /**
2800 * ensure_master_active_connection:
2801 *
2802 * @self: the #NMManager
2803 * @dbus_sender: if the request was initiated by a user via D-Bus, the
2804 * dbus sender name of the client that requested the activation; for auto
2805 * activated connections use %NULL
2806 * @connection: the connection that should depend on @master_connection
2807 * @device: the #NMDevice, if any, which will activate @connection
2808 * @master_connection: the master connection
2809 * @master_device: the master device
2810 * @error: the error, if an error occurred
2811 *
2812 * Determines whether a given #NMConnection depends on another connection to
2813 * be activated, and if so, finds that master connection or creates it.
2814 *
2815 * Returns: the master #NMActiveConnection that the caller should depend on, or
2816 * %NULL if an error occurred
2817 */
2818 static NMActiveConnection *
2819 ensure_master_active_connection (NMManager *self,
2820 const char *dbus_sender,
2821 NMConnection *connection,
2822 NMDevice *device,
2823 NMConnection *master_connection,
2824 NMDevice *master_device,
2825 GError **error)
2826 {
2827 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2828 NMActiveConnection *master_ac = NULL;
2829 NMDeviceState master_state;
2830 GSList *iter;
2831
2832 g_assert (connection);
2833 g_assert (master_connection || master_device);
2834
2835 /* If the master device isn't activated then we need to activate it using
2836 * compatible connection. If it's already activating we can just proceed.
2837 */
2838 if (master_device) {
2839 /* If we're passed a connection and a device, we require that connection
2840 * be already activated on the device, eg returned from find_master().
2841 */
2842 if (master_connection)
2843 g_assert (nm_device_get_connection (master_device) == master_connection);
2844
2845 master_state = nm_device_get_state (master_device);
2846 if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
2847 || nm_device_is_activating (master_device)) {
2848 /* Device already using master_connection */
2849 return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
2850 }
2851
2852 /* If the device is disconnected, find a compabile connection and
2853 * activate it on the device.
2854 */
2855 if (master_state == NM_DEVICE_STATE_DISCONNECTED) {
2856 GSList *connections;
2857
2858 g_assert (master_connection == NULL);
2859
2860 /* Find a compatible connection and activate this device using it */
2861 connections = nm_settings_get_connections (priv->settings);
2862 for (iter = connections; iter; iter = g_slist_next (iter)) {
2863 NMConnection *candidate = NM_CONNECTION (iter->data);
2864
2865 /* Ensure eg bond/team slave and the candidate master is a
2866 * bond/team master
2867 */
2868 if (!is_compatible_with_slave (candidate, connection))
2869 continue;
2870
2871 if (nm_device_check_connection_compatible (master_device, candidate, NULL)) {
2872 master_ac = nm_manager_activate_connection (self,
2873 candidate,
2874 NULL,
2875 nm_device_get_path (master_device),
2876 dbus_sender,
2877 error);
2878 if (!master_ac)
2879 g_prefix_error (error, "%s", "Master device activation failed: ");
2880 g_slist_free (connections);
2881 return master_ac;
2882 }
2883 }
2884 g_slist_free (connections);
2885
2886 g_set_error (error,
2887 NM_MANAGER_ERROR,
2888 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2889 "No compatible connection found for master device %s.",
2890 nm_device_get_iface (master_device));
2891 return NULL;
2892 }
2893
2894 /* Otherwise, the device is unmanaged, unavailable, or disconnecting */
2895 g_set_error (error,
2896 NM_MANAGER_ERROR,
2897 NM_MANAGER_ERROR_UNMANAGED_DEVICE,
2898 "Master device %s unmanaged or not available for activation",
2899 nm_device_get_iface (master_device));
2900 } else if (master_connection) {
2901 gboolean found_device = FALSE;
2902
2903 /* Find a compatible device and activate it using this connection */
2904 for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
2905 NMDevice *candidate = NM_DEVICE (iter->data);
2906
2907 if (candidate == device) {
2908 /* A device obviously can't be its own master */
2909 continue;
2910 }
2911
2912 if (!nm_device_check_connection_compatible (candidate, master_connection, NULL))
2913 continue;
2914
2915 found_device = TRUE;
2916 master_state = nm_device_get_state (candidate);
2917 if (master_state != NM_DEVICE_STATE_DISCONNECTED)
2918 continue;
2919
2920 master_ac = nm_manager_activate_connection (self,
2921 master_connection,
2922 NULL,
2923 nm_device_get_path (candidate),
2924 dbus_sender,
2925 error);
2926 if (!master_ac)
2927 g_prefix_error (error, "%s", "Master device activation failed: ");
2928 return master_ac;
2929 }
2930
2931 /* Device described by master_connection may be a virtual one that's
2932 * not created yet.
2933 */
2934 if (!found_device && connection_needs_virtual_device (master_connection)) {
2935 master_ac = nm_manager_activate_connection (self,
2936 master_connection,
2937 NULL,
2938 NULL,
2939 dbus_sender,
2940 error);
2941 if (!master_ac)
2942 g_prefix_error (error, "%s", "Master device activation failed: ");
2943 return master_ac;
2944 }
2945
2946 g_set_error (error,
2947 NM_MANAGER_ERROR,
2948 NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2949 "No compatible disconnected device found for master connection %s.",
2950 nm_connection_get_uuid (master_connection));
2951 } else
2952 g_assert_not_reached ();
2953
2954 return NULL;
2955 }
2956
2957 static NMActiveConnection *
2958 activate_vpn_connection (NMManager *self,
2959 NMConnection *connection,
2960 const char *specific_object,
2961 gulong sender_uid,
2962 GError **error)
2963 {
2964 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
2965 NMActiveConnection *parent = NULL;
2966 NMDevice *device = NULL;
2967 GSList *iter;
2968
2969 if (specific_object) {
2970 /* Find the specifc connection the client requested we use */
2971 parent = active_connection_get_by_path (self, specific_object);
2972 if (!parent) {
2973 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
2974 "Base connection for VPN connection not active.");
2975 return NULL;
2976 }
2977 } else {
2978 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
2979 NMActiveConnection *candidate = iter->data;
2980
2981 if (nm_active_connection_get_default (candidate)) {
2982 parent = candidate;
2983 break;
2984 }
2985 }
2986 }
2987
2988 if (!parent) {
2989 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
2990 "Could not find source connection.");
2991 return NULL;
2992 }
2993
2994 device = nm_active_connection_get_device (parent);
2995 if (!device) {
2996 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
2997 "Source connection had no active device.");
2998 return NULL;
2999 }
3000
3001 return nm_vpn_manager_activate_connection (priv->vpn_manager,
3002 connection,
3003 device,
3004 nm_active_connection_get_path (parent),
3005 TRUE,
3006 sender_uid,
3007 error);
3008 }
3009
3010 NMActiveConnection *
3011 nm_manager_activate_connection (NMManager *manager,
3012 NMConnection *connection,
3013 const char *specific_object,
3014 const char *device_path,
3015 const char *dbus_sender,
3016 GError **error)
3017 {
3018 NMManagerPrivate *priv;
3019 NMDevice *device = NULL;
3020 gulong sender_uid = G_MAXULONG;
3021 char *iface;
3022 NMDevice *master_device = NULL;
3023 NMConnection *master_connection = NULL;
3024 NMActiveConnection *master_ac = NULL, *ac = NULL;
3025 gboolean matched;
3026
3027 g_return_val_if_fail (manager != NULL, NULL);
3028 g_return_val_if_fail (connection != NULL, NULL);
3029 g_return_val_if_fail (error != NULL, NULL);
3030 g_return_val_if_fail (*error == NULL, NULL);
3031
3032 priv = NM_MANAGER_GET_PRIVATE (manager);
3033
3034 /* Get the UID of the user that originated the request, if any */
3035 if (dbus_sender) {
3036 if (!nm_dbus_manager_get_unix_user (priv->dbus_mgr, dbus_sender, &sender_uid)) {
3037 g_set_error_literal (error,
3038 NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED,
3039 "Failed to get unix user for dbus sender");
3040 return NULL;
3041 }
3042 } else {
3043 /* No sender means an internal/automatic activation request */
3044 sender_uid = 0;
3045 }
3046
3047 /* VPN ? */
3048 if (nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) {
3049 ac = activate_vpn_connection (manager, connection, specific_object, sender_uid, error);
3050 goto activated;
3051 }
3052
3053 /* Device-based connection */
3054 if (device_path) {
3055 device = nm_manager_get_device_by_path (manager, device_path);
3056 if (!device) {
3057 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3058 "Device not found");
3059 return NULL;
3060 }
3061
3062 /* If it's a virtual interface make sure the device given by the
3063 * path matches the connection's interface details.
3064 */
3065 if (connection_needs_virtual_device (connection)) {
3066 iface = get_virtual_iface_name (manager, connection, NULL);
3067 if (!iface) {
3068 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3069 "Failed to determine connection's virtual interface name");
3070 return NULL;
3071 }
3072
3073 matched = g_str_equal (iface, nm_device_get_ip_iface (device));
3074 g_free (iface);
3075 if (!matched) {
3076 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3077 "Device given by path did not match connection's virtual interface name");
3078 return NULL;
3079 }
3080 }
3081 } else {
3082 /* Virtual connections (VLAN, bond, team, etc) may not specify
3083 * a device path because the device may not be created yet,
3084 * or it be given by the connection's properties instead.
3085 * Find the device the connection refers to, or create it
3086 * if needed.
3087 */
3088 if (!connection_needs_virtual_device (connection)) {
3089 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3090 "This connection requires an existing device.");
3091 return NULL;
3092 }
3093
3094 iface = get_virtual_iface_name (manager, connection, NULL);
3095 if (!iface) {
3096 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3097 "Failed to determine connection's virtual interface name");
3098 return NULL;
3099 }
3100
3101 device = find_device_by_ip_iface (manager, iface);
3102 if (!device) {
3103 /* Create the software device. Only exception is when:
3104 * - this is an auto-activation *and* the device denies auto-activation
3105 * at this time (the device was manually disconnected/deleted before)
3106 */
3107 if (!nm_manager_can_device_auto_connect (manager, iface)) {
3108 if (dbus_sender) {
3109 /* Manual activation - allow device auto-activation again */
3110 nm_manager_prevent_device_auto_connect (manager, iface, FALSE);
3111 } else {
3112 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED,
3113 "'%s' does not allow automatic connections at this time => software device '%s' not created for '%s'",
3114 iface, iface, nm_connection_get_id (connection));
3115 g_free (iface);
3116 return NULL;
3117 }
3118 }
3119
3120 device = system_create_virtual_device (manager, connection);
3121 if (!device) {
3122 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3123 "Failed to create virtual interface '%s'", iface);
3124 g_free (iface);
3125 return NULL;
3126 }
3127
3128 /* A newly created device, if allowed to be managed by NM, will be
3129 * in the UNAVAILABLE state here. To ensure it can be activated
3130 * immediately, we transition it to DISCONNECTED so it passes the
3131 * nm_device_can_activate() check below.
3132 */
3133 if ( nm_device_is_available (device)
3134 && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
3135 nm_device_state_changed (device,
3136 NM_DEVICE_STATE_DISCONNECTED,
3137 NM_DEVICE_STATE_REASON_NONE);
3138 }
3139 }
3140 g_free (iface);
3141 }
3142
3143 if (!nm_device_can_activate (device, connection)) {
3144 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE,
3145 "Device not managed by NetworkManager or unavailable");
3146 return NULL;
3147 }
3148
3149 /* If this is an autoconnect request, but the device isn't allowing autoconnect
3150 * right now, we reject it.
3151 */
3152 if (!dbus_sender && !nm_device_autoconnect_allowed (device)) {
3153 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED,
3154 "%s does not allow automatic connections at this time",
3155 nm_device_get_iface (device));
3156 return NULL;
3157 }
3158
3159 /* Try to find the master connection/device if the connection has a dependency */
3160 if (!find_master (manager, connection, device, &master_connection, &master_device)) {
3161 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
3162 "Master connection not found or invalid");
3163 return NULL;
3164 }
3165
3166 /* Ensure there's a master active connection the new connection we're
3167 * activating can depend on.
3168 */
3169 if (master_connection || master_device) {
3170 if (master_connection) {
3171 nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
3172 nm_connection_get_id (connection),
3173 nm_connection_get_id (master_connection));
3174 }
3175 if (master_device) {
3176 nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master device '%s'",
3177 nm_connection_get_id (connection),
3178 nm_device_get_ip_iface (master_device));
3179 }
3180
3181 /* Ensure eg bond/team slave and the candidate master is
3182 * a bond/team master
3183 */
3184 if (master_connection && !is_compatible_with_slave (master_connection, connection)) {
3185 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
3186 "The master connection was not compatible");
3187 return NULL;
3188 }
3189
3190 master_ac = ensure_master_active_connection (manager,
3191 dbus_sender,
3192 connection,
3193 device,
3194 master_connection,
3195 master_device,
3196 error);
3197 if (!master_ac) {
3198 if (error)
3199 g_assert (*error);
3200 return NULL;
3201 }
3202
3203 nm_log_dbg (LOGD_CORE, "Activation of '%s' depends on active connection %s",
3204 nm_connection_get_id (connection),
3205 nm_active_connection_get_path (master_ac));
3206 }
3207
3208 ac = internal_activate_device (manager,
3209 device,
3210 connection,
3211 specific_object,
3212 dbus_sender ? TRUE : FALSE,
3213 dbus_sender ? sender_uid : 0,
3214 dbus_sender,
3215 FALSE,
3216 master_ac,
3217 error);
3218
3219 activated:
3220 if (ac)
3221 active_connection_add (manager, ac);
3222
3223 return ac;
3224 }
3225
3226 /*
3227 * TODO this function was created and named in the era of user settings, where
3228 * we could get activation requests for a connection before we got the settings
3229 * data of that connection. Now that user settings are gone, flatten or rename
3230 * it.
3231 */
3232 static void
3233 pending_activate (NMManager *self, PendingActivation *pending)
3234 {
3235 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3236 NMSettingsConnection *connection;
3237 NMActiveConnection *ac = NULL;
3238 GError *error = NULL;
3239 char *sender = NULL;
3240
3241 /* Ok, we're authorized */
3242
3243 connection = nm_settings_get_connection_by_path (priv->settings, pending->connection_path);
3244 if (!connection) {
3245 error = g_error_new_literal (NM_MANAGER_ERROR,
3246 NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
3247 "Connection could not be found.");
3248 goto out;
3249 }
3250
3251 if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr,
3252 pending->context,
3253 &sender,
3254 NULL)) {
3255 error = g_error_new_literal (NM_MANAGER_ERROR,
3256 NM_MANAGER_ERROR_PERMISSION_DENIED,
3257 "D-Bus sendder could not be determined.");
3258 goto out;
3259 }
3260
3261 g_assert (sender);
3262 ac = nm_manager_activate_connection (self,
3263 NM_CONNECTION (connection),
3264 pending->specific_object_path,
3265 pending->device_path,
3266 sender,
3267 &error);
3268 g_free (sender);
3269
3270 if (!ac) {
3271 nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s",
3272 pending->connection_path,
3273 error ? error->code : -1,
3274 error && error->message ? error->message : "(unknown)");
3275 }
3276
3277 out:
3278 pending_activation_destroy (pending, error, ac);
3279 g_clear_error (&error);
3280 }
3281
3282 static void
3283 activation_auth_done (PendingActivation *pending, GError *error)
3284 {
3285 if (error)
3286 pending_activation_destroy (pending, error, NULL);
3287 else
3288 pending_activate (pending->manager, pending);
3289 }
3290
3291 static void
3292 impl_manager_activate_connection (NMManager *self,
3293 const char *connection_path,
3294 const char *device_path,
3295 const char *specific_object_path,
3296 DBusGMethodInvocation *context)
3297 {
3298 PendingActivation *pending;
3299 GError *error = NULL;
3300
3301 /* Need to check the caller's permissions and stuff before we can
3302 * activate the connection.
3303 */
3304 pending = pending_activation_new (self,
3305 context,
3306 device_path,
3307 connection_path,
3308 NULL,
3309 specific_object_path,
3310 activation_auth_done,
3311 &error);
3312 if (pending)
3313 pending_activation_check_authorized (pending);
3314 else {
3315 g_assert (error);
3316 dbus_g_method_return_error (context, error);
3317 g_error_free (error);
3318 }
3319 }
3320
3321 static void
3322 activation_add_done (NMSettings *self,
3323 NMSettingsConnection *connection,
3324 GError *error,
3325 DBusGMethodInvocation *context,
3326 gpointer user_data)
3327 {
3328 PendingActivation *pending = user_data;
3329
3330 if (error)
3331 pending_activation_destroy (pending, error, NULL);
3332 else {
3333 /* Save the new connection's D-Bus path */
3334 pending->connection_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
3335
3336 /* And activate it */
3337 pending_activate (pending->manager, pending);
3338 }
3339 }
3340
3341 static void
3342 add_and_activate_auth_done (PendingActivation *pending, GError *error)
3343 {
3344 if (error)
3345 pending_activation_destroy (pending, error, NULL);
3346 else {
3347 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pending->manager);
3348
3349 /* Basic sender auth checks performed; try to add the connection */
3350 nm_settings_add_connection_dbus (priv->settings,
3351 pending->connection,
3352 TRUE,
3353 pending->context,
3354 activation_add_done,
3355 pending);
3356 }
3357 }
3358
3359 static void
3360 impl_manager_add_and_activate_connection (NMManager *self,
3361 GHashTable *settings,
3362 const char *device_path,
3363 const char *specific_object_path,
3364 DBusGMethodInvocation *context)
3365 {
3366 PendingActivation *pending;
3367 GError *error = NULL;
3368
3369 /* Need to check the caller's permissions and stuff before we can
3370 * activate the connection.
3371 */
3372 pending = pending_activation_new (self,
3373 context,
3374 device_path,
3375 NULL,
3376 settings,
3377 specific_object_path,
3378 add_and_activate_auth_done,
3379 &error);
3380 if (pending)
3381 pending_activation_check_authorized (pending);
3382 else {
3383 g_assert (error);
3384 dbus_g_method_return_error (context, error);
3385 g_error_free (error);
3386 }
3387 }
3388
3389 gboolean
3390 nm_manager_deactivate_connection (NMManager *manager,
3391 const char *connection_path,
3392 NMDeviceStateReason reason,
3393 GError **error)
3394 {
3395 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
3396 NMActiveConnection *active;
3397 gboolean success = FALSE;
3398
3399 active = active_connection_get_by_path (manager, connection_path);
3400 if (!active) {
3401 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3402 "The connection was not active.");
3403 return FALSE;
3404 }
3405
3406 if (NM_IS_VPN_CONNECTION (active)) {
3407 NMVPNConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
3408
3409 if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
3410 vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
3411 if (nm_vpn_manager_deactivate_connection (priv->vpn_manager, NM_VPN_CONNECTION (active), vpn_reason))
3412 success = TRUE;
3413 else
3414 g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3415 "The VPN connection was not active.");
3416 } else {
3417 g_assert (NM_IS_ACT_REQUEST (active));
3418 /* FIXME: use DEACTIVATING state */
3419 nm_device_state_changed (nm_active_connection_get_device (active),
3420 NM_DEVICE_STATE_DISCONNECTED,
3421 reason);
3422 success = TRUE;
3423 }
3424
3425 if (success)
3426 g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
3427
3428 return success;
3429 }
3430
3431 static void
3432 deactivate_net_auth_done_cb (NMAuthChain *chain,
3433 GError *auth_error,
3434 DBusGMethodInvocation *context,
3435 gpointer user_data)
3436 {
3437 NMManager *self = NM_MANAGER (user_data);
3438 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3439 GError *error = NULL;
3440 NMAuthCallResult result;
3441
3442 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3443
3444 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3445
3446 if (auth_error) {
3447 nm_log_dbg (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
3448 error = g_error_new (NM_MANAGER_ERROR,
3449 NM_MANAGER_ERROR_PERMISSION_DENIED,
3450 "Deactivate request failed: %s",
3451 auth_error->message);
3452 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3453 error = g_error_new_literal (NM_MANAGER_ERROR,
3454 NM_MANAGER_ERROR_PERMISSION_DENIED,
3455 "Not authorized to deactivate connections");
3456 } else {
3457 /* success; deactivation allowed */
3458 if (!nm_manager_deactivate_connection (self,
3459 nm_auth_chain_get_data (chain, "path"),
3460 NM_DEVICE_STATE_REASON_USER_REQUESTED,
3461 &error))
3462 g_assert (error);
3463 }
3464
3465 if (error)
3466 dbus_g_method_return_error (context, error);
3467 else
3468 dbus_g_method_return (context);
3469
3470 g_clear_error (&error);
3471 nm_auth_chain_unref (chain);
3472 }
3473
3474 static void
3475 impl_manager_deactivate_connection (NMManager *self,
3476 const char *active_path,
3477 DBusGMethodInvocation *context)
3478 {
3479 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3480 NMConnection *connection = NULL;
3481 GError *error = NULL;
3482 GSList *iter;
3483 NMAuthChain *chain;
3484 const char *error_desc = NULL;
3485
3486 /* Find the connection by its object path */
3487 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
3488 NMActiveConnection *ac = iter->data;
3489
3490 if (g_strcmp0 (nm_active_connection_get_path (ac), active_path) == 0) {
3491 connection = nm_active_connection_get_connection (ac);
3492 break;
3493 }
3494 }
3495
3496 if (!connection) {
3497 error = g_error_new_literal (NM_MANAGER_ERROR,
3498 NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
3499 "The connection was not active.");
3500 dbus_g_method_return_error (context, error);
3501 g_error_free (error);
3502 return;
3503 }
3504
3505 /* Validate the user request */
3506 chain = nm_auth_chain_new (context, deactivate_net_auth_done_cb, self, &error_desc);
3507 if (chain) {
3508 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3509
3510 nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
3511 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
3512 } else {
3513 error = g_error_new_literal (NM_MANAGER_ERROR,
3514 NM_MANAGER_ERROR_PERMISSION_DENIED,
3515 error_desc);
3516 dbus_g_method_return_error (context, error);
3517 g_error_free (error);
3518 }
3519 }
3520
3521 /*
3522 * Track (software) devices that cannot auto activate.
3523 * It is needed especially for software devices, that can be removed and added
3524 * again. So we can't simply use a flag inside the device.
3525 */
3526 void
3527 nm_manager_prevent_device_auto_connect (NMManager *manager, const char *ifname, gboolean prevent)
3528 {
3529 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
3530
3531 if (prevent)
3532 g_hash_table_add (priv->noauto_sw_devices, g_strdup (ifname));
3533 else
3534 g_hash_table_remove (priv->noauto_sw_devices, ifname);
3535 }
3536
3537 gboolean
3538 nm_manager_can_device_auto_connect (NMManager *manager, const char *ifname)
3539 {
3540 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
3541
3542 return !g_hash_table_contains (priv->noauto_sw_devices, ifname);
3543 }
3544
3545 static void
3546 do_sleep_wake (NMManager *self)
3547 {
3548 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3549 const GSList *unmanaged_specs;
3550 GSList *iter;
3551
3552 if (manager_sleeping (self)) {
3553 nm_log_info (LOGD_SUSPEND, "sleeping or disabling...");
3554
3555 /* Just deactivate and down all devices from the device list,
3556 * to keep things fast the device list will get resynced when
3557 * the manager wakes up.
3558 */
3559 for (iter = priv->devices; iter; iter = iter->next)
3560 nm_device_set_manager_managed (NM_DEVICE (iter->data), FALSE, NM_DEVICE_STATE_REASON_SLEEPING);
3561
3562 } else {
3563 nm_log_info (LOGD_SUSPEND, "waking up and re-enabling...");
3564
3565 unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
3566
3567 /* Ensure rfkill state is up-to-date since we don't respond to state
3568 * changes during sleep.
3569 */
3570 nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
3571
3572 /* Re-manage managed devices */
3573 for (iter = priv->devices; iter; iter = iter->next) {
3574 NMDevice *device = NM_DEVICE (iter->data);
3575 guint i;
3576
3577 /* enable/disable wireless devices since that we don't respond
3578 * to killswitch changes during sleep.
3579 */
3580 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
3581 RadioState *rstate = &priv->radio_states[i];
3582 gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
3583
3584 if (rstate->desc) {
3585 nm_log_dbg (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)",
3586 enabled ? "enabling" : "disabling",
3587 rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled);
3588 }
3589
3590 if (nm_device_get_rfkill_type (device) == rstate->rtype)
3591 nm_device_set_enabled (device, enabled);
3592 }
3593
3594 g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, TRUE, NULL);
3595
3596 if (nm_device_spec_match_list (device, unmanaged_specs))
3597 nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
3598 else
3599 nm_device_set_manager_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
3600 }
3601 }
3602
3603 nm_manager_update_state (self);
3604 }
3605
3606 static void
3607 _internal_sleep (NMManager *self, gboolean do_sleep)
3608 {
3609 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3610
3611 if (priv->sleeping == do_sleep)
3612 return;
3613
3614 nm_log_info (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
3615 do_sleep ? "sleep" : "wake",
3616 priv->sleeping ? "yes" : "no",
3617 priv->net_enabled ? "yes" : "no");
3618
3619 priv->sleeping = do_sleep;
3620
3621 do_sleep_wake (self);
3622
3623 g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
3624 }
3625
3626 #if 0
3627 static void
3628 sleep_auth_done_cb (NMAuthChain *chain,
3629 GError *error,
3630 DBusGMethodInvocation *context,
3631 gpointer user_data)
3632 {
3633 NMManager *self = NM_MANAGER (user_data);
3634 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3635 GError *ret_error;
3636 NMAuthCallResult result;
3637 gboolean do_sleep;
3638
3639 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3640
3641 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
3642 if (error) {
3643 nm_log_dbg (LOGD_SUSPEND, "Sleep/wake request failed: %s", error->message);
3644 ret_error = g_error_new (NM_MANAGER_ERROR,
3645 NM_MANAGER_ERROR_PERMISSION_DENIED,
3646 "Sleep/wake request failed: %s",
3647 error->message);
3648 dbus_g_method_return_error (context, ret_error);
3649 g_error_free (ret_error);
3650 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3651 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
3652 NM_MANAGER_ERROR_PERMISSION_DENIED,
3653 "Not authorized to sleep/wake");
3654 dbus_g_method_return_error (context, ret_error);
3655 g_error_free (ret_error);
3656 } else {
3657 /* Auth success */
3658 do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
3659 _internal_sleep (self, do_sleep);
3660 dbus_g_method_return (context);
3661 }
3662
3663 nm_auth_chain_unref (chain);
3664 }
3665 #endif
3666
3667 static void
3668 impl_manager_sleep (NMManager *self,
3669 gboolean do_sleep,
3670 DBusGMethodInvocation *context)
3671 {
3672 NMManagerPrivate *priv;
3673 GError *error = NULL;
3674 #if 0
3675 NMAuthChain *chain;
3676 const char *error_desc = NULL;
3677 #endif
3678
3679 g_return_if_fail (NM_IS_MANAGER (self));
3680
3681 priv = NM_MANAGER_GET_PRIVATE (self);
3682
3683 if (priv->sleeping == do_sleep) {
3684 error = g_error_new (NM_MANAGER_ERROR,
3685 NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
3686 "Already %s", do_sleep ? "asleep" : "awake");
3687 dbus_g_method_return_error (context, error);
3688 g_error_free (error);
3689 return;
3690 }
3691
3692 /* Unconditionally allow the request. Previously it was polkit protected
3693 * but unfortunately that doesn't work for short-lived processes like
3694 * pm-utils. It uses dbus-send without --print-reply, which quits
3695 * immediately after sending the request, and NM is unable to obtain the
3696 * sender's UID as dbus-send has already dropped off the bus. Thus NM
3697 * fails the request. Instead, don't validate the request, but rely on
3698 * D-Bus permissions to restrict the call to root.
3699 */
3700 _internal_sleep (self, do_sleep);
3701 dbus_g_method_return (context);
3702 return;
3703
3704 #if 0
3705 chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
3706 if (chain) {
3707 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3708 nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
3709 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
3710 } else {
3711 error = g_error_new_literal (NM_MANAGER_ERROR,
3712 NM_MANAGER_ERROR_PERMISSION_DENIED,
3713 error_desc);
3714 dbus_g_method_return_error (context, error);
3715 g_error_free (error);
3716 }
3717 #endif
3718 }
3719
3720 static void
3721 sleeping_cb (DBusGProxy *proxy, gpointer user_data)
3722 {
3723 nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
3724 _internal_sleep (NM_MANAGER (user_data), TRUE);
3725 }
3726
3727 static void
3728 resuming_cb (DBusGProxy *proxy, gpointer user_data)
3729 {
3730 nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
3731 _internal_sleep (NM_MANAGER (user_data), FALSE);
3732 }
3733
3734 static void
3735 _internal_enable (NMManager *self, gboolean enable)
3736 {
3737 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3738 GError *err = NULL;
3739
3740 /* Update "NetworkingEnabled" key in state file */
3741 if (priv->state_file) {
3742 if (!write_value_to_state_file (priv->state_file,
3743 "main", "NetworkingEnabled",
3744 G_TYPE_BOOLEAN, (gpointer) &enable,
3745 &err)) {
3746 /* Not a hard error */
3747 nm_log_warn (LOGD_SUSPEND, "writing to state file %s failed: (%d) %s.",
3748 priv->state_file,
3749 err ? err->code : -1,
3750 (err && err->message) ? err->message : "unknown");
3751 }
3752 }
3753
3754 nm_log_info (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
3755 enable ? "enable" : "disable",
3756 priv->sleeping ? "yes" : "no",
3757 priv->net_enabled ? "yes" : "no");
3758
3759 priv->net_enabled = enable;
3760
3761 do_sleep_wake (self);
3762
3763 g_object_notify (G_OBJECT (self), NM_MANAGER_NETWORKING_ENABLED);
3764 }
3765
3766 static void
3767 enable_net_done_cb (NMAuthChain *chain,
3768 GError *error,
3769 DBusGMethodInvocation *context,
3770 gpointer user_data)
3771 {
3772 NMManager *self = NM_MANAGER (user_data);
3773 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3774 GError *ret_error = NULL;
3775 NMAuthCallResult result;
3776 gboolean enable;
3777
3778 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3779
3780 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
3781 if (error) {
3782 nm_log_dbg (LOGD_CORE, "Enable request failed: %s", error->message);
3783 ret_error = g_error_new (NM_MANAGER_ERROR,
3784 NM_MANAGER_ERROR_PERMISSION_DENIED,
3785 "Enable request failed: %s",
3786 error->message);
3787 } else if (result != NM_AUTH_CALL_RESULT_YES) {
3788 ret_error = g_error_new_literal (NM_MANAGER_ERROR,
3789 NM_MANAGER_ERROR_PERMISSION_DENIED,
3790 "Not authorized to enable/disable networking");
3791 } else {
3792 /* Auth success */
3793 enable = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enable"));
3794 _internal_enable (self, enable);
3795 dbus_g_method_return (context);
3796 }
3797
3798 if (ret_error) {
3799 dbus_g_method_return_error (context, ret_error);
3800 g_error_free (ret_error);
3801 }
3802
3803 nm_auth_chain_unref (chain);
3804 }
3805
3806 static void
3807 impl_manager_enable (NMManager *self,
3808 gboolean enable,
3809 DBusGMethodInvocation *context)
3810 {
3811 NMManagerPrivate *priv;
3812 NMAuthChain *chain;
3813 GError *error = NULL;
3814 const char *error_desc;
3815
3816 g_return_if_fail (NM_IS_MANAGER (self));
3817
3818 priv = NM_MANAGER_GET_PRIVATE (self);
3819
3820 if (priv->net_enabled == enable) {
3821 error = g_error_new (NM_MANAGER_ERROR,
3822 NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
3823 "Already %s", enable ? "enabled" : "disabled");
3824 dbus_g_method_return_error (context, error);
3825 g_error_free (error);
3826 return;
3827 }
3828
3829 chain = nm_auth_chain_new (context, enable_net_done_cb, self, &error_desc);
3830 if (chain) {
3831 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3832
3833 nm_auth_chain_set_data (chain, "enable", GUINT_TO_POINTER (enable), NULL);
3834 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, TRUE);
3835 } else {
3836 error = g_error_new_literal (NM_MANAGER_ERROR,
3837 NM_MANAGER_ERROR_PERMISSION_DENIED,
3838 error_desc);
3839 dbus_g_method_return_error (context, error);
3840 g_error_free (error);
3841 }
3842 }
3843
3844 /* Permissions */
3845
3846 static void
3847 get_perm_add_result (NMAuthChain *chain, GHashTable *results, const char *permission)
3848 {
3849 NMAuthCallResult result;
3850
3851 result = nm_auth_chain_get_result (chain, permission);
3852 if (result == NM_AUTH_CALL_RESULT_YES)
3853 g_hash_table_insert (results, (char *) permission, "yes");
3854 else if (result == NM_AUTH_CALL_RESULT_NO)
3855 g_hash_table_insert (results, (char *) permission, "no");
3856 else if (result == NM_AUTH_CALL_RESULT_AUTH)
3857 g_hash_table_insert (results, (char *) permission, "auth");
3858 else {
3859 nm_log_dbg (LOGD_CORE, "unknown auth chain result %d", result);
3860 }
3861 }
3862
3863 static void
3864 get_permissions_done_cb (NMAuthChain *chain,
3865 GError *error,
3866 DBusGMethodInvocation *context,
3867 gpointer user_data)
3868 {
3869 NMManager *self = NM_MANAGER (user_data);
3870 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3871 GError *ret_error;
3872 GHashTable *results;
3873
3874 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
3875 if (error) {
3876 nm_log_dbg (LOGD_CORE, "Permissions request failed: %s", error->message);
3877 ret_error = g_error_new (NM_MANAGER_ERROR,
3878 NM_MANAGER_ERROR_PERMISSION_DENIED,
3879 "Permissions request failed: %s",
3880 error->message);
3881 dbus_g_method_return_error (context, ret_error);
3882 g_error_free (ret_error);
3883 } else {
3884 results = g_hash_table_new (g_str_hash, g_str_equal);
3885
3886 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
3887 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SLEEP_WAKE);
3888 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
3889 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
3890 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
3891 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
3892 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
3893 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
3894 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
3895 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
3896 get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
3897
3898 dbus_g_method_return (context, results);
3899 g_hash_table_destroy (results);
3900 }
3901
3902 nm_auth_chain_unref (chain);
3903 }
3904
3905 static void
3906 impl_manager_get_permissions (NMManager *self,
3907 DBusGMethodInvocation *context)
3908 {
3909 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3910 NMAuthChain *chain;
3911 const char *error_desc = NULL;
3912 GError *error;
3913
3914 chain = nm_auth_chain_new (context, get_permissions_done_cb, self, &error_desc);
3915 if (chain) {
3916 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
3917
3918 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
3919 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
3920 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
3921 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
3922 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
3923 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
3924 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
3925 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
3926 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
3927 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
3928 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
3929 } else {
3930 error = g_error_new_literal (NM_MANAGER_ERROR,
3931 NM_MANAGER_ERROR_PERMISSION_DENIED,
3932 error_desc);
3933 dbus_g_method_return_error (context, error);
3934 g_error_free (error);
3935 }
3936 }
3937
3938 static gboolean
3939 impl_manager_get_state (NMManager *manager, guint32 *state, GError **error)
3940 {
3941 nm_manager_update_state (manager);
3942 *state = NM_MANAGER_GET_PRIVATE (manager)->state;
3943 return TRUE;
3944 }
3945
3946 static gboolean
3947 impl_manager_set_logging (NMManager *manager,
3948 const char *level,
3949 const char *domains,
3950 GError **error)
3951 {
3952 if (nm_logging_setup (level, domains, error)) {
3953 char *new_domains = nm_logging_domains_to_string ();
3954
3955 nm_log_info (LOGD_CORE, "logging: level '%s' domains '%s'",
3956 nm_logging_level_to_string (),
3957 new_domains);
3958 g_free (new_domains);
3959 return TRUE;
3960 }
3961 return FALSE;
3962 }
3963
3964 static void
3965 impl_manager_get_logging (NMManager *manager,
3966 char **level,
3967 char **domains)
3968 {
3969 *level = g_strdup (nm_logging_level_to_string ());
3970 *domains = g_strdup (nm_logging_domains_to_string ());
3971 }
3972
3973 static void
3974 connectivity_check_done (GObject *object,
3975 GAsyncResult *result,
3976 gpointer user_data)
3977 {
3978 DBusGMethodInvocation *context = user_data;
3979 NMConnectivityState state;
3980 GError *error = NULL;
3981
3982 state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
3983 if (error) {
3984 dbus_g_method_return_error (context, error);
3985 g_error_free (error);
3986 } else
3987 dbus_g_method_return (context, state);
3988 }
3989
3990
3991 static void
3992 check_connectivity_auth_done_cb (NMAuthChain *chain,
3993 GError *auth_error,
3994 DBusGMethodInvocation *context,
3995 gpointer user_data)
3996 {
3997 NMManager *self = NM_MANAGER (user_data);
3998 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
3999 GError *error = NULL;
4000 NMAuthCallResult result;
4001
4002 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4003
4004 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
4005
4006 if (auth_error) {
4007 nm_log_dbg (LOGD_CORE, "CheckConnectivity request failed: %s", auth_error->message);
4008 error = g_error_new (NM_MANAGER_ERROR,
4009 NM_MANAGER_ERROR_PERMISSION_DENIED,
4010 "Connectivity check request failed: %s",
4011 auth_error->message);
4012 } else if (result != NM_AUTH_CALL_RESULT_YES) {
4013 error = g_error_new_literal (NM_MANAGER_ERROR,
4014 NM_MANAGER_ERROR_PERMISSION_DENIED,
4015 "Not authorized to recheck connectivity");
4016 } else {
4017 /* it's allowed */
4018 nm_connectivity_check_async (priv->connectivity,
4019 connectivity_check_done,
4020 context);
4021 }
4022
4023 if (error) {
4024 dbus_g_method_return_error (context, error);
4025 g_error_free (error);
4026 }
4027 nm_auth_chain_unref (chain);
4028 }
4029
4030 static void
4031 impl_manager_check_connectivity (NMManager *manager,
4032 DBusGMethodInvocation *context)
4033 {
4034 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
4035 NMAuthChain *chain;
4036 const char *error_desc = NULL;
4037 GError *error;
4038
4039 /* Validate the user request */
4040 chain = nm_auth_chain_new (context, check_connectivity_auth_done_cb, manager, &error_desc);
4041 if (chain) {
4042 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4043
4044 nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
4045 } else {
4046 error = g_error_new_literal (NM_MANAGER_ERROR,
4047 NM_MANAGER_ERROR_PERMISSION_DENIED,
4048 error_desc);
4049 dbus_g_method_return_error (context, error);
4050 g_error_free (error);
4051 }
4052 }
4053
4054 void
4055 nm_manager_start (NMManager *self)
4056 {
4057 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4058 guint i;
4059
4060 /* Set initial radio enabled/disabled state */
4061 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
4062 RadioState *rstate = &priv->radio_states[i];
4063 RfKillState udev_state;
4064 gboolean enabled;
4065
4066 if (!rstate->desc)
4067 continue;
4068
4069 udev_state = nm_rfkill_manager_get_rfkill_state (priv->rfkill_mgr, i);
4070 update_rstate_from_rfkill (rstate, udev_state);
4071
4072 if (rstate->desc) {
4073 nm_log_info (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
4074 rstate->desc,
4075 (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
4076 rstate->user_enabled ? "enabled" : "disabled");
4077 }
4078 enabled = radio_enabled_for_rstate (rstate, TRUE);
4079 manager_update_radio_enabled (self, rstate, enabled);
4080 }
4081
4082 /* Log overall networking status - enabled/disabled */
4083 nm_log_info (LOGD_CORE, "Networking is %s by state file",
4084 priv->net_enabled ? "enabled" : "disabled");
4085
4086 system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
4087 system_hostname_changed_cb (priv->settings, NULL, self);
4088
4089 /* FIXME: remove when we handle bridges non-destructively */
4090 /* Read a list of bridges NM managed when it last quit, and only
4091 * manage those bridges to avoid conflicts with external tools.
4092 */
4093 priv->nm_bridges = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
4094 read_nm_created_bridges (self);
4095
4096 nm_platform_query_devices ();
4097 nm_atm_manager_query_devices (priv->atm_mgr);
4098 nm_bluez_manager_query_devices (priv->bluez_mgr);
4099
4100 /*
4101 * Connections added before the manager is started do not emit
4102 * connection-added signals thus devices have to be created manually.
4103 */
4104 system_create_virtual_devices (self);
4105
4106 /* FIXME: remove when we handle bridges non-destructively */
4107 g_hash_table_unref (priv->nm_bridges);
4108 priv->nm_bridges = NULL;
4109
4110 check_if_startup_complete (self);
4111 }
4112
4113 static gboolean
4114 handle_firmware_changed (gpointer user_data)
4115 {
4116 NMManager *self = NM_MANAGER (user_data);
4117 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4118 GSList *iter;
4119
4120 priv->fw_changed_id = 0;
4121
4122 if (manager_sleeping (self))
4123 return FALSE;
4124
4125 /* Try to re-enable devices with missing firmware */
4126 for (iter = priv->devices; iter; iter = iter->next) {
4127 NMDevice *candidate = NM_DEVICE (iter->data);
4128 NMDeviceState state = nm_device_get_state (candidate);
4129
4130 if ( nm_device_get_firmware_missing (candidate)
4131 && (state == NM_DEVICE_STATE_UNAVAILABLE)) {
4132 nm_log_info (LOGD_CORE, "(%s): firmware may now be available",
4133 nm_device_get_iface (candidate));
4134
4135 /* Re-set unavailable state to try bringing the device up again */
4136 nm_device_state_changed (candidate,
4137 NM_DEVICE_STATE_UNAVAILABLE,
4138 NM_DEVICE_STATE_REASON_NONE);
4139 }
4140 }
4141
4142 return FALSE;
4143 }
4144
4145 static void
4146 connectivity_changed (NMConnectivity *connectivity,
4147 GParamSpec *pspec,
4148 gpointer user_data)
4149 {
4150 NMManager *self = NM_MANAGER (user_data);
4151 NMConnectivityState state;
4152 static const char *connectivity_states[] = { "UNKNOWN", "NONE", "PORTAL", "LIMITED", "FULL" };
4153
4154 state = nm_connectivity_get_state (connectivity);
4155 nm_log_dbg (LOGD_CORE, "connectivity checking indicates %s",
4156 connectivity_states[state]);
4157
4158 nm_manager_update_state (self);
4159 }
4160
4161 static void
4162 firmware_dir_changed (GFileMonitor *monitor,
4163 GFile *file,
4164 GFile *other_file,
4165 GFileMonitorEvent event_type,
4166 gpointer user_data)
4167 {
4168 NMManager *self = NM_MANAGER (user_data);
4169 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4170
4171 switch (event_type) {
4172 case G_FILE_MONITOR_EVENT_CREATED:
4173 case G_FILE_MONITOR_EVENT_CHANGED:
4174 case G_FILE_MONITOR_EVENT_MOVED:
4175 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
4176 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
4177 if (!priv->fw_changed_id) {
4178 priv->fw_changed_id = g_timeout_add_seconds (4, handle_firmware_changed, self);
4179 nm_log_info (LOGD_CORE, "kernel firmware directory '%s' changed",
4180 KERNEL_FIRMWARE_DIR);
4181 }
4182 break;
4183 default:
4184 break;
4185 }
4186 }
4187
4188 static void
4189 policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4190 {
4191 NMManager *self = NM_MANAGER (user_data);
4192 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4193 NMDevice *best;
4194 NMActiveConnection *ac;
4195
4196 /* Note: this assumes that it's not possible for the IP4 default
4197 * route to be going over the default-ip6-device. If that changes,
4198 * we need something more complicated here.
4199 */
4200 best = nm_policy_get_default_ip4_device (priv->policy);
4201 if (!best)
4202 best = nm_policy_get_default_ip6_device (priv->policy);
4203
4204 if (best)
4205 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
4206 else
4207 ac = NULL;
4208
4209 if (ac != priv->primary_connection) {
4210 g_clear_object (&priv->primary_connection);
4211 priv->primary_connection = ac ? g_object_ref (ac) : NULL;
4212 nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_name (ac) : "(none)");
4213 g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
4214 }
4215 }
4216
4217 static void
4218 policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
4219 {
4220 NMManager *self = NM_MANAGER (user_data);
4221 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4222 NMDevice *activating, *best;
4223 NMActiveConnection *ac;
4224
4225 /* We only look at activating-ip6-device if activating-ip4-device
4226 * AND default-ip4-device are NULL; if default-ip4-device is
4227 * non-NULL, then activating-ip6-device is irrelevant, since while
4228 * that device might become the new default-ip6-device, it can't
4229 * become primary-connection while default-ip4-device is set to
4230 * something else.
4231 */
4232 activating = nm_policy_get_activating_ip4_device (priv->policy);
4233 best = nm_policy_get_default_ip4_device (priv->policy);
4234 if (!activating && !best)
4235 activating = nm_policy_get_activating_ip6_device (priv->policy);
4236
4237 if (activating)
4238 ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
4239 else
4240 ac = NULL;
4241
4242 if (ac != priv->activating_connection) {
4243 g_clear_object (&priv->activating_connection);
4244 priv->activating_connection = ac ? g_object_ref (ac) : NULL;
4245 nm_log_dbg (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_name (ac) : "(none)");
4246 g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVATING_CONNECTION);
4247 }
4248 }
4249
4250 #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
4251 #define DEV_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.Device.PermissionDenied"
4252
4253 static void
4254 prop_set_auth_done_cb (NMAuthChain *chain,
4255 GError *error,
4256 DBusGMethodInvocation *context,
4257 gpointer user_data)
4258 {
4259 NMManager *self = NM_MANAGER (user_data);
4260 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4261 DBusConnection *connection;
4262 NMAuthCallResult result;
4263 DBusMessage *reply = NULL, *message;
4264 const char *permission, *prop;
4265 GObject *obj;
4266 gboolean set_enabled = TRUE;
4267
4268 priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
4269
4270 message = nm_auth_chain_get_data (chain, "message");
4271 permission = nm_auth_chain_get_data (chain, "permission");
4272 prop = nm_auth_chain_get_data (chain, "prop");
4273 set_enabled = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enabled"));
4274 obj = nm_auth_chain_get_data (chain, "object");
4275
4276 result = nm_auth_chain_get_result (chain, permission);
4277 if (error || (result != NM_AUTH_CALL_RESULT_YES)) {
4278 reply = dbus_message_new_error (message,
4279 NM_IS_DEVICE (obj) ? DEV_PERM_DENIED_ERROR : NM_PERM_DENIED_ERROR,
4280 "Not authorized to perform this operation");
4281 } else {
4282 g_object_set (obj, prop, set_enabled, NULL);
4283 reply = dbus_message_new_method_return (message);
4284 }
4285
4286 g_assert (reply);
4287 connection = nm_auth_chain_get_data (chain, "connection");
4288 g_assert (connection);
4289 dbus_connection_send (connection, reply, NULL);
4290 dbus_message_unref (reply);
4291
4292 nm_auth_chain_unref (chain);
4293 }
4294
4295 static DBusHandlerResult
4296 prop_filter (DBusConnection *connection,
4297 DBusMessage *message,
4298 void *user_data)
4299 {
4300 NMManager *self = NM_MANAGER (user_data);
4301 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4302 DBusMessageIter iter;
4303 DBusMessageIter sub;
4304 const char *propiface = NULL;
4305 const char *propname = NULL;
4306 const char *glib_propname = NULL, *permission = NULL;
4307 gulong caller_uid = G_MAXULONG;
4308 DBusMessage *reply = NULL;
4309 gboolean set_enabled = FALSE;
4310 NMAuthChain *chain;
4311 GObject *obj;
4312
4313 /* The sole purpose of this function is to validate property accesses
4314 * on the NMManager object since dbus-glib doesn't yet give us this
4315 * functionality.
4316 */
4317
4318 if (!dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Set"))
4319 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4320
4321 dbus_message_iter_init (message, &iter);
4322
4323 /* Get the D-Bus interface of the property to set */
4324 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
4325 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4326 dbus_message_iter_get_basic (&iter, &propiface);
4327 if (!propiface || (strcmp (propiface, NM_DBUS_INTERFACE) && strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)))
4328 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4329 dbus_message_iter_next (&iter);
4330
4331 /* Get the property name that's going to be set */
4332 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
4333 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4334 dbus_message_iter_get_basic (&iter, &propname);
4335 dbus_message_iter_next (&iter);
4336
4337 if (!strcmp (propname, "WirelessEnabled")) {
4338 glib_propname = NM_MANAGER_WIRELESS_ENABLED;
4339 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI;
4340 } else if (!strcmp (propname, "WwanEnabled")) {
4341 glib_propname = NM_MANAGER_WWAN_ENABLED;
4342 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
4343 } else if (!strcmp (propname, "WimaxEnabled")) {
4344 glib_propname = NM_MANAGER_WIMAX_ENABLED;
4345 permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
4346 } else if (!strcmp (propname, "Autoconnect")) {
4347 glib_propname = NM_DEVICE_AUTOCONNECT;
4348 permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
4349 } else
4350 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4351
4352 /* Get the new value for the property */
4353 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT)
4354 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4355 dbus_message_iter_recurse (&iter, &sub);
4356 if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_BOOLEAN)
4357 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4358 dbus_message_iter_get_basic (&sub, &set_enabled);
4359
4360 /* Make sure the object exists */
4361 obj = dbus_g_connection_lookup_g_object (dbus_connection_get_g_connection (connection),
4362 dbus_message_get_path (message));
4363 if (!obj) {
4364 reply = dbus_message_new_error (message, NM_PERM_DENIED_ERROR,
4365 "Object does not exist");
4366 goto out;
4367 }
4368
4369 if (!nm_dbus_manager_get_caller_info_from_message (priv->dbus_mgr,
4370 connection,
4371 message,
4372 NULL,
4373 &caller_uid)) {
4374 reply = dbus_message_new_error (message, NM_PERM_DENIED_ERROR,
4375 "Could not determine request UID.");
4376 goto out;
4377 }
4378
4379 /* Validate the user request */
4380 chain = nm_auth_chain_new_raw_message (message, caller_uid, prop_set_auth_done_cb, self);
4381 g_assert (chain);
4382 priv->auth_chains = g_slist_append (priv->auth_chains, chain);
4383 nm_auth_chain_set_data (chain, "prop", g_strdup (glib_propname), g_free);
4384 nm_auth_chain_set_data (chain, "permission", g_strdup (permission), g_free);
4385 nm_auth_chain_set_data (chain, "enabled", GUINT_TO_POINTER (set_enabled), NULL);
4386 nm_auth_chain_set_data (chain, "message", dbus_message_ref (message), (GDestroyNotify) dbus_message_unref);
4387 nm_auth_chain_set_data (chain, "connection", dbus_connection_ref (connection), (GDestroyNotify) dbus_connection_unref);
4388 nm_auth_chain_set_data (chain, "object", g_object_ref (obj), (GDestroyNotify) g_object_unref);
4389 nm_auth_chain_add_call (chain, permission, TRUE);
4390
4391 out:
4392 if (reply) {
4393 dbus_connection_send (connection, reply, NULL);
4394 dbus_message_unref (reply);
4395 }
4396 return DBUS_HANDLER_RESULT_HANDLED;
4397 }
4398
4399 static NMManager *singleton = NULL;
4400
4401 NMManager *
4402 nm_manager_get (void)
4403 {
4404 g_assert (singleton);
4405 return g_object_ref (singleton);
4406 }
4407
4408 NMManager *
4409 nm_manager_new (NMSettings *settings,
4410 const char *state_file,
4411 gboolean initial_net_enabled,
4412 gboolean initial_wifi_enabled,
4413 gboolean initial_wwan_enabled,
4414 gboolean initial_wimax_enabled,
4415 GError **error)
4416 {
4417 NMManagerPrivate *priv;
4418 DBusGConnection *bus;
4419 DBusConnection *dbus_connection;
4420
4421 g_assert (settings);
4422
4423 /* Can only be called once */
4424 g_assert (singleton == NULL);
4425 singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL);
4426 g_assert (singleton);
4427
4428 priv = NM_MANAGER_GET_PRIVATE (singleton);
4429
4430 priv->policy = nm_policy_new (singleton, settings);
4431 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
4432 G_CALLBACK (policy_default_device_changed), singleton);
4433 g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
4434 G_CALLBACK (policy_default_device_changed), singleton);
4435 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
4436 G_CALLBACK (policy_activating_device_changed), singleton);
4437 g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
4438 G_CALLBACK (policy_activating_device_changed), singleton);
4439
4440 priv->connectivity = nm_connectivity_new ();
4441 g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
4442 G_CALLBACK (connectivity_changed), singleton);
4443
4444 bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
4445 g_assert (bus);
4446 dbus_connection = dbus_g_connection_get_connection (bus);
4447 g_assert (dbus_connection);
4448
4449 if (!dbus_connection_add_filter (dbus_connection, prop_filter, singleton, NULL)) {
4450 nm_log_err (LOGD_CORE, "failed to register DBus connection filter");
4451 g_object_unref (singleton);
4452 return NULL;
4453 }
4454
4455 priv->settings = g_object_ref (settings);
4456
4457 priv->state_file = g_strdup (state_file);
4458
4459 priv->net_enabled = initial_net_enabled;
4460
4461 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled;
4462 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled;
4463 priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = initial_wimax_enabled;
4464
4465 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
4466 G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
4467 g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
4468 G_CALLBACK (system_hostname_changed_cb), singleton);
4469 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
4470 G_CALLBACK (connection_added), singleton);
4471 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
4472 G_CALLBACK (connection_changed), singleton);
4473 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
4474 G_CALLBACK (connection_removed), singleton);
4475 g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
4476 G_CALLBACK (connection_changed), singleton);
4477
4478 nm_dbus_manager_register_object (priv->dbus_mgr, NM_DBUS_PATH, singleton);
4479
4480 g_signal_connect (nm_platform_get (),
4481 NM_PLATFORM_LINK_ADDED,
4482 G_CALLBACK (platform_link_added_cb),
4483 singleton);
4484 g_signal_connect (nm_platform_get (),
4485 NM_PLATFORM_LINK_REMOVED,
4486 G_CALLBACK (platform_link_removed_cb),
4487 singleton);
4488
4489 priv->atm_mgr = nm_atm_manager_new ();
4490 g_signal_connect (priv->atm_mgr,
4491 "device-added",
4492 G_CALLBACK (atm_device_added_cb),
4493 singleton);
4494 g_signal_connect (priv->atm_mgr,
4495 "device-removed",
4496 G_CALLBACK (atm_device_removed_cb),
4497 singleton);
4498
4499 priv->rfkill_mgr = nm_rfkill_manager_new ();
4500 g_signal_connect (priv->rfkill_mgr,
4501 "rfkill-changed",
4502 G_CALLBACK (rfkill_manager_rfkill_changed_cb),
4503 singleton);
4504
4505 priv->bluez_mgr = nm_bluez_manager_new (NM_CONNECTION_PROVIDER (priv->settings));
4506
4507 g_signal_connect (priv->bluez_mgr,
4508 NM_BLUEZ_MANAGER_BDADDR_ADDED,
4509 G_CALLBACK (bluez_manager_bdaddr_added_cb),
4510 singleton);
4511
4512 g_signal_connect (priv->bluez_mgr,
4513 NM_BLUEZ_MANAGER_BDADDR_REMOVED,
4514 G_CALLBACK (bluez_manager_bdaddr_removed_cb),
4515 singleton);
4516
4517 /* Force kernel WiFi rfkill state to follow NM saved wifi state in case
4518 * the BIOS doesn't save rfkill state, and to be consistent with user
4519 * changes to the WirelessEnabled property which toggles kernel rfkill.
4520 */
4521 rfkill_change_wifi (priv->radio_states[RFKILL_TYPE_WLAN].desc, initial_wifi_enabled);
4522
4523 return singleton;
4524 }
4525
4526 static void
4527 authority_changed_cb (gpointer user_data)
4528 {
4529 /* Let clients know they should re-check their authorization */
4530 g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
4531 }
4532
4533 static void
4534 dispose (GObject *object)
4535 {
4536 NMManager *manager = NM_MANAGER (object);
4537 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
4538 DBusGConnection *bus;
4539 DBusConnection *dbus_connection;
4540 GSList *iter;
4541
4542 if (priv->disposed) {
4543 G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
4544 return;
4545 }
4546 priv->disposed = TRUE;
4547
4548 g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
4549
4550 nm_auth_changed_func_unregister (authority_changed_cb, manager);
4551
4552 /* FIXME: remove when we handle bridges non-destructively */
4553 write_nm_created_bridges (manager);
4554
4555 /* Remove all devices */
4556 while (priv->devices)
4557 remove_device (manager, NM_DEVICE (priv->devices->data), TRUE);
4558
4559 if (priv->ac_cleanup_id) {
4560 g_source_remove (priv->ac_cleanup_id);
4561 priv->ac_cleanup_id = 0;
4562 }
4563
4564 for (iter = priv->active_connections; iter; iter = g_slist_next (iter))
4565 active_connection_removed (manager, NM_ACTIVE_CONNECTION (iter->data));
4566 g_slist_free (priv->active_connections);
4567 priv->active_connections = NULL;
4568 g_clear_object (&priv->primary_connection);
4569 g_clear_object (&priv->activating_connection);
4570
4571 g_clear_object (&priv->connectivity);
4572
4573 g_free (priv->hostname);
4574
4575 g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_default_device_changed), singleton);
4576 g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_activating_device_changed), singleton);
4577 g_object_unref (priv->policy);
4578
4579 g_object_unref (priv->settings);
4580 g_object_unref (priv->vpn_manager);
4581
4582 if (priv->modem_added_id) {
4583 g_source_remove (priv->modem_added_id);
4584 priv->modem_added_id = 0;
4585 }
4586 if (priv->modem_removed_id) {
4587 g_source_remove (priv->modem_removed_id);
4588 priv->modem_removed_id = 0;
4589 }
4590 g_object_unref (priv->modem_manager);
4591
4592 /* Unregister property filter */
4593 bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
4594 if (bus) {
4595 dbus_connection = dbus_g_connection_get_connection (bus);
4596 g_assert (dbus_connection);
4597 dbus_connection_remove_filter (dbus_connection, prop_filter, manager);
4598 }
4599 g_signal_handler_disconnect (priv->dbus_mgr, priv->dbus_connection_changed_id);
4600 priv->dbus_mgr = NULL;
4601
4602 if (priv->bluez_mgr)
4603 g_object_unref (priv->bluez_mgr);
4604
4605 if (priv->aipd_proxy)
4606 g_object_unref (priv->aipd_proxy);
4607
4608 if (priv->sleep_monitor)
4609 g_object_unref (priv->sleep_monitor);
4610
4611 if (priv->fw_monitor) {
4612 if (priv->fw_monitor_id)
4613 g_signal_handler_disconnect (priv->fw_monitor, priv->fw_monitor_id);
4614
4615 if (priv->fw_changed_id)
4616 g_source_remove (priv->fw_changed_id);
4617
4618 g_file_monitor_cancel (priv->fw_monitor);
4619 g_object_unref (priv->fw_monitor);
4620 }
4621
4622 g_hash_table_unref (priv->noauto_sw_devices);
4623
4624 g_slist_free (priv->factories);
4625
4626 if (priv->timestamp_update_id) {
4627 g_source_remove (priv->timestamp_update_id);
4628 priv->timestamp_update_id = 0;
4629 }
4630
4631 G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
4632 }
4633
4634 #define KERN_RFKILL_OP_CHANGE_ALL 3
4635 #define KERN_RFKILL_TYPE_WLAN 1
4636 struct rfkill_event {
4637 __u32 idx;
4638 __u8 type;
4639 __u8 op;
4640 __u8 soft, hard;
4641 } __attribute__((packed));
4642
4643 static void
4644 rfkill_change_wifi (const char *desc, gboolean enabled)
4645 {
4646 int fd;
4647 struct rfkill_event event;
4648 ssize_t len;
4649
4650 errno = 0;
4651 fd = open ("/dev/rfkill", O_RDWR);
4652 if (fd < 0) {
4653 if (errno == EACCES)
4654 nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device "
4655 "for WiFi radio control", desc);
4656 return;
4657 }
4658
4659 if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
4660 nm_log_warn (LOGD_RFKILL, "(%s): failed to set killswitch device for "
4661 "non-blocking operation", desc);
4662 close (fd);
4663 return;
4664 }
4665
4666 memset (&event, 0, sizeof (event));
4667 event.op = KERN_RFKILL_OP_CHANGE_ALL;
4668 event.type = KERN_RFKILL_TYPE_WLAN;
4669 event.soft = enabled ? 0 : 1;
4670
4671 len = write (fd, &event, sizeof (event));
4672 if (len < 0) {
4673 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
4674 desc, errno, g_strerror (errno));
4675 } else if (len == sizeof (event)) {
4676 nm_log_info (LOGD_RFKILL, "%s hardware radio set %s",
4677 desc, enabled ? "enabled" : "disabled");
4678 } else {
4679 /* Failed to write full structure */
4680 nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
4681 }
4682
4683 close (fd);
4684 }
4685
4686 static void
4687 manager_radio_user_toggled (NMManager *self,
4688 RadioState *rstate,
4689 gboolean enabled)
4690 {
4691 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4692 GError *error = NULL;
4693 gboolean old_enabled, new_enabled;
4694
4695 if (rstate->desc) {
4696 nm_log_dbg (LOGD_RFKILL, "(%s): setting radio %s by user",
4697 rstate->desc,
4698 enabled ? "enabled" : "disabled");
4699 }
4700
4701 /* Update enabled key in state file */
4702 if (priv->state_file) {
4703 if (!write_value_to_state_file (priv->state_file,
4704 "main", rstate->key,
4705 G_TYPE_BOOLEAN, (gpointer) &enabled,
4706 &error)) {
4707 nm_log_warn (LOGD_CORE, "writing to state file %s failed: (%d) %s.",
4708 priv->state_file,
4709 error ? error->code : -1,
4710 (error && error->message) ? error->message : "unknown");
4711 g_clear_error (&error);
4712 }
4713 }
4714
4715 /* When the user toggles the radio, their request should override any
4716 * daemon (like ModemManager) enabled state that can be changed. For WWAN
4717 * for example, we want the WwanEnabled property to reflect the daemon state
4718 * too so that users can toggle the modem powered, but we don't want that
4719 * daemon state to affect whether or not the user *can* turn it on, which is
4720 * what the kernel rfkill state does. So we ignore daemon enabled state
4721 * when determining what the new state should be since it shouldn't block
4722 * the user's request.
4723 */
4724 old_enabled = radio_enabled_for_rstate (rstate, TRUE);
4725 rstate->user_enabled = enabled;
4726 new_enabled = radio_enabled_for_rstate (rstate, FALSE);
4727 if (new_enabled != old_enabled) {
4728 manager_update_radio_enabled (self, rstate, new_enabled);
4729
4730 /* For WiFi only (for now) set the actual kernel rfkill state */
4731 if (rstate->rtype == RFKILL_TYPE_WLAN)
4732 rfkill_change_wifi (rstate->desc, new_enabled);
4733 }
4734 }
4735
4736 static void
4737 set_property (GObject *object, guint prop_id,
4738 const GValue *value, GParamSpec *pspec)
4739 {
4740 NMManager *self = NM_MANAGER (object);
4741 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4742
4743 switch (prop_id) {
4744 case PROP_NETWORKING_ENABLED:
4745 /* Construct only for now */
4746 priv->net_enabled = g_value_get_boolean (value);
4747 break;
4748 case PROP_WIRELESS_ENABLED:
4749 manager_radio_user_toggled (NM_MANAGER (object),
4750 &priv->radio_states[RFKILL_TYPE_WLAN],
4751 g_value_get_boolean (value));
4752 break;
4753 case PROP_WWAN_ENABLED:
4754 manager_radio_user_toggled (NM_MANAGER (object),
4755 &priv->radio_states[RFKILL_TYPE_WWAN],
4756 g_value_get_boolean (value));
4757 break;
4758 case PROP_WIMAX_ENABLED:
4759 manager_radio_user_toggled (NM_MANAGER (object),
4760 &priv->radio_states[RFKILL_TYPE_WIMAX],
4761 g_value_get_boolean (value));
4762 break;
4763 default:
4764 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4765 break;
4766 }
4767 }
4768
4769 static void
4770 get_property (GObject *object, guint prop_id,
4771 GValue *value, GParamSpec *pspec)
4772 {
4773 NMManager *self = NM_MANAGER (object);
4774 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4775 GSList *iter;
4776 GPtrArray *active;
4777 const char *path;
4778
4779 switch (prop_id) {
4780 case PROP_VERSION:
4781 g_value_set_string (value, VERSION);
4782 break;
4783 case PROP_STATE:
4784 nm_manager_update_state (self);
4785 g_value_set_uint (value, priv->state);
4786 break;
4787 case PROP_STARTUP:
4788 g_value_set_boolean (value, priv->startup);
4789 break;
4790 case PROP_NETWORKING_ENABLED:
4791 g_value_set_boolean (value, priv->net_enabled);
4792 break;
4793 case PROP_WIRELESS_ENABLED:
4794 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
4795 break;
4796 case PROP_WIRELESS_HARDWARE_ENABLED:
4797 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
4798 break;
4799 case PROP_WWAN_ENABLED:
4800 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
4801 break;
4802 case PROP_WWAN_HARDWARE_ENABLED:
4803 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
4804 break;
4805 case PROP_WIMAX_ENABLED:
4806 g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WIMAX, TRUE));
4807 break;
4808 case PROP_WIMAX_HARDWARE_ENABLED:
4809 g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled);
4810 break;
4811 case PROP_ACTIVE_CONNECTIONS:
4812 active = g_ptr_array_sized_new (3);
4813 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
4814 path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (iter->data));
4815 g_ptr_array_add (active, g_strdup (path));
4816 }
4817 g_value_take_boxed (value, active);
4818 break;
4819 case PROP_CONNECTIVITY:
4820 g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
4821 break;
4822 case PROP_PRIMARY_CONNECTION:
4823 path = priv->primary_connection ? nm_active_connection_get_path (priv->primary_connection) : "/";
4824 g_value_set_boxed (value, path);
4825 break;
4826 case PROP_ACTIVATING_CONNECTION:
4827 path = priv->activating_connection ? nm_active_connection_get_path (priv->activating_connection) : "/";
4828 g_value_set_boxed (value, path);
4829 break;
4830 case PROP_HOSTNAME:
4831 g_value_set_string (value, priv->hostname);
4832 break;
4833 case PROP_SLEEPING:
4834 g_value_set_boolean (value, priv->sleeping);
4835 break;
4836 default:
4837 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4838 break;
4839 }
4840 }
4841
4842 static gboolean
4843 periodic_update_active_connection_timestamps (gpointer user_data)
4844 {
4845 NMManager *manager = NM_MANAGER (user_data);
4846 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
4847 GSList *iter;
4848
4849 for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
4850 NMActiveConnection *ac = iter->data;
4851 NMSettingsConnection *connection;
4852
4853 if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
4854 connection = NM_SETTINGS_CONNECTION (nm_active_connection_get_connection (ac));
4855 nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
4856 }
4857 }
4858
4859 return TRUE;
4860 }
4861
4862 static void
4863 dbus_connection_changed_cb (NMDBusManager *dbus_mgr,
4864 DBusConnection *dbus_connection,
4865 gpointer user_data)
4866 {
4867 NMManager *self = NM_MANAGER (user_data);
4868
4869 if (dbus_connection) {
4870 /* Register property filter on new connection; there's no reason this
4871 * should fail except out-of-memory or program error; if it does fail
4872 * then there's no Manager property access control, which is bad.
4873 */
4874 g_assert (dbus_connection_add_filter (dbus_connection, prop_filter, self, NULL));
4875 }
4876 }
4877
4878 static void
4879 nm_manager_init (NMManager *manager)
4880 {
4881 NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
4882 DBusGConnection *g_connection;
4883 guint i;
4884 GFile *file;
4885
4886 /* Initialize rfkill structures and states */
4887 memset (priv->radio_states, 0, sizeof (priv->radio_states));
4888
4889 priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
4890 priv->radio_states[RFKILL_TYPE_WLAN].key = "WirelessEnabled";
4891 priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
4892 priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
4893 priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
4894 priv->radio_states[RFKILL_TYPE_WLAN].other_enabled_func = nm_manager_get_ipw_rfkill_state;
4895 priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
4896
4897 priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
4898 priv->radio_states[RFKILL_TYPE_WWAN].key = "WWANEnabled";
4899 priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
4900 priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
4901 priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
4902 priv->radio_states[RFKILL_TYPE_WWAN].daemon_enabled_func = nm_manager_get_modem_enabled_state;
4903 priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
4904
4905 priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE;
4906 priv->radio_states[RFKILL_TYPE_WIMAX].key = "WiMAXEnabled";
4907 priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED;
4908 priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED;
4909 priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX";
4910 priv->radio_states[RFKILL_TYPE_WIMAX].other_enabled_func = NULL;
4911 priv->radio_states[RFKILL_TYPE_WIMAX].rtype = RFKILL_TYPE_WIMAX;
4912
4913 for (i = 0; i < RFKILL_TYPE_MAX; i++)
4914 priv->radio_states[i].hw_enabled = TRUE;
4915
4916 priv->sleeping = FALSE;
4917 priv->state = NM_STATE_DISCONNECTED;
4918 priv->startup = TRUE;
4919
4920 priv->dbus_mgr = nm_dbus_manager_get ();
4921 priv->dbus_connection_changed_id = g_signal_connect (priv->dbus_mgr,
4922 NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED,
4923 G_CALLBACK (dbus_connection_changed_cb),
4924 manager);
4925
4926 priv->modem_manager = nm_modem_manager_get ();
4927 priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added",
4928 G_CALLBACK (modem_added), manager);
4929 priv->modem_removed_id = g_signal_connect (priv->modem_manager, "modem-removed",
4930 G_CALLBACK (modem_removed), manager);
4931
4932 priv->vpn_manager = nm_vpn_manager_get ();
4933
4934 g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
4935
4936 /* avahi-autoipd stuff */
4937 priv->aipd_proxy = dbus_g_proxy_new_for_name (g_connection,
4938 NM_AUTOIP_DBUS_SERVICE,
4939 "/",
4940 NM_AUTOIP_DBUS_IFACE);
4941 if (priv->aipd_proxy) {
4942 dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
4943 G_TYPE_NONE,
4944 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
4945 G_TYPE_INVALID);
4946
4947 dbus_g_proxy_add_signal (priv->aipd_proxy,
4948 "Event",
4949 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
4950 G_TYPE_INVALID);
4951
4952 dbus_g_proxy_connect_signal (priv->aipd_proxy, "Event",
4953 G_CALLBACK (aipd_handle_event),
4954 manager,
4955 NULL);
4956 } else
4957 nm_log_warn (LOGD_AUTOIP4, "could not initialize avahi-autoipd D-Bus proxy");
4958
4959 /* sleep/wake handling */
4960 priv->sleep_monitor = nm_sleep_monitor_get ();
4961 g_signal_connect (priv->sleep_monitor, "sleeping",
4962 G_CALLBACK (sleeping_cb), manager);
4963 g_signal_connect (priv->sleep_monitor, "resuming",
4964 G_CALLBACK (resuming_cb), manager);
4965
4966 /* Listen for authorization changes */
4967 nm_auth_changed_func_register (authority_changed_cb, manager);
4968
4969 /* Monitor the firmware directory */
4970 if (strlen (KERNEL_FIRMWARE_DIR)) {
4971 file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/");
4972 priv->fw_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
4973 g_object_unref (file);
4974 }
4975
4976 if (priv->fw_monitor) {
4977 priv->fw_monitor_id = g_signal_connect (priv->fw_monitor, "changed",
4978 G_CALLBACK (firmware_dir_changed),
4979 manager);
4980 nm_log_info (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
4981 KERNEL_FIRMWARE_DIR);
4982 } else {
4983 nm_log_warn (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
4984 KERNEL_FIRMWARE_DIR);
4985 }
4986
4987 /* Hash table storing software devices that should not auto activate */
4988 priv->noauto_sw_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
4989
4990 load_device_factories (manager);
4991
4992 /* Update timestamps in active connections */
4993 priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager);
4994 }
4995
4996 static void
4997 nm_manager_class_init (NMManagerClass *manager_class)
4998 {
4999 GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
5000
5001 g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
5002
5003 /* virtual methods */
5004 object_class->set_property = set_property;
5005 object_class->get_property = get_property;
5006 object_class->dispose = dispose;
5007
5008 /* properties */
5009 g_object_class_install_property
5010 (object_class, PROP_VERSION,
5011 g_param_spec_string (NM_MANAGER_VERSION,
5012 "Version",
5013 "NetworkManager version",
5014 NULL,
5015 G_PARAM_READABLE));
5016
5017 g_object_class_install_property
5018 (object_class, PROP_STATE,
5019 g_param_spec_uint (NM_MANAGER_STATE,
5020 "State",
5021 "Current state",
5022 0, NM_STATE_DISCONNECTED, 0,
5023 G_PARAM_READABLE));
5024
5025 g_object_class_install_property
5026 (object_class, PROP_STARTUP,
5027 g_param_spec_boolean (NM_MANAGER_STARTUP,
5028 "Startup",
5029 "Is NetworkManager still starting up",
5030 TRUE,
5031 G_PARAM_READABLE));
5032
5033 g_object_class_install_property
5034 (object_class, PROP_NETWORKING_ENABLED,
5035 g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED,
5036 "NetworkingEnabled",
5037 "Is networking enabled",
5038 TRUE,
5039 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
5040
5041 g_object_class_install_property
5042 (object_class, PROP_WIRELESS_ENABLED,
5043 g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED,
5044 "WirelessEnabled",
5045 "Is wireless enabled",
5046 TRUE,
5047 G_PARAM_READWRITE));
5048
5049 g_object_class_install_property
5050 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
5051 g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED,
5052 "WirelessHardwareEnabled",
5053 "RF kill state",
5054 TRUE,
5055 G_PARAM_READABLE));
5056
5057 g_object_class_install_property
5058 (object_class, PROP_WWAN_ENABLED,
5059 g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED,
5060 "WwanEnabled",
5061 "Is mobile broadband enabled",
5062 TRUE,
5063 G_PARAM_READWRITE));
5064
5065 g_object_class_install_property
5066 (object_class, PROP_WWAN_HARDWARE_ENABLED,
5067 g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED,
5068 "WwanHardwareEnabled",
5069 "Whether WWAN is disabled by a hardware switch or not",
5070 TRUE,
5071 G_PARAM_READABLE));
5072
5073 g_object_class_install_property
5074 (object_class, PROP_WIMAX_ENABLED,
5075 g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED,
5076 "WimaxEnabled",
5077 "Is WiMAX enabled",
5078 TRUE,
5079 G_PARAM_READWRITE));
5080
5081 g_object_class_install_property
5082 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
5083 g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED,
5084 "WimaxHardwareEnabled",
5085 "Whether WiMAX is disabled by a hardware switch or not",
5086 TRUE,
5087 G_PARAM_READABLE));
5088
5089 g_object_class_install_property
5090 (object_class, PROP_ACTIVE_CONNECTIONS,
5091 g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS,
5092 "Active connections",
5093 "Active connections",
5094 DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
5095 G_PARAM_READABLE));
5096
5097 g_object_class_install_property
5098 (object_class, PROP_CONNECTIVITY,
5099 g_param_spec_uint (NM_MANAGER_CONNECTIVITY,
5100 "Connectivity",
5101 "Connectivity state",
5102 NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
5103 G_PARAM_READABLE));
5104
5105 g_object_class_install_property
5106 (object_class, PROP_PRIMARY_CONNECTION,
5107 g_param_spec_boxed (NM_MANAGER_PRIMARY_CONNECTION,
5108 "Primary connection",
5109 "Primary connection",
5110 DBUS_TYPE_G_OBJECT_PATH,
5111 G_PARAM_READABLE));
5112
5113 g_object_class_install_property
5114 (object_class, PROP_ACTIVATING_CONNECTION,
5115 g_param_spec_boxed (NM_MANAGER_ACTIVATING_CONNECTION,
5116 "Activating connection",
5117 "Activating connection",
5118 DBUS_TYPE_G_OBJECT_PATH,
5119 G_PARAM_READABLE));
5120
5121 /* Hostname is not exported over D-Bus */
5122 g_object_class_install_property
5123 (object_class, PROP_HOSTNAME,
5124 g_param_spec_string (NM_MANAGER_HOSTNAME,
5125 "Hostname",
5126 "Hostname",
5127 NULL,
5128 G_PARAM_READABLE));
5129
5130 /* Sleeping is not exported over D-Bus */
5131 g_object_class_install_property
5132 (object_class, PROP_SLEEPING,
5133 g_param_spec_boolean (NM_MANAGER_SLEEPING,
5134 "Sleeping",
5135 "Sleeping",
5136 FALSE,
5137 G_PARAM_READABLE));
5138
5139 /* signals */
5140 signals[DEVICE_ADDED] =
5141 g_signal_new ("device-added",
5142 G_OBJECT_CLASS_TYPE (object_class),
5143 G_SIGNAL_RUN_FIRST,
5144 G_STRUCT_OFFSET (NMManagerClass, device_added),
5145 NULL, NULL, NULL,
5146 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5147
5148 signals[DEVICE_REMOVED] =
5149 g_signal_new ("device-removed",
5150 G_OBJECT_CLASS_TYPE (object_class),
5151 G_SIGNAL_RUN_FIRST,
5152 G_STRUCT_OFFSET (NMManagerClass, device_removed),
5153 NULL, NULL, NULL,
5154 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5155
5156 signals[STATE_CHANGED] =
5157 g_signal_new ("state-changed",
5158 G_OBJECT_CLASS_TYPE (object_class),
5159 G_SIGNAL_RUN_FIRST,
5160 G_STRUCT_OFFSET (NMManagerClass, state_changed),
5161 NULL, NULL, NULL,
5162 G_TYPE_NONE, 1, G_TYPE_UINT);
5163
5164 signals[CHECK_PERMISSIONS] =
5165 g_signal_new ("check-permissions",
5166 G_OBJECT_CLASS_TYPE (object_class),
5167 G_SIGNAL_RUN_FIRST,
5168 0, NULL, NULL, NULL,
5169 G_TYPE_NONE, 0);
5170
5171 signals[USER_PERMISSIONS_CHANGED] =
5172 g_signal_new ("user-permissions-changed",
5173 G_OBJECT_CLASS_TYPE (object_class),
5174 G_SIGNAL_RUN_FIRST,
5175 0, NULL, NULL, NULL,
5176 G_TYPE_NONE, 0);
5177
5178 signals[ACTIVE_CONNECTION_ADDED] =
5179 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
5180 G_OBJECT_CLASS_TYPE (object_class),
5181 G_SIGNAL_RUN_FIRST,
5182 0, NULL, NULL, NULL,
5183 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5184
5185 signals[ACTIVE_CONNECTION_REMOVED] =
5186 g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
5187 G_OBJECT_CLASS_TYPE (object_class),
5188 G_SIGNAL_RUN_FIRST,
5189 0, NULL, NULL, NULL,
5190 G_TYPE_NONE, 1, G_TYPE_OBJECT);
5191
5192 nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
5193 G_TYPE_FROM_CLASS (manager_class),
5194 &dbus_glib_nm_manager_object_info);
5195
5196 dbus_g_error_domain_register (NM_MANAGER_ERROR, NULL, NM_TYPE_MANAGER_ERROR);
5197 dbus_g_error_domain_register (NM_LOGGING_ERROR, "org.freedesktop.NetworkManager.Logging", NM_TYPE_LOGGING_ERROR);
5198 }
5199
5200