1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
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.
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.
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.
18 * Copyright (C) 2008 - 2014 Red Hat, Inc.
21 #include "nm-default.h"
23 #include "nm-active-connection.h"
24 #include "nm-dbus-interface.h"
25 #include "nm-device.h"
26 #include "nm-settings-connection.h"
27 #include "nm-simple-connection.h"
28 #include "nm-auth-utils.h"
29 #include "nm-auth-subject.h"
30 #include "NetworkManagerUtils.h"
31 #include "nm-core-internal.h"
33 #include "nmdbus-active-connection.h"
35 /* Base class for anything implementing the Connection.Active D-Bus interface */
36 G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORTED_OBJECT)
38 #define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
39 NM_TYPE_ACTIVE_CONNECTION, \
40 NMActiveConnectionPrivate))
43 NMSettingsConnection *settings_connection;
44 NMConnection *applied_connection;
45 char *specific_object;
50 char *pending_activation_id;
54 NMActiveConnectionState state;
58 NMAuthSubject *subject;
59 NMActiveConnection *master;
60 gboolean master_ready;
65 const char *wifi_shared_permission;
66 NMActiveConnectionAuthResultFunc result_func;
69 } NMActiveConnectionPrivate;
89 PROP_INT_SETTINGS_CONNECTION,
93 PROP_INT_MASTER_READY,
100 DEVICE_METERED_CHANGED,
103 static guint signals[LAST_SIGNAL] = { 0 };
105 static void check_master_ready (NMActiveConnection *self);
106 static void _device_cleanup (NMActiveConnection *self);
108 /****************************************************************/
110 #define _NMLOG_DOMAIN LOGD_DEVICE
111 #define _NMLOG_PREFIX_NAME "active-connection"
112 #define _NMLOG(level, ...) \
116 nm_log ((level), _NMLOG_DOMAIN, \
117 "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
118 _NMLOG_PREFIX_NAME, \
119 self ? nm_sprintf_buf (_sbuf, "[%p]", self) : "" \
120 _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
123 /****************************************************************/
125 NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, NMActiveConnectionState,
126 NM_UTILS_LOOKUP_DEFAULT (NULL),
127 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_UNKNOWN, "unknown"),
128 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATING, "activating"),
129 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATED, "activated"),
130 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, "deactivating"),
131 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATED, "deactivated"),
133 #define state_to_string(state) NM_UTILS_LOOKUP_STR (_state_to_string, state)
135 /****************************************************************/
137 NMActiveConnectionState
138 nm_active_connection_get_state (NMActiveConnection *self)
140 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->state;
144 nm_active_connection_set_state (NMActiveConnection *self,
145 NMActiveConnectionState new_state)
147 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
148 NMActiveConnectionState old_state;
150 if (priv->state == new_state)
153 /* DEACTIVATED is a terminal state */
154 if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
155 g_return_if_fail (new_state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
157 _LOGD ("set state %s (was %s)",
158 state_to_string (new_state),
159 state_to_string (priv->state));
161 old_state = priv->state;
162 priv->state = new_state;
163 priv->state_set = TRUE;
164 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
166 check_master_ready (self);
168 if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
169 || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
170 nm_settings_connection_update_timestamp (priv->settings_connection,
171 (guint64) time (NULL), TRUE);
175 if ( old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED
176 && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
177 priv->pending_activation_id)
179 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
180 g_clear_pointer (&priv->pending_activation_id, g_free);
184 if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
185 || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
186 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP4_CONFIG);
187 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DHCP4_CONFIG);
188 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP6_CONFIG);
189 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DHCP6_CONFIG);
192 if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
193 /* Device is no longer relevant when deactivated. So remove it and
194 * emit property change notification so clients re-read the value,
195 * which will be NULL due to conditions in get_property().
197 _device_cleanup (self);
198 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
203 nm_active_connection_get_settings_connection_id (NMActiveConnection *self)
205 NMSettingsConnection *con;
207 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
209 con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection;
211 ? nm_connection_get_id (NM_CONNECTION (con))
215 NMSettingsConnection *
216 _nm_active_connection_get_settings_connection (NMActiveConnection *self)
218 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
220 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection;
223 NMSettingsConnection *
224 nm_active_connection_get_settings_connection (NMActiveConnection *self)
226 NMSettingsConnection *con;
228 con = _nm_active_connection_get_settings_connection (self);
230 /* Only call this function on an active-connection that is already
231 * fully set-up (i.e. that has a settings-connection). Other uses
233 g_return_val_if_fail (con, NULL);
238 nm_active_connection_get_applied_connection (NMActiveConnection *self)
242 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
244 con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection;
246 /* Only call this function on an active-connection that is already
247 * fully set-up (i.e. that has a settings-connection). Other uses
249 g_return_val_if_fail (con, NULL);
254 nm_active_connection_set_settings_connection (NMActiveConnection *self,
255 NMSettingsConnection *connection)
257 NMActiveConnectionPrivate *priv;
259 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
261 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
263 g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
264 g_return_if_fail (!priv->settings_connection);
265 g_return_if_fail (!priv->applied_connection);
267 /* Can't change connection after the ActiveConnection is exported over D-Bus.
269 * Later, we want to change the settings-connection of an activated connection.
270 * When doing that, this changes the assumption that the settings-connection
271 * never changes (once it's set). That has effects for NMVpnConnection and
272 * NMActivationRequest.
273 * For example, we'd have to cancel all pending seret requests. */
274 g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
276 priv->settings_connection = g_object_ref (connection);
277 priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
278 nm_connection_clear_secrets (priv->applied_connection);
282 nm_active_connection_has_unmodified_applied_connection (NMActiveConnection *self, NMSettingCompareFlags compare_flags)
284 NMActiveConnectionPrivate *priv;
286 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
288 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
290 g_return_val_if_fail (priv->settings_connection, FALSE);
292 return nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection,
293 priv->applied_connection,
297 /*******************************************************************/
300 nm_active_connection_clear_secrets (NMActiveConnection *self)
302 NMActiveConnectionPrivate *priv;
304 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
306 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
308 if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection,
309 priv->applied_connection,
310 NM_SETTING_COMPARE_FLAG_NONE))
311 nm_connection_clear_secrets ((NMConnection *) priv->settings_connection);
312 nm_connection_clear_secrets (priv->applied_connection);
315 /*******************************************************************/
318 nm_active_connection_get_specific_object (NMActiveConnection *self)
320 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->specific_object;
324 nm_active_connection_set_specific_object (NMActiveConnection *self,
325 const char *specific_object)
327 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
329 /* Nothing that calls this function should be using paths from D-Bus,
330 * where NM uses "/" to mean NULL.
332 g_assert (g_strcmp0 (specific_object, "/") != 0);
334 if (g_strcmp0 (priv->specific_object, specific_object) == 0)
337 g_free (priv->specific_object);
338 priv->specific_object = g_strdup (specific_object);
339 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT);
343 nm_active_connection_set_default (NMActiveConnection *self, gboolean is_default)
345 NMActiveConnectionPrivate *priv;
347 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
349 is_default = !!is_default;
351 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
352 if (priv->is_default == is_default)
355 priv->is_default = is_default;
356 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
360 nm_active_connection_get_default (NMActiveConnection *self)
362 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
364 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default;
368 nm_active_connection_set_default6 (NMActiveConnection *self, gboolean is_default6)
370 NMActiveConnectionPrivate *priv;
372 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
374 is_default6 = !!is_default6;
376 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
377 if (priv->is_default6 == is_default6)
380 priv->is_default6 = is_default6;
381 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
385 nm_active_connection_get_default6 (NMActiveConnection *self)
387 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
389 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default6;
393 nm_active_connection_get_subject (NMActiveConnection *self)
395 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
397 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject;
401 nm_active_connection_get_user_requested (NMActiveConnection *self)
403 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
405 return nm_auth_subject_is_unix_process (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject);
409 nm_active_connection_get_device (NMActiveConnection *self)
411 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
413 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->device;
417 device_state_changed (NMDevice *device,
418 NMDeviceState new_state,
419 NMDeviceState old_state,
420 NMDeviceStateReason reason,
423 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
424 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
426 /* When already deactivated or before activation, device state changes are useless */
427 if (priv->state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
429 if (old_state < NM_DEVICE_STATE_DISCONNECTED)
432 /* Let subclasses handle the state change */
433 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->device_state_changed)
434 NM_ACTIVE_CONNECTION_GET_CLASS (self)->device_state_changed (self, device, new_state, old_state);
438 device_master_changed (GObject *object,
442 NMDevice *device = NM_DEVICE (object);
443 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
444 NMActiveConnection *master;
445 NMActiveConnectionState master_state;
447 if (NM_ACTIVE_CONNECTION (nm_device_get_act_request (device)) != self)
449 if (!nm_device_get_master (device))
451 if (!nm_active_connection_get_master (self))
453 g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_master_changed), self);
455 master = nm_active_connection_get_master (self);
456 master_state = nm_active_connection_get_state (master);
457 if (master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
458 /* Master failed before attaching the slave */
459 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
460 NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
465 device_metered_changed (GObject *object,
469 NMActiveConnection *self = (NMActiveConnection *) user_data;
470 NMDevice *device = NM_DEVICE (object);
472 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
473 g_signal_emit (self, signals[DEVICE_METERED_CHANGED], 0, nm_device_get_metered (device));
477 nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
479 NMActiveConnectionPrivate *priv;
480 gs_unref_object NMDevice *old_device = NULL;
482 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
483 g_return_val_if_fail (!device || NM_IS_DEVICE (device), FALSE);
485 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
486 if (device == priv->device)
489 _LOGD ("set device %s%s%s [%p]",
490 NM_PRINT_FMT_QUOTED (device && nm_device_get_iface (device),
492 nm_device_get_iface (device),
494 device ? "(unknown)" : "(null)"),
497 old_device = priv->device ? g_object_ref (priv->device) : NULL;
498 _device_cleanup (self);
501 /* Device obviously can't be its own master */
502 g_return_val_if_fail (!priv->master || device != nm_active_connection_get_device (priv->master), FALSE);
504 priv->device = g_object_ref (device);
506 g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
507 G_CALLBACK (device_state_changed), self);
508 g_signal_connect (device, "notify::master",
509 G_CALLBACK (device_master_changed), self);
510 g_signal_connect (device, "notify::" NM_DEVICE_METERED,
511 G_CALLBACK (device_metered_changed), self);
513 if (!priv->assumed) {
514 priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self);
515 nm_device_add_pending_action (device, priv->pending_activation_id, TRUE);
518 /* The ActiveConnection's device can only be cleared after the
519 * connection is activated.
521 g_warn_if_fail (priv->state > NM_ACTIVE_CONNECTION_STATE_UNKNOWN);
524 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_DEVICE);
526 g_signal_emit (self, signals[DEVICE_CHANGED], 0, priv->device, old_device);
528 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
534 nm_active_connection_get_master (NMActiveConnection *self)
536 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
538 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master;
542 * nm_active_connection_get_master_ready:
543 * @self: the #NMActiveConnection
545 * Returns: %TRUE if the connection has a master connection, and that
546 * master connection is ready to accept slaves. Otherwise %FALSE.
549 nm_active_connection_get_master_ready (NMActiveConnection *self)
551 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
553 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master_ready;
557 check_master_ready (NMActiveConnection *self)
559 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
560 gboolean signalling = FALSE;
562 /* ActiveConnetions don't enter the ACTIVATING state until they have a
563 * NMDevice in PREPARE or higher states, so the master active connection's
564 * device will be ready to accept slaves when the master is in ACTIVATING
567 if ( !priv->master_ready
569 && priv->state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING
570 && NM_IN_SET (nm_active_connection_get_state (priv->master),
571 NM_ACTIVE_CONNECTION_STATE_ACTIVATING,
572 NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
576 _LOGD ("check-master-ready: %s (state %s, %s)",
579 : (priv->master_ready ? "already signalled" : "not signalling"),
580 state_to_string (priv->state),
582 ? nm_sprintf_bufa (128, "master %p is in state %s",
584 state_to_string (nm_active_connection_get_state (priv->master)))
588 priv->master_ready = TRUE;
589 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_MASTER_READY);
591 /* Also notify clients to recheck the exported 'master' property to
592 * ensure that if the master connection was created without a device
593 * that we notify clients when the master device is known.
595 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_MASTER);
600 master_state_cb (NMActiveConnection *master,
604 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
605 NMActiveConnectionState master_state = nm_active_connection_get_state (master);
606 NMDevice *master_device = nm_active_connection_get_device (master);
608 check_master_ready (self);
610 if ( master_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATING
611 && (!master_device || !nm_device_is_real (master_device))) {
612 /* Master failed without ever creating or realizing its device */
613 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
614 NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
619 * nm_active_connection_set_master:
620 * @self: the #NMActiveConnection
621 * @master: if the activation depends on another device (ie, bond or bridge
622 * master to which this device will be enslaved) pass the #NMActiveConnection
623 * that this activation request is a child of
625 * Sets the master active connection of @self.
628 nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *master)
630 NMActiveConnectionPrivate *priv;
632 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
633 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (master));
635 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
637 /* Master is write-once, and must be set before exporting the object */
638 g_return_if_fail (priv->master == NULL);
639 g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
641 /* Note, the master ActiveConnection may not yet have a device */
642 g_return_if_fail (priv->device != nm_active_connection_get_device (master));
645 _LOGD ("set master %p, %s, state %s",
647 nm_active_connection_get_settings_connection_id (master),
648 state_to_string (nm_active_connection_get_state (master)));
650 priv->master = g_object_ref (master);
651 g_signal_connect (priv->master,
652 "notify::" NM_ACTIVE_CONNECTION_STATE,
653 (GCallback) master_state_cb,
656 check_master_ready (self);
660 nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed)
662 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
664 g_return_if_fail (priv->assumed == FALSE);
665 priv->assumed = assumed;
667 if (priv->pending_activation_id) {
668 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
669 g_clear_pointer (&priv->pending_activation_id, g_free);
674 nm_active_connection_get_assumed (NMActiveConnection *self)
676 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->assumed;
679 /****************************************************************/
682 auth_done (NMAuthChain *chain,
684 GDBusMethodInvocation *unused,
687 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
688 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
689 NMAuthCallResult result;
691 g_assert (priv->chain == chain);
692 g_assert (priv->result_func != NULL);
694 /* Must stay alive over the callback */
698 priv->result_func (self, FALSE, error->message, priv->user_data1, priv->user_data2);
702 /* Caller has had a chance to obtain authorization, so we only need to
703 * check for 'yes' here.
705 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
706 if (result != NM_AUTH_CALL_RESULT_YES) {
707 priv->result_func (self,
709 "Not authorized to control networking.",
715 if (priv->wifi_shared_permission) {
716 result = nm_auth_chain_get_result (chain, priv->wifi_shared_permission);
717 if (result != NM_AUTH_CALL_RESULT_YES) {
718 priv->result_func (self,
720 "Not authorized to share connections via wifi.",
727 /* Otherwise authorized and available to activate */
728 priv->result_func (self, TRUE, NULL, priv->user_data1, priv->user_data2);
731 nm_auth_chain_unref (chain);
733 priv->result_func = NULL;
734 priv->user_data1 = NULL;
735 priv->user_data2 = NULL;
737 g_object_unref (self);
741 * nm_active_connection_authorize:
742 * @self: the #NMActiveConnection
743 * @initial_connection: (allow-none): for add-and-activate, there
744 * is no @settings_connection available when creating the active connection.
745 * Instead pass an alternative connection.
746 * @result_func: function to be called on success or error
747 * @user_data1: pointer passed to @result_func
748 * @user_data2: additional pointer passed to @result_func
750 * Checks whether the subject that initiated the active connection (read from
751 * the #NMActiveConnection::subject property) is authorized to complete this
752 * activation request.
755 nm_active_connection_authorize (NMActiveConnection *self,
756 NMConnection *initial_connection,
757 NMActiveConnectionAuthResultFunc result_func,
761 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
762 const char *wifi_permission = NULL;
765 g_return_if_fail (result_func != NULL);
766 g_return_if_fail (priv->chain == NULL);
768 if (initial_connection) {
769 g_return_if_fail (NM_IS_CONNECTION (initial_connection));
770 g_return_if_fail (!priv->settings_connection);
771 g_return_if_fail (!priv->applied_connection);
772 con = initial_connection;
774 g_return_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection));
775 g_return_if_fail (NM_IS_CONNECTION (priv->applied_connection));
776 con = priv->applied_connection;
779 priv->chain = nm_auth_chain_new_subject (priv->subject, NULL, auth_done, self);
780 g_assert (priv->chain);
782 /* Check that the subject is allowed to use networking at all */
783 nm_auth_chain_add_call (priv->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
785 /* Shared wifi connections require special permissions too */
786 wifi_permission = nm_utils_get_shared_wifi_permission (con);
787 if (wifi_permission) {
788 priv->wifi_shared_permission = wifi_permission;
789 nm_auth_chain_add_call (priv->chain, wifi_permission, TRUE);
792 /* Wait for authorization */
793 priv->result_func = result_func;
794 priv->user_data1 = user_data1;
795 priv->user_data2 = user_data2;
798 /****************************************************************/
801 _version_id_new (void)
803 static guint64 id = 0;
809 nm_active_connection_version_id_get (NMActiveConnection *self)
811 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
813 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->version_id;
817 nm_active_connection_version_id_bump (NMActiveConnection *self)
819 NMActiveConnectionPrivate *priv;
821 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
823 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
824 priv->version_id = _version_id_new ();
825 _LOGT ("new version-id %llu", (long long unsigned) priv->version_id);
826 return priv->version_id;
829 /****************************************************************/
832 nm_active_connection_init (NMActiveConnection *self)
834 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
838 priv->version_id = _version_id_new ();
842 constructed (GObject *object)
844 NMActiveConnection *self = (NMActiveConnection *) object;
845 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
847 G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
849 _LOGD ("constructed (%s, version-id %llu)", G_OBJECT_TYPE_NAME (self), (long long unsigned) priv->version_id);
851 g_return_if_fail (priv->subject);
855 set_property (GObject *object, guint prop_id,
856 const GValue *value, GParamSpec *pspec)
858 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
860 NMSettingsConnection *con;
863 case PROP_INT_SETTINGS_CONNECTION:
865 con = g_value_get_object (value);
867 priv->settings_connection = g_object_ref (con);
868 priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (con));
869 nm_connection_clear_secrets (priv->applied_connection);
872 case PROP_INT_DEVICE:
874 nm_active_connection_set_device (NM_ACTIVE_CONNECTION (object), g_value_get_object (value));
876 case PROP_INT_SUBJECT:
877 priv->subject = g_value_dup_object (value);
879 case PROP_INT_MASTER:
880 nm_active_connection_set_master (NM_ACTIVE_CONNECTION (object), g_value_get_object (value));
882 case PROP_SPECIFIC_OBJECT:
883 tmp = g_value_get_string (value);
884 /* NM uses "/" to mean NULL */
885 if (g_strcmp0 (tmp, "/") != 0)
886 priv->specific_object = g_strdup (tmp);
889 priv->is_default = !!g_value_get_boolean (value);
892 priv->is_default6 = !!g_value_get_boolean (value);
895 priv->vpn = g_value_get_boolean (value);
900 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
906 get_property (GObject *object, guint prop_id,
907 GValue *value, GParamSpec *pspec)
909 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
911 NMDevice *master_device = NULL;
914 case PROP_CONNECTION:
915 g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->settings_connection)));
918 g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection)));
921 g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection)));
924 g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection)));
926 case PROP_SPECIFIC_OBJECT:
927 g_value_set_string (value, priv->specific_object ? priv->specific_object : "/");
930 devices = g_ptr_array_sized_new (2);
931 if (priv->device && priv->state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
932 g_ptr_array_add (devices, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (priv->device))));
933 g_ptr_array_add (devices, NULL);
934 g_value_take_boxed (value, (char **) g_ptr_array_free (devices, FALSE));
938 g_value_set_uint (value, priv->state);
940 /* When the AC has just been created, its externally-visible state should
941 * be "ACTIVATING", even though internally it is "UNKNOWN".
943 g_value_set_uint (value, NM_ACTIVE_CONNECTION_STATE_ACTIVATING);
947 g_value_set_boolean (value, priv->is_default);
949 case PROP_IP4_CONFIG:
950 /* The IP and DHCP config properties may be overridden by a subclass */
951 g_value_set_string (value, "/");
953 case PROP_DHCP4_CONFIG:
954 g_value_set_string (value, "/");
957 g_value_set_boolean (value, priv->is_default6);
959 case PROP_IP6_CONFIG:
960 g_value_set_string (value, "/");
962 case PROP_DHCP6_CONFIG:
963 g_value_set_string (value, "/");
966 g_value_set_boolean (value, priv->vpn);
970 master_device = nm_active_connection_get_device (priv->master);
971 nm_utils_g_value_set_object_path (value, master_device);
973 case PROP_INT_SUBJECT:
974 g_value_set_object (value, priv->subject);
976 case PROP_INT_MASTER_READY:
977 g_value_set_boolean (value, priv->master_ready);
980 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
986 _device_cleanup (NMActiveConnection *self)
988 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
991 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_state_changed), self);
992 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_master_changed), self);
993 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_metered_changed), self);
996 if (priv->pending_activation_id) {
997 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
998 g_clear_pointer (&priv->pending_activation_id, g_free);
1001 g_clear_object (&priv->device);
1005 dispose (GObject *object)
1007 NMActiveConnection *self = NM_ACTIVE_CONNECTION (object);
1008 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
1010 _LOGD ("disposing");
1013 nm_auth_chain_unref (priv->chain);
1017 g_free (priv->specific_object);
1018 priv->specific_object = NULL;
1020 g_clear_object (&priv->settings_connection);
1021 g_clear_object (&priv->applied_connection);
1023 _device_cleanup (self);
1026 g_signal_handlers_disconnect_by_func (priv->master,
1027 (GCallback) master_state_cb,
1030 g_clear_object (&priv->master);
1031 g_clear_object (&priv->subject);
1033 G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object);
1037 nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
1039 GObjectClass *object_class = G_OBJECT_CLASS (ac_class);
1040 NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (ac_class);
1042 g_type_class_add_private (ac_class, sizeof (NMActiveConnectionPrivate));
1044 exported_object_class->export_path = NM_DBUS_PATH "/ActiveConnection/%u";
1046 /* virtual methods */
1047 object_class->get_property = get_property;
1048 object_class->set_property = set_property;
1049 object_class->constructed = constructed;
1050 object_class->dispose = dispose;
1052 /* D-Bus exported properties */
1053 g_object_class_install_property
1054 (object_class, PROP_CONNECTION,
1055 g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, "", "",
1058 G_PARAM_STATIC_STRINGS));
1060 g_object_class_install_property
1061 (object_class, PROP_ID,
1062 g_param_spec_string (NM_ACTIVE_CONNECTION_ID, "", "",
1065 G_PARAM_STATIC_STRINGS));
1067 g_object_class_install_property
1068 (object_class, PROP_UUID,
1069 g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "", "",
1072 G_PARAM_STATIC_STRINGS));
1074 g_object_class_install_property
1075 (object_class, PROP_TYPE,
1076 g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, "", "",
1079 G_PARAM_STATIC_STRINGS));
1081 g_object_class_install_property
1082 (object_class, PROP_SPECIFIC_OBJECT,
1083 g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, "", "",
1085 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1086 G_PARAM_STATIC_STRINGS));
1088 g_object_class_install_property
1089 (object_class, PROP_DEVICES,
1090 g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "", "",
1093 G_PARAM_STATIC_STRINGS));
1095 g_object_class_install_property
1096 (object_class, PROP_STATE,
1097 g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, "", "",
1098 NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
1099 NM_ACTIVE_CONNECTION_STATE_DEACTIVATING,
1100 NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
1102 G_PARAM_STATIC_STRINGS));
1104 g_object_class_install_property
1105 (object_class, PROP_DEFAULT,
1106 g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "",
1109 G_PARAM_STATIC_STRINGS));
1111 g_object_class_install_property
1112 (object_class, PROP_IP4_CONFIG,
1113 g_param_spec_string (NM_ACTIVE_CONNECTION_IP4_CONFIG, "", "",
1116 G_PARAM_STATIC_STRINGS));
1118 g_object_class_install_property
1119 (object_class, PROP_DHCP4_CONFIG,
1120 g_param_spec_string (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, "", "",
1123 G_PARAM_STATIC_STRINGS));
1125 g_object_class_install_property
1126 (object_class, PROP_DEFAULT6,
1127 g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "", "",
1130 G_PARAM_STATIC_STRINGS));
1132 g_object_class_install_property
1133 (object_class, PROP_IP6_CONFIG,
1134 g_param_spec_string (NM_ACTIVE_CONNECTION_IP6_CONFIG, "", "",
1137 G_PARAM_STATIC_STRINGS));
1139 g_object_class_install_property
1140 (object_class, PROP_DHCP6_CONFIG,
1141 g_param_spec_string (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, "", "",
1144 G_PARAM_STATIC_STRINGS));
1146 g_object_class_install_property
1147 (object_class, PROP_VPN,
1148 g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "", "",
1150 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1151 G_PARAM_STATIC_STRINGS));
1153 g_object_class_install_property
1154 (object_class, PROP_MASTER,
1155 g_param_spec_string (NM_ACTIVE_CONNECTION_MASTER, "", "",
1158 G_PARAM_STATIC_STRINGS));
1160 /* Internal properties */
1161 g_object_class_install_property
1162 (object_class, PROP_INT_SETTINGS_CONNECTION,
1163 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, "", "",
1164 NM_TYPE_SETTINGS_CONNECTION,
1165 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
1166 G_PARAM_STATIC_STRINGS));
1168 g_object_class_install_property
1169 (object_class, PROP_INT_DEVICE,
1170 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_DEVICE, "", "",
1172 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1173 G_PARAM_STATIC_STRINGS));
1175 g_object_class_install_property
1176 (object_class, PROP_INT_SUBJECT,
1177 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SUBJECT, "", "",
1178 NM_TYPE_AUTH_SUBJECT,
1179 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1180 G_PARAM_STATIC_STRINGS));
1182 g_object_class_install_property
1183 (object_class, PROP_INT_MASTER,
1184 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_MASTER, "", "",
1185 NM_TYPE_ACTIVE_CONNECTION,
1187 G_PARAM_STATIC_STRINGS));
1189 g_object_class_install_property
1190 (object_class, PROP_INT_MASTER_READY,
1191 g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_MASTER_READY, "", "",
1192 FALSE, G_PARAM_READABLE |
1193 G_PARAM_STATIC_STRINGS));
1195 signals[DEVICE_CHANGED] =
1196 g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_CHANGED,
1197 G_OBJECT_CLASS_TYPE (object_class),
1199 G_STRUCT_OFFSET (NMActiveConnectionClass, device_changed),
1201 G_TYPE_NONE, 2, NM_TYPE_DEVICE, NM_TYPE_DEVICE);
1203 signals[DEVICE_METERED_CHANGED] =
1204 g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
1205 G_OBJECT_CLASS_TYPE (object_class),
1207 G_STRUCT_OFFSET (NMActiveConnectionClass, device_metered_changed),
1209 G_TYPE_NONE, 1, G_TYPE_UINT);
1211 nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class),
1212 NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON,