Skip to content
Snippets Groups Projects
Commit 390e80fa authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Allow access to a system view if user has READ permissions to source space

parent 4c159681
No related branches found
No related tags found
No related merge requests found
......@@ -35,6 +35,7 @@
struct sysview_iterator {
struct iterator base;
struct iterator *source;
struct space *space;
};
static inline struct sysview_iterator *
......@@ -63,7 +64,7 @@ sysview_iterator_next(struct iterator *iterator)
class SysviewIndex *index = (class SysviewIndex *) iterator->index;
struct tuple *tuple;
while ((tuple = it->source->next(it->source)) != NULL) {
if (index->predicate(tuple))
if (index->predicate(it->space, tuple))
return tuple;
}
return NULL;
......@@ -121,6 +122,7 @@ SysviewIndex::initIterator(struct iterator *iterator,
pk->initIterator(it->source, type, key, part_count);
iterator->index = (Index *) this;
iterator->next = sysview_iterator_next;
it->space = source;
}
struct tuple *
......@@ -132,7 +134,7 @@ SysviewIndex::findByKey(const char *key, uint32_t part_count) const
tnt_raise(ClientError, ER_MORE_THAN_ONE_TUPLE);
primary_key_validate(pk->key_def, key, part_count);
struct tuple *tuple = pk->findByKey(key, part_count);
if (tuple == NULL || !predicate(tuple))
if (tuple == NULL || !predicate(source, tuple))
return NULL;
return tuple;
}
......@@ -148,11 +150,16 @@ SysviewIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
}
static bool
vspace_predicate(struct tuple *tuple)
vspace_predicate(struct space *source, struct tuple *tuple)
{
struct credentials *cr = current_user();
if (PRIV_R & cr->universal_access)
return true; /* read access to unverse */
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
uint32_t space_id = tuple_field_u32(tuple, 0);
struct space *space = space_cache_find(space_id);
struct credentials *cr = current_user();
uint8_t effective = space->access[cr->auth_token].effective;
return ((PRIV_R | PRIV_W) & (cr->universal_access | effective) ||
space->def.uid == cr->uid);
......@@ -169,11 +176,14 @@ SysviewVindexIndex::SysviewVindexIndex(struct key_def *key_def)
}
static bool
vuser_predicate(struct tuple *tuple)
vuser_predicate(struct space *source, struct tuple *tuple)
{
struct credentials *cr = current_user();
if (PRIV_R & cr->universal_access)
return true;
return true; /* read access to unverse */
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
uint32_t uid = tuple_field_u32(tuple, 0);
uint32_t owner_id = tuple_field_u32(tuple, 1);
return uid == cr->uid || owner_id == cr->uid;
......@@ -185,11 +195,14 @@ SysviewVuserIndex::SysviewVuserIndex(struct key_def *key_def)
}
static bool
vpriv_predicate(struct tuple *tuple)
vpriv_predicate(struct space *source, struct tuple *tuple)
{
struct credentials *cr = current_user();
if (PRIV_R & cr->universal_access)
return true;
return true; /* read access to unverse */
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
uint32_t grantor_id = tuple_field_u32(tuple, 0);
uint32_t grantee_id = tuple_field_u32(tuple, 1);
return grantor_id == cr->uid || grantee_id == cr->uid;
......@@ -201,18 +214,20 @@ SysviewVprivIndex::SysviewVprivIndex(struct key_def *key_def)
}
static bool
vfunc_predicate(struct tuple *tuple)
vfunc_predicate(struct space *source, struct tuple *tuple)
{
struct credentials *cr = current_user();
if (PRIV_X & cr->universal_access)
return true;
uint32_t owner_id = tuple_field_u32(tuple, 1);
if (owner_id == cr->uid)
return true;
if ((PRIV_R | PRIV_X) & cr->universal_access)
return true; /* read or execute access to unverse */
if (PRIV_R & source->access[cr->auth_token].effective)
return true; /* read access to original space */
const char *name = tuple_field_cstr(tuple, 2);
uint32_t name_len = strlen(name);
struct func_def *func = func_by_name(name, name_len);
if (func != NULL && (PRIV_X & func->access[cr->auth_token].effective))
assert(func != NULL);
uint8_t effective = func->access[cr->auth_token].effective;
if (func->uid == cr->uid || (PRIV_X & effective))
return true;
return false;
}
......
......@@ -33,7 +33,7 @@
struct sysview_iterator;
typedef bool (*sysview_predicate_f)(struct tuple *);
typedef bool (*sysview_predicate_f)(struct space *source, struct tuple *);
class SysviewIndex: public Index {
public:
......
......@@ -238,10 +238,6 @@ box.schema.user.grant('guest', 'write', 'universe')
box.session.su('guest')
---
...
#box.space._vspace:select{}
---
- 13
...
#box.space._vindex:select{}
---
- 32
......@@ -270,6 +266,53 @@ box.space.test:drop()
box.session.su('guest')
---
...
-- read access to original space also allow to read a view
box.session.su('admin')
---
...
space_cnt = #box.space._space:select{}
---
...
index_cnt = #box.space._index:select{}
---
...
box.schema.user.grant('guest', 'read', 'space', '_space')
---
...
box.schema.user.grant('guest', 'read', 'space', '_index')
---
...
box.session.su('guest')
---
...
#box.space._vspace:select{} == space_cnt
---
- true
...
#box.space._vindex:select{} == index_cnt
---
- true
...
box.session.su('admin')
---
...
box.schema.user.revoke('guest', 'read', 'space', '_space')
---
...
box.schema.user.revoke('guest', 'read', 'space', '_index')
---
...
box.session.su('guest')
---
...
#box.space._vspace:select{} < space_cnt
---
- true
...
#box.space._vindex:select{} < index_cnt
---
- true
...
--
-- _vuser
--
......@@ -278,9 +321,35 @@ t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
---
- true
...
#box.space._vuser:select{}
-- read access to original space also allow to read a view
box.session.su('admin')
---
...
user_cnt = #box.space._user:select{}
---
...
box.schema.user.grant('guest', 'read', 'space', '_user')
---
...
box.session.su('guest')
---
...
#box.space._vuser:select{} == user_cnt
---
- true
...
box.session.su('admin')
---
...
box.schema.user.revoke('guest', 'read', 'space', '_user')
---
- 1
...
box.session.su('guest')
---
...
#box.space._vuser:select{} < user_cnt
---
- true
...
box.session.su('admin')
---
......@@ -324,9 +393,39 @@ box.space._vpriv.index[2]:select('role')[1][2] == session.uid()
---
- true
...
-- read access to original space also allow to read a view
box.session.su('admin')
---
...
box.schema.user.grant('guest', 'read', 'space', '_priv')
---
...
priv_cnt = #box.space._priv:select{}
---
...
box.session.su('guest')
---
...
#box.space._vpriv:select{} == priv_cnt
---
- true
...
box.session.su('admin')
---
...
box.schema.user.revoke('guest', 'read', 'space', '_priv')
---
...
box.session.su('guest')
---
...
cnt = #box.space._vpriv:select{}
---
...
cnt < priv_cnt
---
- true
...
box.session.su('admin')
---
...
......@@ -356,13 +455,43 @@ box.session.su('guest')
--
-- _vfunc
--
cnt = #box.space._vfunc:select{}
box.session.su('admin')
---
...
box.schema.func.create('test')
---
...
-- read access to original space also allow to read a view
func_cnt = #box.space._func:select{}
---
...
box.schema.user.grant('guest', 'read', 'space', '_func')
---
...
box.session.su('guest')
---
...
#box.space._vfunc:select{} == func_cnt
---
- true
...
box.session.su('admin')
---
...
box.schema.func.create('test')
box.schema.user.revoke('guest', 'read', 'space', '_func')
---
...
box.session.su('guest')
---
...
cnt = #box.space._vfunc:select{}
---
...
cnt < func_cnt
---
- true
...
box.session.su('admin')
---
...
box.schema.user.grant('guest', 'execute', 'function', 'test')
......
......@@ -94,7 +94,6 @@ box.schema.user.revoke('guest', 'read', 'universe')
box.schema.user.grant('guest', 'write', 'universe')
box.session.su('guest')
#box.space._vspace:select{}
#box.space._vindex:select{}
#box.space._vuser:select{}
#box.space._vpriv:select{}
......@@ -105,6 +104,22 @@ box.schema.user.revoke('guest', 'write', 'universe')
box.space.test:drop()
box.session.su('guest')
-- read access to original space also allow to read a view
box.session.su('admin')
space_cnt = #box.space._space:select{}
index_cnt = #box.space._index:select{}
box.schema.user.grant('guest', 'read', 'space', '_space')
box.schema.user.grant('guest', 'read', 'space', '_index')
box.session.su('guest')
#box.space._vspace:select{} == space_cnt
#box.space._vindex:select{} == index_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'read', 'space', '_space')
box.schema.user.revoke('guest', 'read', 'space', '_index')
box.session.su('guest')
#box.space._vspace:select{} < space_cnt
#box.space._vindex:select{} < index_cnt
--
-- _vuser
--
......@@ -112,7 +127,16 @@ box.session.su('guest')
-- a guest user can read information about itself
t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
#box.space._vuser:select{}
-- read access to original space also allow to read a view
box.session.su('admin')
user_cnt = #box.space._user:select{}
box.schema.user.grant('guest', 'read', 'space', '_user')
box.session.su('guest')
#box.space._vuser:select{} == user_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'read', 'space', '_user')
box.session.su('guest')
#box.space._vuser:select{} < user_cnt
box.session.su('admin')
box.schema.user.grant('guest', 'read,write', 'universe')
......@@ -137,8 +161,19 @@ box.session.su('guest')
-- a guest user can see granted 'public' role
box.space._vpriv.index[2]:select('role')[1][2] == session.uid()
-- read access to original space also allow to read a view
box.session.su('admin')
box.schema.user.grant('guest', 'read', 'space', '_priv')
priv_cnt = #box.space._priv:select{}
box.session.su('guest')
#box.space._vpriv:select{} == priv_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'read', 'space', '_priv')
box.session.su('guest')
cnt = #box.space._vpriv:select{}
cnt < priv_cnt
box.session.su('admin')
box.schema.user.grant('guest', 'read,write', 'space', '_schema')
box.session.su('guest')
......@@ -155,10 +190,22 @@ box.session.su('guest')
-- _vfunc
--
box.session.su('admin')
box.schema.func.create('test')
-- read access to original space also allow to read a view
func_cnt = #box.space._func:select{}
box.schema.user.grant('guest', 'read', 'space', '_func')
box.session.su('guest')
#box.space._vfunc:select{} == func_cnt
box.session.su('admin')
box.schema.user.revoke('guest', 'read', 'space', '_func')
box.session.su('guest')
cnt = #box.space._vfunc:select{}
cnt < func_cnt
box.session.su('admin')
box.schema.func.create('test')
box.schema.user.grant('guest', 'execute', 'function', 'test')
box.session.su('guest')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment