client: remove recursive permissions checks

Don't let permissions of an object influence the child permissions,
this is not so easy to manage and needs some more thought.
The result is now that it's possible to see a reference to a (parent)
id that is not visible, but that's ok.
This commit is contained in:
Wim Taymans 2019-06-28 12:18:10 +02:00
parent 57879cc801
commit 5833b7b2a7
2 changed files with 15 additions and 35 deletions

View file

@ -102,8 +102,7 @@ static uint32_t
client_permission_func(struct pw_global *global, client_permission_func(struct pw_global *global,
struct pw_client *client, void *data) struct pw_client *client, void *data)
{ {
struct pw_permission *p; struct pw_permission *p = find_permission(client, global->id);
p = find_permission(client, global->id);
return p->permissions; return p->permissions;
} }

View file

@ -41,29 +41,13 @@ struct impl {
}; };
/** \endcond */ /** \endcond */
static inline uint32_t get_permissions(struct pw_global *global, struct pw_client *client, bool recurse)
{
uint32_t perms;
if (client->permission_func == NULL)
return PW_PERM_RWX;
perms = client->permission_func(global, client, client->permission_data);
if (recurse) {
while (global->parent != NULL && global != global->parent) {
global = global->parent;
perms &= client->permission_func(global, client, client->permission_data);
}
}
return perms;
}
SPA_EXPORT SPA_EXPORT
uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client) uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_client *client)
{ {
return get_permissions(global, client, true); if (client->permission_func == NULL)
return PW_PERM_RWX;
return client->permission_func(global, client, client->permission_data);
} }
/** Create a new global /** Create a new global
@ -329,29 +313,25 @@ int pw_global_update_permissions(struct pw_global *global, struct pw_client *cli
{ {
struct pw_core *core = global->core; struct pw_core *core = global->core;
struct pw_resource *resource, *t; struct pw_resource *resource, *t;
struct pw_global *g; bool do_hide, do_show;
uint32_t perms;
do_hide = PW_PERM_IS_R(old_permissions) && !PW_PERM_IS_R(new_permissions);
do_show = !PW_PERM_IS_R(old_permissions) && PW_PERM_IS_R(new_permissions);
pw_log_debug("client %p: permissions changed %d %08x -> %08x", client,
global->id, old_permissions, new_permissions);
pw_global_emit_permissions_changed(global, client, old_permissions, new_permissions); pw_global_emit_permissions_changed(global, client, old_permissions, new_permissions);
spa_list_for_each(g, &global->child_list, child_link) {
if (g == global)
continue;
perms = get_permissions(g, client, false);
pw_global_update_permissions(g, client,
perms & old_permissions,
perms & new_permissions);
}
spa_list_for_each(resource, &core->registry_resource_list, link) { spa_list_for_each(resource, &core->registry_resource_list, link) {
if (resource->client != client) if (resource->client != client)
continue; continue;
if (PW_PERM_IS_R(old_permissions) && !PW_PERM_IS_R(new_permissions)) { if (do_hide) {
pw_log_debug("client %p: hide global %d", client, global->id); pw_log_debug("client %p: hide global %d", client, global->id);
pw_registry_resource_global_remove(resource, global->id); pw_registry_resource_global_remove(resource, global->id);
} }
else if (!PW_PERM_IS_R(old_permissions) && PW_PERM_IS_R(new_permissions)) { else if (do_show) {
pw_log_debug("client %p: show global %d", client, global->id); pw_log_debug("client %p: show global %d", client, global->id);
pw_registry_resource_global(resource, pw_registry_resource_global(resource,
global->id, global->id,
@ -363,6 +343,7 @@ int pw_global_update_permissions(struct pw_global *global, struct pw_client *cli
&global->properties->dict : NULL); &global->properties->dict : NULL);
} }
} }
spa_list_for_each_safe(resource, t, &global->resource_list, link) { spa_list_for_each_safe(resource, t, &global->resource_list, link) {
if (resource->client != client) if (resource->client != client)
continue; continue;