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;
62 NMActiveConnection *parent;
67 const char *wifi_shared_permission;
68 NMActiveConnectionAuthResultFunc result_func;
71 } NMActiveConnectionPrivate;
91 PROP_INT_SETTINGS_CONNECTION,
95 PROP_INT_MASTER_READY,
102 DEVICE_METERED_CHANGED,
106 static guint signals[LAST_SIGNAL] = { 0 };
108 static void check_master_ready (NMActiveConnection *self);
109 static void _device_cleanup (NMActiveConnection *self);
111 /****************************************************************/
113 #define _NMLOG_DOMAIN LOGD_DEVICE
114 #define _NMLOG_PREFIX_NAME "active-connection"
115 #define _NMLOG(level, ...) \
119 nm_log ((level), _NMLOG_DOMAIN, \
120 "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
121 _NMLOG_PREFIX_NAME, \
122 self ? nm_sprintf_buf (_sbuf, "[%p]", self) : "" \
123 _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
126 /****************************************************************/
128 NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, NMActiveConnectionState,
129 NM_UTILS_LOOKUP_DEFAULT (NULL),
130 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_UNKNOWN, "unknown"),
131 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATING, "activating"),
132 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATED, "activated"),
133 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, "deactivating"),
134 NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATED, "deactivated"),
136 #define state_to_string(state) NM_UTILS_LOOKUP_STR (_state_to_string, state)
138 /****************************************************************/
140 NMActiveConnectionState
141 nm_active_connection_get_state (NMActiveConnection *self)
143 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->state;
147 nm_active_connection_set_state (NMActiveConnection *self,
148 NMActiveConnectionState new_state)
150 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
151 NMActiveConnectionState old_state;
153 if (priv->state == new_state)
156 /* DEACTIVATED is a terminal state */
157 if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
158 g_return_if_fail (new_state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
160 _LOGD ("set state %s (was %s)",
161 state_to_string (new_state),
162 state_to_string (priv->state));
164 old_state = priv->state;
165 priv->state = new_state;
166 priv->state_set = TRUE;
167 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
169 check_master_ready (self);
171 if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
172 || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
173 nm_settings_connection_update_timestamp (priv->settings_connection,
174 (guint64) time (NULL), TRUE);
178 if ( old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED
179 && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
180 priv->pending_activation_id)
182 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
183 g_clear_pointer (&priv->pending_activation_id, g_free);
187 if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
188 || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
189 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP4_CONFIG);
190 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DHCP4_CONFIG);
191 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_IP6_CONFIG);
192 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DHCP6_CONFIG);
195 if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
196 /* Device is no longer relevant when deactivated. So remove it and
197 * emit property change notification so clients re-read the value,
198 * which will be NULL due to conditions in get_property().
200 _device_cleanup (self);
201 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
206 nm_active_connection_get_settings_connection_id (NMActiveConnection *self)
208 NMSettingsConnection *con;
210 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
212 con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection;
214 ? nm_connection_get_id (NM_CONNECTION (con))
218 NMSettingsConnection *
219 _nm_active_connection_get_settings_connection (NMActiveConnection *self)
221 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
223 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection;
226 NMSettingsConnection *
227 nm_active_connection_get_settings_connection (NMActiveConnection *self)
229 NMSettingsConnection *con;
231 con = _nm_active_connection_get_settings_connection (self);
233 /* Only call this function on an active-connection that is already
234 * fully set-up (i.e. that has a settings-connection). Other uses
236 g_return_val_if_fail (con, NULL);
241 nm_active_connection_get_applied_connection (NMActiveConnection *self)
245 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
247 con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection;
249 /* Only call this function on an active-connection that is already
250 * fully set-up (i.e. that has a settings-connection). Other uses
252 g_return_val_if_fail (con, NULL);
257 nm_active_connection_set_settings_connection (NMActiveConnection *self,
258 NMSettingsConnection *connection)
260 NMActiveConnectionPrivate *priv;
262 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
264 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
266 g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
267 g_return_if_fail (!priv->settings_connection);
268 g_return_if_fail (!priv->applied_connection);
270 /* Can't change connection after the ActiveConnection is exported over D-Bus.
272 * Later, we want to change the settings-connection of an activated connection.
273 * When doing that, this changes the assumption that the settings-connection
274 * never changes (once it's set). That has effects for NMVpnConnection and
275 * NMActivationRequest.
276 * For example, we'd have to cancel all pending seret requests. */
277 g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
279 priv->settings_connection = g_object_ref (connection);
280 priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
281 nm_connection_clear_secrets (priv->applied_connection);
285 nm_active_connection_has_unmodified_applied_connection (NMActiveConnection *self, NMSettingCompareFlags compare_flags)
287 NMActiveConnectionPrivate *priv;
289 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
291 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
293 g_return_val_if_fail (priv->settings_connection, FALSE);
295 return nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection,
296 priv->applied_connection,
300 /*******************************************************************/
303 nm_active_connection_clear_secrets (NMActiveConnection *self)
305 NMActiveConnectionPrivate *priv;
307 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
309 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
311 if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection,
312 priv->applied_connection,
313 NM_SETTING_COMPARE_FLAG_NONE))
314 nm_connection_clear_secrets ((NMConnection *) priv->settings_connection);
315 nm_connection_clear_secrets (priv->applied_connection);
318 /*******************************************************************/
321 nm_active_connection_get_specific_object (NMActiveConnection *self)
323 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->specific_object;
327 nm_active_connection_set_specific_object (NMActiveConnection *self,
328 const char *specific_object)
330 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
332 /* Nothing that calls this function should be using paths from D-Bus,
333 * where NM uses "/" to mean NULL.
335 g_assert (g_strcmp0 (specific_object, "/") != 0);
337 if (g_strcmp0 (priv->specific_object, specific_object) == 0)
340 g_free (priv->specific_object);
341 priv->specific_object = g_strdup (specific_object);
342 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT);
346 nm_active_connection_set_default (NMActiveConnection *self, gboolean is_default)
348 NMActiveConnectionPrivate *priv;
350 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
352 is_default = !!is_default;
354 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
355 if (priv->is_default == is_default)
358 priv->is_default = is_default;
359 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
363 nm_active_connection_get_default (NMActiveConnection *self)
365 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
367 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default;
371 nm_active_connection_set_default6 (NMActiveConnection *self, gboolean is_default6)
373 NMActiveConnectionPrivate *priv;
375 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
377 is_default6 = !!is_default6;
379 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
380 if (priv->is_default6 == is_default6)
383 priv->is_default6 = is_default6;
384 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
388 nm_active_connection_get_default6 (NMActiveConnection *self)
390 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
392 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->is_default6;
396 nm_active_connection_get_subject (NMActiveConnection *self)
398 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
400 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject;
404 nm_active_connection_get_user_requested (NMActiveConnection *self)
406 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
408 return nm_auth_subject_is_unix_process (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject);
412 nm_active_connection_get_device (NMActiveConnection *self)
414 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
416 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->device;
420 device_state_changed (NMDevice *device,
421 NMDeviceState new_state,
422 NMDeviceState old_state,
423 NMDeviceStateReason reason,
426 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
427 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
429 /* When already deactivated or before activation, device state changes are useless */
430 if (priv->state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
432 if (old_state < NM_DEVICE_STATE_DISCONNECTED)
435 /* Let subclasses handle the state change */
436 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->device_state_changed)
437 NM_ACTIVE_CONNECTION_GET_CLASS (self)->device_state_changed (self, device, new_state, old_state);
441 device_master_changed (GObject *object,
445 NMDevice *device = NM_DEVICE (object);
446 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
447 NMActiveConnection *master;
448 NMActiveConnectionState master_state;
450 if (NM_ACTIVE_CONNECTION (nm_device_get_act_request (device)) != self)
452 if (!nm_device_get_master (device))
454 if (!nm_active_connection_get_master (self))
456 g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_master_changed), self);
458 master = nm_active_connection_get_master (self);
459 master_state = nm_active_connection_get_state (master);
460 if (master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
461 /* Master failed before attaching the slave */
462 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
463 NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
468 device_metered_changed (GObject *object,
472 NMActiveConnection *self = (NMActiveConnection *) user_data;
473 NMDevice *device = NM_DEVICE (object);
475 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
476 g_signal_emit (self, signals[DEVICE_METERED_CHANGED], 0, nm_device_get_metered (device));
480 nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
482 NMActiveConnectionPrivate *priv;
483 gs_unref_object NMDevice *old_device = NULL;
485 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
486 g_return_val_if_fail (!device || NM_IS_DEVICE (device), FALSE);
488 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
489 if (device == priv->device)
492 _LOGD ("set device %s%s%s [%p]",
493 NM_PRINT_FMT_QUOTED (device && nm_device_get_iface (device),
495 nm_device_get_iface (device),
497 device ? "(unknown)" : "(null)"),
500 old_device = priv->device ? g_object_ref (priv->device) : NULL;
501 _device_cleanup (self);
504 /* Device obviously can't be its own master */
505 g_return_val_if_fail (!priv->master || device != nm_active_connection_get_device (priv->master), FALSE);
507 priv->device = g_object_ref (device);
509 g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
510 G_CALLBACK (device_state_changed), self);
511 g_signal_connect (device, "notify::master",
512 G_CALLBACK (device_master_changed), self);
513 g_signal_connect (device, "notify::" NM_DEVICE_METERED,
514 G_CALLBACK (device_metered_changed), self);
516 if (!priv->assumed) {
517 priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self);
518 nm_device_add_pending_action (device, priv->pending_activation_id, TRUE);
521 /* The ActiveConnection's device can only be cleared after the
522 * connection is activated.
524 g_warn_if_fail (priv->state > NM_ACTIVE_CONNECTION_STATE_UNKNOWN);
527 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_DEVICE);
529 g_signal_emit (self, signals[DEVICE_CHANGED], 0, priv->device, old_device);
531 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
537 nm_active_connection_get_master (NMActiveConnection *self)
539 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
541 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master;
545 * nm_active_connection_get_master_ready:
546 * @self: the #NMActiveConnection
548 * Returns: %TRUE if the connection has a master connection, and that
549 * master connection is ready to accept slaves. Otherwise %FALSE.
552 nm_active_connection_get_master_ready (NMActiveConnection *self)
554 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
556 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master_ready;
560 check_master_ready (NMActiveConnection *self)
562 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
563 gboolean signalling = FALSE;
565 /* ActiveConnetions don't enter the ACTIVATING state until they have a
566 * NMDevice in PREPARE or higher states, so the master active connection's
567 * device will be ready to accept slaves when the master is in ACTIVATING
570 if ( !priv->master_ready
572 && priv->state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING
573 && NM_IN_SET (nm_active_connection_get_state (priv->master),
574 NM_ACTIVE_CONNECTION_STATE_ACTIVATING,
575 NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
579 _LOGD ("check-master-ready: %s (state %s, %s)",
582 : (priv->master_ready ? "already signalled" : "not signalling"),
583 state_to_string (priv->state),
585 ? nm_sprintf_bufa (128, "master %p is in state %s",
587 state_to_string (nm_active_connection_get_state (priv->master)))
591 priv->master_ready = TRUE;
592 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_MASTER_READY);
594 /* Also notify clients to recheck the exported 'master' property to
595 * ensure that if the master connection was created without a device
596 * that we notify clients when the master device is known.
598 g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_MASTER);
603 master_state_cb (NMActiveConnection *master,
607 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
608 NMActiveConnectionState master_state = nm_active_connection_get_state (master);
609 NMDevice *master_device = nm_active_connection_get_device (master);
611 check_master_ready (self);
613 if ( master_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATING
614 && (!master_device || !nm_device_is_real (master_device))) {
615 /* Master failed without ever creating or realizing its device */
616 if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
617 NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
622 * nm_active_connection_set_master:
623 * @self: the #NMActiveConnection
624 * @master: if the activation depends on another device (ie, bond or bridge
625 * master to which this device will be enslaved) pass the #NMActiveConnection
626 * that this activation request is a child of
628 * Sets the master active connection of @self.
631 nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *master)
633 NMActiveConnectionPrivate *priv;
635 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
636 g_return_if_fail (NM_IS_ACTIVE_CONNECTION (master));
638 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
640 /* Master is write-once, and must be set before exporting the object */
641 g_return_if_fail (priv->master == NULL);
642 g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
644 /* Note, the master ActiveConnection may not yet have a device */
645 g_return_if_fail (priv->device != nm_active_connection_get_device (master));
648 _LOGD ("set master %p, %s, state %s",
650 nm_active_connection_get_settings_connection_id (master),
651 state_to_string (nm_active_connection_get_state (master)));
653 priv->master = g_object_ref (master);
654 g_signal_connect (priv->master,
655 "notify::" NM_ACTIVE_CONNECTION_STATE,
656 (GCallback) master_state_cb,
659 check_master_ready (self);
663 nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed)
665 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
667 g_return_if_fail (priv->assumed == FALSE);
668 priv->assumed = assumed;
670 if (priv->pending_activation_id) {
671 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
672 g_clear_pointer (&priv->pending_activation_id, g_free);
677 nm_active_connection_get_assumed (NMActiveConnection *self)
679 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->assumed;
682 /****************************************************************/
684 static void unwatch_parent (NMActiveConnection *self);
687 parent_destroyed (gpointer user_data, GObject *parent)
689 NMActiveConnection *self = user_data;
691 unwatch_parent (self);
692 g_signal_emit (self, signals[PARENT_ACTIVE], 0, NULL);
696 parent_state_cb (NMActiveConnection *parent_ac,
700 NMActiveConnection *self = user_data;
701 NMActiveConnectionState parent_state = nm_active_connection_get_state (parent_ac);
703 if (parent_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
706 unwatch_parent (self);
707 g_signal_emit (self, signals[PARENT_ACTIVE], 0, parent_ac);
711 unwatch_parent (NMActiveConnection *self)
713 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
715 g_signal_handlers_disconnect_by_func (priv->parent,
716 (GCallback) parent_state_cb,
718 g_object_weak_unref ((GObject *) priv->parent, parent_destroyed, self);
723 * nm_active_connection_set_parent:
724 * @self: the #NMActiveConnection
725 * @parent: The #NMActiveConnection that must be active before the manager
726 * can proceed progressing the device to disconnected state for us.
728 * Sets the parent connection of @self. A "parent-active" signal will be
729 * emitted when the parent connection becomes active.
732 nm_active_connection_set_parent (NMActiveConnection *self, NMActiveConnection *parent)
734 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
736 g_return_if_fail (priv->parent == NULL);
737 priv->parent = parent;
738 g_signal_connect (priv->parent,
739 "notify::" NM_ACTIVE_CONNECTION_STATE,
740 (GCallback) parent_state_cb,
742 g_object_weak_ref ((GObject *) priv->parent, parent_destroyed, self);
745 /****************************************************************/
748 auth_done (NMAuthChain *chain,
750 GDBusMethodInvocation *unused,
753 NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
754 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
755 NMAuthCallResult result;
757 g_assert (priv->chain == chain);
758 g_assert (priv->result_func != NULL);
760 /* Must stay alive over the callback */
764 priv->result_func (self, FALSE, error->message, priv->user_data1, priv->user_data2);
768 /* Caller has had a chance to obtain authorization, so we only need to
769 * check for 'yes' here.
771 result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
772 if (result != NM_AUTH_CALL_RESULT_YES) {
773 priv->result_func (self,
775 "Not authorized to control networking.",
781 if (priv->wifi_shared_permission) {
782 result = nm_auth_chain_get_result (chain, priv->wifi_shared_permission);
783 if (result != NM_AUTH_CALL_RESULT_YES) {
784 priv->result_func (self,
786 "Not authorized to share connections via wifi.",
793 /* Otherwise authorized and available to activate */
794 priv->result_func (self, TRUE, NULL, priv->user_data1, priv->user_data2);
797 nm_auth_chain_unref (chain);
799 priv->result_func = NULL;
800 priv->user_data1 = NULL;
801 priv->user_data2 = NULL;
803 g_object_unref (self);
807 * nm_active_connection_authorize:
808 * @self: the #NMActiveConnection
809 * @initial_connection: (allow-none): for add-and-activate, there
810 * is no @settings_connection available when creating the active connection.
811 * Instead pass an alternative connection.
812 * @result_func: function to be called on success or error
813 * @user_data1: pointer passed to @result_func
814 * @user_data2: additional pointer passed to @result_func
816 * Checks whether the subject that initiated the active connection (read from
817 * the #NMActiveConnection::subject property) is authorized to complete this
818 * activation request.
821 nm_active_connection_authorize (NMActiveConnection *self,
822 NMConnection *initial_connection,
823 NMActiveConnectionAuthResultFunc result_func,
827 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
828 const char *wifi_permission = NULL;
831 g_return_if_fail (result_func != NULL);
832 g_return_if_fail (priv->chain == NULL);
834 if (initial_connection) {
835 g_return_if_fail (NM_IS_CONNECTION (initial_connection));
836 g_return_if_fail (!priv->settings_connection);
837 g_return_if_fail (!priv->applied_connection);
838 con = initial_connection;
840 g_return_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection));
841 g_return_if_fail (NM_IS_CONNECTION (priv->applied_connection));
842 con = priv->applied_connection;
845 priv->chain = nm_auth_chain_new_subject (priv->subject, NULL, auth_done, self);
846 g_assert (priv->chain);
848 /* Check that the subject is allowed to use networking at all */
849 nm_auth_chain_add_call (priv->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
851 /* Shared wifi connections require special permissions too */
852 wifi_permission = nm_utils_get_shared_wifi_permission (con);
853 if (wifi_permission) {
854 priv->wifi_shared_permission = wifi_permission;
855 nm_auth_chain_add_call (priv->chain, wifi_permission, TRUE);
858 /* Wait for authorization */
859 priv->result_func = result_func;
860 priv->user_data1 = user_data1;
861 priv->user_data2 = user_data2;
864 /****************************************************************/
867 _version_id_new (void)
869 static guint64 id = 0;
875 nm_active_connection_version_id_get (NMActiveConnection *self)
877 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
879 return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->version_id;
883 nm_active_connection_version_id_bump (NMActiveConnection *self)
885 NMActiveConnectionPrivate *priv;
887 g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
889 priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
890 priv->version_id = _version_id_new ();
891 _LOGT ("new version-id %llu", (long long unsigned) priv->version_id);
892 return priv->version_id;
895 /****************************************************************/
898 nm_active_connection_init (NMActiveConnection *self)
900 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
904 priv->version_id = _version_id_new ();
908 constructed (GObject *object)
910 NMActiveConnection *self = (NMActiveConnection *) object;
911 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
913 G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
915 _LOGD ("constructed (%s, version-id %llu)", G_OBJECT_TYPE_NAME (self), (long long unsigned) priv->version_id);
917 g_return_if_fail (priv->subject);
921 set_property (GObject *object, guint prop_id,
922 const GValue *value, GParamSpec *pspec)
924 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
926 NMSettingsConnection *con;
929 case PROP_INT_SETTINGS_CONNECTION:
931 con = g_value_get_object (value);
933 priv->settings_connection = g_object_ref (con);
934 priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (con));
935 nm_connection_clear_secrets (priv->applied_connection);
938 case PROP_INT_DEVICE:
940 nm_active_connection_set_device (NM_ACTIVE_CONNECTION (object), g_value_get_object (value));
942 case PROP_INT_SUBJECT:
943 priv->subject = g_value_dup_object (value);
945 case PROP_INT_MASTER:
946 nm_active_connection_set_master (NM_ACTIVE_CONNECTION (object), g_value_get_object (value));
948 case PROP_SPECIFIC_OBJECT:
949 tmp = g_value_get_string (value);
950 /* NM uses "/" to mean NULL */
951 if (g_strcmp0 (tmp, "/") != 0)
952 priv->specific_object = g_strdup (tmp);
955 priv->is_default = !!g_value_get_boolean (value);
958 priv->is_default6 = !!g_value_get_boolean (value);
961 priv->vpn = g_value_get_boolean (value);
966 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
972 get_property (GObject *object, guint prop_id,
973 GValue *value, GParamSpec *pspec)
975 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
977 NMDevice *master_device = NULL;
980 case PROP_CONNECTION:
981 g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->settings_connection)));
984 g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection)));
987 g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection)));
990 g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection)));
992 case PROP_SPECIFIC_OBJECT:
993 g_value_set_string (value, priv->specific_object ? priv->specific_object : "/");
996 devices = g_ptr_array_sized_new (2);
997 if (priv->device && priv->state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
998 g_ptr_array_add (devices, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (priv->device))));
999 g_ptr_array_add (devices, NULL);
1000 g_value_take_boxed (value, (char **) g_ptr_array_free (devices, FALSE));
1003 if (priv->state_set)
1004 g_value_set_uint (value, priv->state);
1006 /* When the AC has just been created, its externally-visible state should
1007 * be "ACTIVATING", even though internally it is "UNKNOWN".
1009 g_value_set_uint (value, NM_ACTIVE_CONNECTION_STATE_ACTIVATING);
1013 g_value_set_boolean (value, priv->is_default);
1015 case PROP_IP4_CONFIG:
1016 /* The IP and DHCP config properties may be overridden by a subclass */
1017 g_value_set_string (value, "/");
1019 case PROP_DHCP4_CONFIG:
1020 g_value_set_string (value, "/");
1023 g_value_set_boolean (value, priv->is_default6);
1025 case PROP_IP6_CONFIG:
1026 g_value_set_string (value, "/");
1028 case PROP_DHCP6_CONFIG:
1029 g_value_set_string (value, "/");
1032 g_value_set_boolean (value, priv->vpn);
1036 master_device = nm_active_connection_get_device (priv->master);
1037 nm_utils_g_value_set_object_path (value, master_device);
1039 case PROP_INT_SUBJECT:
1040 g_value_set_object (value, priv->subject);
1042 case PROP_INT_MASTER_READY:
1043 g_value_set_boolean (value, priv->master_ready);
1046 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1052 _device_cleanup (NMActiveConnection *self)
1054 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
1057 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_state_changed), self);
1058 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_master_changed), self);
1059 g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_metered_changed), self);
1062 if (priv->pending_activation_id) {
1063 nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
1064 g_clear_pointer (&priv->pending_activation_id, g_free);
1067 g_clear_object (&priv->device);
1071 dispose (GObject *object)
1073 NMActiveConnection *self = NM_ACTIVE_CONNECTION (object);
1074 NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
1076 _LOGD ("disposing");
1079 nm_auth_chain_unref (priv->chain);
1083 g_free (priv->specific_object);
1084 priv->specific_object = NULL;
1086 g_clear_object (&priv->settings_connection);
1087 g_clear_object (&priv->applied_connection);
1089 _device_cleanup (self);
1092 g_signal_handlers_disconnect_by_func (priv->master,
1093 (GCallback) master_state_cb,
1096 g_clear_object (&priv->master);
1099 unwatch_parent (self);
1101 g_clear_object (&priv->subject);
1103 G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object);
1107 nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
1109 GObjectClass *object_class = G_OBJECT_CLASS (ac_class);
1110 NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (ac_class);
1112 g_type_class_add_private (ac_class, sizeof (NMActiveConnectionPrivate));
1114 exported_object_class->export_path = NM_DBUS_PATH "/ActiveConnection/%u";
1116 /* virtual methods */
1117 object_class->get_property = get_property;
1118 object_class->set_property = set_property;
1119 object_class->constructed = constructed;
1120 object_class->dispose = dispose;
1122 /* D-Bus exported properties */
1123 g_object_class_install_property
1124 (object_class, PROP_CONNECTION,
1125 g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, "", "",
1128 G_PARAM_STATIC_STRINGS));
1130 g_object_class_install_property
1131 (object_class, PROP_ID,
1132 g_param_spec_string (NM_ACTIVE_CONNECTION_ID, "", "",
1135 G_PARAM_STATIC_STRINGS));
1137 g_object_class_install_property
1138 (object_class, PROP_UUID,
1139 g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "", "",
1142 G_PARAM_STATIC_STRINGS));
1144 g_object_class_install_property
1145 (object_class, PROP_TYPE,
1146 g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, "", "",
1149 G_PARAM_STATIC_STRINGS));
1151 g_object_class_install_property
1152 (object_class, PROP_SPECIFIC_OBJECT,
1153 g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, "", "",
1155 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1156 G_PARAM_STATIC_STRINGS));
1158 g_object_class_install_property
1159 (object_class, PROP_DEVICES,
1160 g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "", "",
1163 G_PARAM_STATIC_STRINGS));
1165 g_object_class_install_property
1166 (object_class, PROP_STATE,
1167 g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, "", "",
1168 NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
1169 NM_ACTIVE_CONNECTION_STATE_DEACTIVATING,
1170 NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
1172 G_PARAM_STATIC_STRINGS));
1174 g_object_class_install_property
1175 (object_class, PROP_DEFAULT,
1176 g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "",
1179 G_PARAM_STATIC_STRINGS));
1181 g_object_class_install_property
1182 (object_class, PROP_IP4_CONFIG,
1183 g_param_spec_string (NM_ACTIVE_CONNECTION_IP4_CONFIG, "", "",
1186 G_PARAM_STATIC_STRINGS));
1188 g_object_class_install_property
1189 (object_class, PROP_DHCP4_CONFIG,
1190 g_param_spec_string (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, "", "",
1193 G_PARAM_STATIC_STRINGS));
1195 g_object_class_install_property
1196 (object_class, PROP_DEFAULT6,
1197 g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "", "",
1200 G_PARAM_STATIC_STRINGS));
1202 g_object_class_install_property
1203 (object_class, PROP_IP6_CONFIG,
1204 g_param_spec_string (NM_ACTIVE_CONNECTION_IP6_CONFIG, "", "",
1207 G_PARAM_STATIC_STRINGS));
1209 g_object_class_install_property
1210 (object_class, PROP_DHCP6_CONFIG,
1211 g_param_spec_string (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, "", "",
1214 G_PARAM_STATIC_STRINGS));
1216 g_object_class_install_property
1217 (object_class, PROP_VPN,
1218 g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "", "",
1220 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1221 G_PARAM_STATIC_STRINGS));
1223 g_object_class_install_property
1224 (object_class, PROP_MASTER,
1225 g_param_spec_string (NM_ACTIVE_CONNECTION_MASTER, "", "",
1228 G_PARAM_STATIC_STRINGS));
1230 /* Internal properties */
1231 g_object_class_install_property
1232 (object_class, PROP_INT_SETTINGS_CONNECTION,
1233 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, "", "",
1234 NM_TYPE_SETTINGS_CONNECTION,
1235 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
1236 G_PARAM_STATIC_STRINGS));
1238 g_object_class_install_property
1239 (object_class, PROP_INT_DEVICE,
1240 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_DEVICE, "", "",
1242 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1243 G_PARAM_STATIC_STRINGS));
1245 g_object_class_install_property
1246 (object_class, PROP_INT_SUBJECT,
1247 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SUBJECT, "", "",
1248 NM_TYPE_AUTH_SUBJECT,
1249 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
1250 G_PARAM_STATIC_STRINGS));
1252 g_object_class_install_property
1253 (object_class, PROP_INT_MASTER,
1254 g_param_spec_object (NM_ACTIVE_CONNECTION_INT_MASTER, "", "",
1255 NM_TYPE_ACTIVE_CONNECTION,
1257 G_PARAM_STATIC_STRINGS));
1259 g_object_class_install_property
1260 (object_class, PROP_INT_MASTER_READY,
1261 g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_MASTER_READY, "", "",
1262 FALSE, G_PARAM_READABLE |
1263 G_PARAM_STATIC_STRINGS));
1265 signals[DEVICE_CHANGED] =
1266 g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_CHANGED,
1267 G_OBJECT_CLASS_TYPE (object_class),
1269 G_STRUCT_OFFSET (NMActiveConnectionClass, device_changed),
1271 G_TYPE_NONE, 2, NM_TYPE_DEVICE, NM_TYPE_DEVICE);
1273 signals[DEVICE_METERED_CHANGED] =
1274 g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
1275 G_OBJECT_CLASS_TYPE (object_class),
1277 G_STRUCT_OFFSET (NMActiveConnectionClass, device_metered_changed),
1279 G_TYPE_NONE, 1, G_TYPE_UINT);
1281 signals[PARENT_ACTIVE] =
1282 g_signal_new (NM_ACTIVE_CONNECTION_PARENT_ACTIVE,
1283 G_OBJECT_CLASS_TYPE (object_class),
1285 G_STRUCT_OFFSET (NMActiveConnectionClass, parent_active),
1287 G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
1289 nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class),
1290 NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON,