Tarantool development patches archive
 help / color / mirror / Atom feed
From: Serge Petrenko <sergepetrenko@tarantool.org>
To: tarantool-patches@freelists.org
Cc: Serge Petrenko <sergepetrenko@tarantool.org>
Subject: [tarantool-patches] [PATCH] Fix nested calls to box.session.su()
Date: Tue,  3 Jul 2018 13:40:20 +0300	[thread overview]
Message-ID: <20180703104020.43833-1-sergepetrenko@tarantool.org> (raw)

box.session.su() set effective user to user
after its execution, which made nested calls
to it not work. Fixed this by saving current
effective user and recovering from the save
after sudo execution. This opened up a bug in
box.schema.user.drop(): it has unnecessary
check for privelege PRIV_REVOKE, which never
gets granted to anyone but admin. Also fixed
this by adding one extra box.session.su() call.

Closes #3090, #3492
---
https://github.com/tarantool/tarantool/tree/sergepetrenko/gh-3090-nested-su-fix
https://github.com/tarantool/tarantool/issues/3090
https://github.com/tarantool/tarantool/issues/3492

 src/box/lua/schema.lua   |  5 +++-
 src/box/lua/session.c    |  7 ++---
 test/box/access.result   | 69 +++++++++++++++++++++++++++++++++++++++++++-----
 test/box/access.test.lua | 37 ++++++++++++++++++++++----
 4 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 30c6bc69c..788b0be89 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -2038,9 +2038,12 @@ local function drop(uid, opts)
         box.session.su('admin', box.schema.user.revoke, uid,
                        'session,usage', 'universe', nil, {if_exists = true})
     end
+    
     local privs = _priv.index.primary:select{uid}
     for k, tuple in pairs(privs) do
-        revoke(uid, uid, tuple[5], tuple[3], tuple[4])
+	-- we need an additional box.session.su() here, because of
+	-- unnecessary check for privilege PRIV_REVOKE in priv_def_check()
+        box.session.su("admin", revoke, uid, uid, tuple[5], tuple[3], tuple[4])
     end
     box.space[box.schema.USER_ID]:delete{uid}
 end
diff --git a/src/box/lua/session.c b/src/box/lua/session.c
index 51caf199f..cb8fa411a 100644
--- a/src/box/lua/session.c
+++ b/src/box/lua/session.c
@@ -188,16 +188,17 @@ lbox_session_su(struct lua_State *L)
 		fiber_set_user(fiber(), &session->credentials);
 		return 0; /* su */
 	}
-
+	
 	struct credentials su_credentials;
+	struct credentials *old_credentials =
+		(struct credentials *)fiber_get_key(fiber(), FIBER_KEY_USER);
 	credentials_init(&su_credentials, user->auth_token, user->def->uid);
 	fiber_set_user(fiber(), &su_credentials);
-
 	/* sudo */
 	luaL_checktype(L, 2, LUA_TFUNCTION);
 	int error = lua_pcall(L, top - 2, LUA_MULTRET, 0);
 	/* Restore the original credentials. */
-	fiber_set_user(fiber(), &session->credentials);
+	fiber_set_user(fiber(), old_credentials);
 
 	if (error)
 		luaT_error(L);
diff --git a/test/box/access.result b/test/box/access.result
index 191857f49..039790d91 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -1414,19 +1414,76 @@ _ = box.session.su("tester", box.schema.func.drop, 'test_func')
 -- box.session.su("tester", s.format, s, {name="id", type="unsigned"})
 -- failed drop
 -- box.session.su("tester", s.drop, s)
--- can't use here sudo
--- because drop use sudo inside
--- and currently sudo can't be performed nested
-box.session.su("tester")
+-- gh-3090: nested su unexpected behaviour.
+-- gh-3492: su doesn't grant effective privileges
+-- should print guest
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
+function f()
+    box.session.su("admin", function() end)
+    return box.session.effective_user()
+end;
+---
+...
+box.session.su("guest", f);
+---
+- guest
+...
+-- the call of test_admin below shouldn't fail
+function test_admin()
+    box.schema.user.create('storage', {password = 'storage', if_not_exists=true})
+
+    box.schema.user.grant('storage', 'replication', nil, nil, {if_not_exists=true})
+end;
+---
+...
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
+box.session.su("guest")
+---
+...
+box.session.user()
 ---
+- guest
 ...
-box.schema.user.drop("test")
+box.session.effective_user()
 ---
-- error: Revoke access to role 'public' is denied for user 'tester'
+- guest
+...
+box.session.su("admin", test_admin)
+---
+...
+box.session.user()
+---
+- guest
+...
+box.session.effective_user()
+---
+- guest
 ...
 box.session.su("admin")
 ---
 ...
+box.session.user()
+---
+- admin
+...
+box.session.effective_user()
+---
+- admin
+...
+box.schema.user.drop("storage")
+---
+...
+-- now sudo can be used here since nested sudo is fixed
+box.session.su("tester", box.schema.user.drop, "test")
+---
+- error: Drop access to user 'test' is denied for user 'tester'
+...
 box.session.su("tester", box.schema.func.drop, "test")
 ---
 - error: Drop access to function 'test' is denied for user 'tester'
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 7e880a0cf..c5fa1f138 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -544,13 +544,40 @@ _ = box.session.su("tester", box.schema.func.drop, 'test_func')
 -- failed drop
 -- box.session.su("tester", s.drop, s)
 
--- can't use here sudo
--- because drop use sudo inside
--- and currently sudo can't be performed nested
-box.session.su("tester")
-box.schema.user.drop("test")
+
+-- gh-3090: nested su unexpected behaviour.
+-- gh-3492: su doesn't grant effective privileges
+
+-- should print guest
+test_run:cmd("setopt delimiter ';'")
+function f()
+    box.session.su("admin", function() end)
+    return box.session.effective_user()
+end;
+box.session.su("guest", f);
+
+-- the call of test_admin below shouldn't fail
+function test_admin()
+    box.schema.user.create('storage', {password = 'storage', if_not_exists=true})
+
+    box.schema.user.grant('storage', 'replication', nil, nil, {if_not_exists=true})
+end;
+test_run:cmd("setopt delimiter ''");
+
+box.session.su("guest")
+box.session.user()
+box.session.effective_user()
+box.session.su("admin", test_admin)
+box.session.user()
+box.session.effective_user()
 box.session.su("admin")
+box.session.user()
+box.session.effective_user()
 
+box.schema.user.drop("storage")
+
+-- now sudo can be used here since nested sudo is fixed
+box.session.su("tester", box.schema.user.drop, "test")
 box.session.su("tester", box.schema.func.drop, "test")
 
 box.schema.user.grant("tester", "drop", "universe")
-- 
2.15.2 (Apple Git-101.1)

             reply	other threads:[~2018-07-03 10:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-03 10:40 Serge Petrenko [this message]
2018-07-03 15:35 ` [tarantool-patches] [PATCH v2] " Serge Petrenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180703104020.43833-1-sergepetrenko@tarantool.org \
    --to=sergepetrenko@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH] Fix nested calls to box.session.su()' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox