summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-12-06 11:48:04 +0100
committerThomas Haller <thaller@redhat.com>2019-12-10 07:53:25 +0100
commit51bc2c02242ead7659c417cfa2336a231ac4ea24 (patch)
treee3dadd386d196b695e46cd7e98c27239ec2d5dcf
parent89d55ad6e167ab89df98d2705605bc17a6ce13aa (diff)
downloadNetworkManager-51bc2c02242ead7659c417cfa2336a231ac4ea24.tar.gz
libnm: track permissions in NMClient as an array of well known permissions
On D-Bus, the permission names are just the PolicyKit action names, like "org.freedesktop.NetworkManager.wifi.scan". But NMClient already ignores all strings that it doesn't know at compile time and only keeps track of well known permission. And neither does the API nm_client_get_permissions_result() allow to expose permissions unknown to libnm. Maybe the API of NMClient should be more generic and allow exposing any permissions announced by NetworkManager. As it is however, it's not necessary to track the permissions in a hash table. An array with fixed indices is sufficient.
-rw-r--r--libnm/nm-client.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 42cba4095d..b10456e274 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -278,7 +278,7 @@ typedef struct {
NMLDBusObject *dbobj_settings;
NMLDBusObject *dbobj_dns_manager;
- GHashTable *permissions;
+ guint8 *permissions;
GCancellable *permissions_cancellable;
char *name_owner;
@@ -3311,27 +3311,35 @@ _dbus_nm_vpn_connection_state_changed_cb (GDBusConnection *connection,
static void
_emit_permissions_changed (NMClient *self,
- GHashTable *permissions,
- gboolean force_unknown)
+ const guint8 *old_permissions,
+ const guint8 *permissions)
{
- GHashTableIter iter;
- gpointer key;
- gpointer value;
+ int i;
- if (!permissions)
- return;
if (self->obj_base.is_disposing)
return;
- g_hash_table_iter_init (&iter, permissions);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (old_permissions == permissions)
+ return;
+
+ for (i = 0; i < (int) G_N_ELEMENTS (nm_auth_permission_sorted); i++) {
+ NMClientPermission perm = nm_auth_permission_sorted[i];
+ NMClientPermissionResult perm_result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
+ NMClientPermissionResult perm_result_old = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
+
+ if (permissions)
+ perm_result = permissions[perm - 1];
+ if (old_permissions)
+ perm_result_old = old_permissions[perm - 1];
+
+ if (perm_result == perm_result_old)
+ continue;
+
g_signal_emit (self,
signals[PERMISSION_CHANGED],
0,
- GPOINTER_TO_UINT (key),
- force_unknown
- ? (guint) NM_CLIENT_PERMISSION_NONE
- : GPOINTER_TO_UINT (value));
+ (guint) perm,
+ (guint) perm_result);
}
}
@@ -3344,10 +3352,11 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe
NMClientPrivate *priv;
gs_unref_variant GVariant *ret = NULL;
nm_auto_free_variant_iter GVariantIter *v_permissions = NULL;
- gs_unref_hashtable GHashTable *old_permissions = NULL;
+ gs_free guint8 *old_permissions = NULL;
gs_free_error GError *error = NULL;
const char *pkey;
const char *pvalue;
+ int i;
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
if ( !ret
@@ -3366,9 +3375,10 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe
NML_NMCLIENT_LOG_T (self, "GetPermissions call finished with success");
- /* get list of old permissions for change notification */
old_permissions = g_steal_pointer (&priv->permissions);
- priv->permissions = g_hash_table_new (nm_direct_hash, NULL);
+ priv->permissions = g_new (guint8, G_N_ELEMENTS (nm_auth_permission_sorted));
+ for (i = 0; i < (int) G_N_ELEMENTS (nm_auth_permission_sorted); i++)
+ priv->permissions[i] = NM_CLIENT_PERMISSION_NONE;
g_variant_get (ret, "(a{ss})", &v_permissions);
while (g_variant_iter_next (v_permissions, "{&s&s}", &pkey, &pvalue)) {
@@ -3380,19 +3390,11 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe
continue;
perm_result = nm_client_permission_result_from_string (pvalue);
-
- g_hash_table_insert (priv->permissions,
- GUINT_TO_POINTER (perm),
- GUINT_TO_POINTER (perm_result));
- if (old_permissions) {
- g_hash_table_remove (old_permissions,
- GUINT_TO_POINTER (perm));
- }
+ priv->permissions[perm - 1] = perm_result;
}
dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context);
- _emit_permissions_changed (self, priv->permissions, FALSE);
- _emit_permissions_changed (self, old_permissions, TRUE);
+ _emit_permissions_changed (self, old_permissions, priv->permissions);
}
static void
@@ -4271,18 +4273,18 @@ NMClientPermissionResult
nm_client_get_permission_result (NMClient *client, NMClientPermission permission)
{
NMClientPrivate *priv;
- gpointer result;
+ NMClientPermissionResult result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
- priv = NM_CLIENT_GET_PRIVATE (client);
- if ( !priv->permissions
- || !g_hash_table_lookup_extended (priv->permissions,
- GUINT_TO_POINTER (permission),
- NULL,
- &result))
- return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
- return GPOINTER_TO_UINT (result);
+ if ( permission > NM_CLIENT_PERMISSION_NONE
+ && permission <= NM_CLIENT_PERMISSION_LAST) {
+ priv = NM_CLIENT_GET_PRIVATE (client);
+ if (priv->permissions)
+ result = priv->permissions[permission - 1];
+ }
+
+ return result;
}
/**
@@ -6553,9 +6555,9 @@ _init_release_all (NMClient *self)
&priv->dbsid_nm_check_permissions);
if (priv->permissions) {
- gs_unref_hashtable GHashTable *old_permissions = g_steal_pointer (&priv->permissions);
+ gs_free guint8 *old_permissions = g_steal_pointer (&priv->permissions);
- _emit_permissions_changed (self, old_permissions, TRUE);
+ _emit_permissions_changed (self, old_permissions, NULL);
}
nm_assert (c_list_is_empty (&priv->obj_changed_lst_head));
@@ -7372,7 +7374,7 @@ dispose (GObject *object)
nm_clear_pointer (&priv->dbus_context, g_main_context_unref);
nm_clear_pointer (&priv->main_context, g_main_context_unref);
- nm_clear_pointer (&priv->permissions, g_hash_table_unref);
+ nm_clear_g_free (&priv->permissions);
g_clear_object (&priv->dbus_connection);