diff options
Diffstat (limited to 'src/nm-manager.c')
| -rw-r--r-- | src/nm-manager.c | 158 |
1 files changed, 119 insertions, 39 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c index 9c82d145..9037e649 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -222,6 +222,7 @@ typedef struct { guint dbus_connection_changed_id; NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; + NMSessionMonitor *session_monitor; /* List of NMDeviceFactoryFunc pointers sorted in priority order */ GSList *factories; @@ -583,6 +584,7 @@ checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data) else if ( connectivity == NM_CONNECTIVITY_PORTAL || connectivity == NM_CONNECTIVITY_LIMITED) set_state (manager, NM_STATE_CONNECTED_SITE); + g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY); } g_object_unref (manager); @@ -940,16 +942,18 @@ static void pending_activation_check_authorized (PendingActivation *pending, NMDBusManager *dbus_mgr) { + NMManagerPrivate *priv; char *error_desc = NULL; gulong sender_uid = G_MAXULONG; GError *error; const char *wifi_permission = NULL; NMConnection *connection; - NMSettings *settings; g_return_if_fail (pending != NULL); g_return_if_fail (dbus_mgr != NULL); + priv = NM_MANAGER_GET_PRIVATE (pending->manager); + if (!nm_auth_get_caller_uid (pending->context, dbus_mgr, &sender_uid, @@ -973,10 +977,8 @@ pending_activation_check_authorized (PendingActivation *pending, * or an existing connection (for Activate). */ connection = pending->connection; - if (!connection) { - settings = NM_MANAGER_GET_PRIVATE (pending->manager)->settings; - connection = (NMConnection *) nm_settings_get_connection_by_path (settings, pending->connection_path); - } + if (!connection) + connection = (NMConnection *) nm_settings_get_connection_by_path (priv->settings, pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -987,6 +989,20 @@ pending_activation_check_authorized (PendingActivation *pending, return; } + /* Ensure the subject has permissions for this connection */ + if (!nm_auth_uid_in_acl (connection, + priv->session_monitor, + sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + error_desc); + pending->callback (pending, error); + g_error_free (error); + g_free (error_desc); + return; + } + /* First check if the user is allowed to use networking at all, giving * the user a chance to authenticate to gain the permission. */ @@ -1304,8 +1320,8 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) iface = get_virtual_iface_name (self, connection, &parent); if (!iface) { - nm_log_warn (LOGD_DEVICE, "(%s) failed to determine virtual interface name", - nm_connection_get_id (connection)); + nm_log_dbg (LOGD_DEVICE, "(%s) failed to determine virtual interface name", + nm_connection_get_id (connection)); return NULL; } @@ -1833,6 +1849,7 @@ device_auth_done_cb (NMAuthChain *chain, static void device_auth_request_cb (NMDevice *device, DBusGMethodInvocation *context, + NMConnection *connection, const char *permission, gboolean allow_interaction, NMDeviceAuthRequestFunc callback, @@ -1856,6 +1873,20 @@ device_auth_request_cb (NMDevice *device, return; } + /* Ensure the subject has permissions for this connection */ + if (!nm_auth_uid_in_acl (connection, + priv->session_monitor, + sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + error_desc); + callback (device, context, error, user_data); + g_error_free (error); + g_free (error_desc); + return; + } + /* Yay for root */ if (0 == sender_uid) callback (device, context, NULL, user_data); @@ -2007,9 +2038,7 @@ add_device (NMManager *self, NMDevice *device) nm_device_get_iface (device)); ac = internal_activate_device (self, device, existing, NULL, FALSE, 0, NULL, TRUE, NULL, &error); - if (ac) - active_connection_add (self, ac); - else { + if (!ac) { nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s", nm_connection_get_path (existing), error ? error->code : -1, @@ -2518,6 +2547,7 @@ internal_activate_device (NMManager *manager, device, master_device); g_assert (req); + active_connection_add (manager, NM_ACTIVE_CONNECTION (req)); nm_device_activate (device, req); return NM_ACTIVE_CONNECTION (req); @@ -2795,7 +2825,7 @@ activate_vpn_connection (NMManager *self, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMActiveConnection *parent = NULL; + NMActiveConnection *parent = NULL, *ac; NMDevice *device = NULL; GSList *iter; @@ -2831,13 +2861,16 @@ activate_vpn_connection (NMManager *self, return NULL; } - return nm_vpn_manager_activate_connection (priv->vpn_manager, - connection, - device, - nm_active_connection_get_path (parent), - TRUE, - sender_uid, - error); + ac = nm_vpn_manager_activate_connection (priv->vpn_manager, + connection, + device, + nm_active_connection_get_path (parent), + TRUE, + sender_uid, + error); + if (ac) + active_connection_add (self, ac); + return ac; } NMActiveConnection * @@ -2856,8 +2889,10 @@ nm_manager_activate_connection (NMManager *manager, char *iface; NMDevice *master_device = NULL; NMConnection *master_connection = NULL; - NMActiveConnection *master_ac = NULL, *ac = NULL; + NMConnection *existing_connection = NULL; + NMActiveConnection *master_ac = NULL; gboolean matched; + char *error_desc = NULL; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); @@ -2879,13 +2914,24 @@ nm_manager_activate_connection (NMManager *manager, dbus_error_free (&dbus_error); return NULL; } + + /* Ensure the subject has permissions for this connection */ + if (!nm_auth_uid_in_acl (connection, + priv->session_monitor, + sender_uid, + &error_desc)) { + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + return NULL; + } } /* VPN ? */ - if (nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) { - ac = activate_vpn_connection (manager, connection, specific_object, sender_uid, error); - goto activated; - } + if (nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) + return activate_vpn_connection (manager, connection, specific_object, sender_uid, error); /* Device-based connection */ if (device_path) { @@ -2975,6 +3021,28 @@ nm_manager_activate_connection (NMManager *manager, return NULL; } + if (dbus_sender) { + /* If the device is active and its connection is not visible to the + * user that's requesting this new activation, fail, since other users + * should not be allowed to implicitly deactivate private connections + * by activating a connection of their own. + */ + existing_connection = nm_device_get_connection (device); + if (existing_connection && + !nm_auth_uid_in_acl (existing_connection, + priv->session_monitor, + sender_uid, + &error_desc)) { + g_set_error (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Private connection already active on the device: %s", + error_desc); + g_free (error_desc); + return FALSE; + } + } + /* Try to find the master connection/device if the connection has a dependency */ if (!find_master (manager, connection, device, &master_connection, &master_device)) { g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, @@ -3022,22 +3090,16 @@ nm_manager_activate_connection (NMManager *manager, nm_active_connection_get_path (master_ac)); } - ac = internal_activate_device (manager, - device, - connection, - specific_object, - dbus_sender ? TRUE : FALSE, - dbus_sender ? sender_uid : 0, - dbus_sender, - FALSE, - master_ac, - error); - -activated: - if (ac) - active_connection_add (manager, ac); - - return ac; + return internal_activate_device (manager, + device, + connection, + specific_object, + dbus_sender ? TRUE : FALSE, + dbus_sender ? sender_uid : 0, + dbus_sender, + FALSE, + master_ac, + error); } /* @@ -3329,6 +3391,20 @@ impl_manager_deactivate_connection (NMManager *self, return; } + /* Ensure the subject has permissions for this connection */ + if (!nm_auth_uid_in_acl (connection, + priv->session_monitor, + sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + error_desc); + dbus_g_method_return_error (context, error); + g_error_free (error); + g_free (error_desc); + return; + } + /* Yay for root */ if (0 == sender_uid) { if (!nm_manager_deactivate_connection (self, @@ -3997,6 +4073,7 @@ connectivity_changed (NMConnectivity *connectivity, connectivity_states[state]); nm_manager_update_state (self); + g_object_notify (G_OBJECT (self), NM_MANAGER_CONNECTIVITY); } static void @@ -4396,6 +4473,8 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (bluez_manager_bdaddr_removed_cb), singleton); + priv->session_monitor = nm_session_monitor_get (); + /* Force kernel WiFi rfkill state to follow NM saved wifi state in case * the BIOS doesn't save rfkill state, and to be consistent with user * changes to the WirelessEnabled property which toggles kernel rfkill. @@ -4465,6 +4544,7 @@ dispose (GObject *object) g_object_unref (priv->settings); g_object_unref (priv->vpn_manager); + g_object_unref (priv->session_monitor); if (priv->modem_added_id) { g_source_remove (priv->modem_added_id); |