From 9e30f895b52d433965ffd5ba96cda381711446d1 Mon Sep 17 00:00:00 2001
From: IlyaMarkovMipt <markovilya197@gmail.com>
Date: Mon, 29 Jan 2018 11:37:15 +0300
Subject: [PATCH] security: Change checks on usage access

* Add following behavior:
Owner of object can't utilize her own objects if she has not usage
access.
* Change access checks of space, sequence, function objects
Similar checks of other objects are performed in alter.cc.

Closes gh-3089
---
 src/box/call.c                |   7 ++-
 src/box/sequence.c            |   9 ++-
 src/box/space.c               |   8 ++-
 test/box/access_misc.result   | 103 ++++++++++++++++++++++++++++++++++
 test/box/access_misc.test.lua |  40 +++++++++++++
 5 files changed, 162 insertions(+), 5 deletions(-)

diff --git a/src/box/call.c b/src/box/call.c
index 3312477934..6388e1e68f 100644
--- a/src/box/call.c
+++ b/src/box/call.c
@@ -72,8 +72,13 @@ access_check_func(const char *name, uint32_t name_len, struct func **funcp)
 	}
 	user_access_t access = PRIV_X | PRIV_U;
 	user_access_t func_access = access & ~credentials->universal_access;
-	if (func == NULL || (func->def->uid != credentials->uid &&
+	if (func == NULL ||
+	    /* Check for missing Usage access, ignore owner rights. */
+	    func_access & PRIV_U ||
+	    /* Check for missing specific access, respect owner rights. */
+	    (func->def->uid != credentials->uid &&
 	    func_access & ~func->access[credentials->auth_token].effective)) {
+
 		/* Access violation, report error. */
 		struct user *user = user_find(credentials->uid);
 		if (user != NULL) {
diff --git a/src/box/sequence.c b/src/box/sequence.c
index 0f6a8ca974..162147cded 100644
--- a/src/box/sequence.c
+++ b/src/box/sequence.c
@@ -250,8 +250,13 @@ access_check_sequence(struct sequence *seq)
 
 	user_access_t access = PRIV_U | PRIV_W;
 	user_access_t sequence_access = access & ~cr->universal_access;
-	if (seq->def->uid != cr->uid &&
-	    sequence_access & ~seq->access[cr->auth_token].effective) {
+	if (sequence_access &&
+	    /* Check for missing Usage access, ignore owner rights. */
+	    (sequence_access & PRIV_U ||
+	     /* Check for missing specific access, respect owner rights. */
+	     (seq->def->uid != cr->uid &&
+	      sequence_access & ~seq->access[cr->auth_token].effective))) {
+
 		/* Access violation, report error. */
 		struct user *user = user_find(cr->uid);
 		if (user != NULL) {
diff --git a/src/box/space.c b/src/box/space.c
index bb5f07ed5c..11fd2c17dd 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -59,8 +59,12 @@ access_check_space(struct space *space, user_access_t access)
 	 */
 	user_access_t space_access = access & ~cr->universal_access;
 
-	if (space_access && space->def->uid != cr->uid &&
-	    space_access & ~space->access[cr->auth_token].effective) {
+	if (space_access &&
+	    /* Check for missing Usage access, ignore owner rights. */
+	    (space_access & PRIV_U ||
+	     /* Check for missing specific access, respect owner rights. */
+	    (space->def->uid != cr->uid &&
+	     space_access & ~space->access[cr->auth_token].effective))) {
 		/*
 		 * Report access violation. Throw "no such user"
 		 * error if there is  no user with this id.
diff --git a/test/box/access_misc.result b/test/box/access_misc.result
index 67234ab243..d358e5fdb3 100644
--- a/test/box/access_misc.result
+++ b/test/box/access_misc.result
@@ -620,6 +620,109 @@ box.schema.user.drop('testuser')
 s:drop()
 ---
 ...
+--
+-- gh-3089 usage access is not applied to owner
+--
+box.schema.user.grant("guest","read, write, execute, create", "universe")
+---
+...
+box.session.su("guest")
+---
+...
+s = box.schema.space.create("test")
+---
+...
+_ = s:create_index("prim")
+---
+...
+test_func = function() end
+---
+...
+box.schema.func.create('test_func')
+---
+...
+sq = box.schema.sequence.create("test")
+---
+...
+box.session.su("admin")
+---
+...
+box.schema.user.revoke("guest", "usage", "universe")
+---
+...
+box.session.su("guest")
+---
+...
+s:select{}
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+s:drop()
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+sq:set(100)
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+sq:drop()
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+c = require("net.box").connect(os.getenv("LISTEN"))
+---
+...
+c:call("test_func")
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+box.session.su("admin")
+---
+...
+box.schema.user.revoke("guest","read, write, execute, create", "universe")
+---
+...
+box.session.su("guest")
+---
+...
+s:select{}
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+s:drop()
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+sq:set(100)
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+sq:drop()
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+c = require("net.box").connect(os.getenv("LISTEN"))
+---
+...
+c:call("test_func")
+---
+- error: Usage access to universe '' is denied for user 'guest'
+...
+box.session.su("admin")
+---
+...
+box.schema.user.grant("guest","usage", "universe")
+---
+...
+box.schema.func.drop("test_func")
+---
+...
+s:drop()
+---
+...
+sq:drop()
+---
+...
 box.space._user:select()
 ---
 - - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}]
diff --git a/test/box/access_misc.test.lua b/test/box/access_misc.test.lua
index c23a021731..18e4e68564 100644
--- a/test/box/access_misc.test.lua
+++ b/test/box/access_misc.test.lua
@@ -243,6 +243,46 @@ box.schema.user.drop('testuser')
 
 s:drop()
 
+--
+-- gh-3089 usage access is not applied to owner
+--
+box.schema.user.grant("guest","read, write, execute, create", "universe")
+box.session.su("guest")
+s = box.schema.space.create("test")
+_ = s:create_index("prim")
+test_func = function() end
+box.schema.func.create('test_func')
+sq = box.schema.sequence.create("test")
+box.session.su("admin")
+box.schema.user.revoke("guest", "usage", "universe")
+box.session.su("guest")
+
+s:select{}
+s:drop()
+sq:set(100)
+sq:drop()
+c = require("net.box").connect(os.getenv("LISTEN"))
+c:call("test_func")
+
+box.session.su("admin")
+box.schema.user.revoke("guest","read, write, execute, create", "universe")
+box.session.su("guest")
+
+s:select{}
+s:drop()
+sq:set(100)
+sq:drop()
+c = require("net.box").connect(os.getenv("LISTEN"))
+c:call("test_func")
+
+box.session.su("admin")
+
+box.schema.user.grant("guest","usage", "universe")
+
+box.schema.func.drop("test_func")
+s:drop()
+sq:drop()
+
 box.space._user:select()
 box.space._space:select()
 box.space._func:select()
-- 
GitLab