perm: add a new L permissions

When a client has the L permission on the node, it can make links
between the node even if the owner of the node can't see the other node.
This commit is contained in:
Wim Taymans 2023-07-26 18:45:15 +02:00
parent 94385068cb
commit 390f6c9cb8
5 changed files with 41 additions and 13 deletions

View file

@ -31,6 +31,7 @@ struct pw_metadata;
#define PW_METADATA_EVENT_PROPERTY 0 #define PW_METADATA_EVENT_PROPERTY 0
#define PW_METADATA_EVENT_NUM 1 #define PW_METADATA_EVENT_NUM 1
/** \ref pw_metadata events */ /** \ref pw_metadata events */
struct pw_metadata_events { struct pw_metadata_events {
#define PW_VERSION_METADATA_EVENTS 0 #define PW_VERSION_METADATA_EVENTS 0

View file

@ -1131,7 +1131,7 @@ static void try_unlink_controls(struct impl *impl, struct pw_impl_port *output,
} }
static int check_owner_permissions(struct pw_context *context, static int check_owner_permissions(struct pw_context *context,
struct pw_impl_node *node, uint32_t id, uint32_t permissions) struct pw_impl_node *node, struct pw_global *other, uint32_t permissions)
{ {
const char *str; const char *str;
struct pw_impl_client *client; struct pw_impl_client *client;
@ -1155,11 +1155,7 @@ static int check_owner_permissions(struct pw_context *context,
/* not the right object, something wrong */ /* not the right object, something wrong */
return -EIO; return -EIO;
if ((global = pw_context_find_global(context, id)) == NULL) perms = pw_global_get_permissions(other, client);
/* current client can't see node id */
return -errno;
perms = pw_global_get_permissions(global, client);
if ((perms & permissions) != permissions) if ((perms & permissions) != permissions)
/* owner client can't see other node */ /* owner client can't see other node */
return -EPERM; return -EPERM;
@ -1174,12 +1170,37 @@ check_permission(struct pw_context *context,
struct pw_properties *properties) struct pw_properties *properties)
{ {
int res; int res;
uint32_t in_perms, out_perms;
struct pw_global *in_global, *out_global;
if ((in_global = input->node->global) == NULL)
return -ENOENT;
if ((out_global = output->node->global) == NULL)
return -ENOENT;
in_perms = out_perms = PW_PERM_R | PW_PERM_L;
if (context->current_client != NULL) {
in_perms = pw_global_get_permissions(in_global, context->current_client);
out_perms = pw_global_get_permissions(out_global, context->current_client);
}
/* current client can't see input node or output node */
if (!PW_PERM_IS_R(in_perms) || !PW_PERM_IS_R(out_perms))
return -ENOENT;
if ((res = check_owner_permissions(context, output->node, if ((res = check_owner_permissions(context, output->node,
input->node->info.id, PW_PERM_R)) < 0) in_global, PW_PERM_R)) < 0) {
return res; /* output node owner can't see input node, check if the current
* client has universal link permissions for the output node */
if (!PW_PERM_IS_L(out_perms))
return res;
}
if ((res = check_owner_permissions(context, input->node, if ((res = check_owner_permissions(context, input->node,
output->node->info.id, PW_PERM_R)) < 0) out_global, PW_PERM_R)) < 0) {
return res; /* input node owner can't see output node, check if the current
* client has universal link permissions for the input node */
if (!PW_PERM_IS_L(in_perms))
return res;
}
return 0; return 0;
} }

View file

@ -29,7 +29,7 @@ extern "C" {
*/ */
#define PW_TYPE_INTERFACE_Node PW_TYPE_INFO_INTERFACE_BASE "Node" #define PW_TYPE_INTERFACE_Node PW_TYPE_INFO_INTERFACE_BASE "Node"
#define PW_NODE_PERM_MASK PW_PERM_RWXM #define PW_NODE_PERM_MASK PW_PERM_RWXML
#define PW_VERSION_NODE 3 #define PW_VERSION_NODE 3
struct pw_node; struct pw_node;

View file

@ -29,15 +29,19 @@ extern "C" {
#define PW_PERM_X 0100 /**< methods can be called on the object. The W flag must be #define PW_PERM_X 0100 /**< methods can be called on the object. The W flag must be
* present in order to call methods that modify the object. */ * present in order to call methods that modify the object. */
#define PW_PERM_M 0010 /**< metadata can be set on object, Since 0.3.9 */ #define PW_PERM_M 0010 /**< metadata can be set on object, Since 0.3.9 */
#define PW_PERM_L 0020 /**< a link can be made between a node that doesn't have
* permission to see the other node, Since 0.3.77 */
#define PW_PERM_RW (PW_PERM_R|PW_PERM_W) #define PW_PERM_RW (PW_PERM_R|PW_PERM_W)
#define PW_PERM_RWX (PW_PERM_RW|PW_PERM_X) #define PW_PERM_RWX (PW_PERM_RW|PW_PERM_X)
#define PW_PERM_RWXM (PW_PERM_RWX|PW_PERM_M) #define PW_PERM_RWXM (PW_PERM_RWX|PW_PERM_M)
#define PW_PERM_RWXML (PW_PERM_RWXM|PW_PERM_L)
#define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R) #define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R)
#define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W) #define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W)
#define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X) #define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X)
#define PW_PERM_IS_M(p) (((p)&PW_PERM_M) == PW_PERM_M) #define PW_PERM_IS_M(p) (((p)&PW_PERM_M) == PW_PERM_M)
#define PW_PERM_IS_L(p) (((p)&PW_PERM_L) == PW_PERM_L)
#define PW_PERM_ALL PW_PERM_RWXM #define PW_PERM_ALL PW_PERM_RWXM
#define PW_PERM_INVALID (uint32_t)(0xffffffff) #define PW_PERM_INVALID (uint32_t)(0xffffffff)
@ -49,12 +53,13 @@ struct pw_permission {
#define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) }) #define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) })
#define PW_PERMISSION_FORMAT "%c%c%c%c" #define PW_PERMISSION_FORMAT "%c%c%c%c%c"
#define PW_PERMISSION_ARGS(permission) \ #define PW_PERMISSION_ARGS(permission) \
(permission) & PW_PERM_R ? 'r' : '-', \ (permission) & PW_PERM_R ? 'r' : '-', \
(permission) & PW_PERM_W ? 'w' : '-', \ (permission) & PW_PERM_W ? 'w' : '-', \
(permission) & PW_PERM_X ? 'x' : '-', \ (permission) & PW_PERM_X ? 'x' : '-', \
(permission) & PW_PERM_M ? 'm' : '-' (permission) & PW_PERM_M ? 'm' : '-', \
(permission) & PW_PERM_L ? 'l' : '-'
/** /**
* \} * \}

View file

@ -1427,6 +1427,7 @@ static void dump_objects(struct data *d)
{ "w", PW_PERM_W }, { "w", PW_PERM_W },
{ "x", PW_PERM_X }, { "x", PW_PERM_X },
{ "m", PW_PERM_M }, { "m", PW_PERM_M },
{ "l", PW_PERM_L },
{ NULL, }, { NULL, },
}; };