~stgraber/+junk/nm-ofono

« back to all changes in this revision

Viewing changes to .pc/lp191889_always_offline_with_unmanaged_devices.patch/src/nm-manager.c

  • Committer: Stéphane Graber
  • Date: 2013-03-15 18:27:57 UTC
  • Revision ID: stgraber@ubuntu.com-20130315182757-7bcjymubsn3lsshs
Import of NM 0.9.8.0

Show diffs side-by-side

added added

removed removed

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