diff --git a/expected/set_user.out b/expected/set_user.out index 1763d8e..5d9320c 100644 --- a/expected/set_user.out +++ b/expected/set_user.out @@ -14,6 +14,7 @@ CREATE ROLE newbs; CREATE ROLE su NOINHERIT; -- dba is the role we want to allow to execute set_user() GRANT EXECUTE ON FUNCTION set_user(text) TO dba; +GRANT EXECUTE ON FUNCTION set_user(text,text) TO dba; GRANT EXECUTE ON FUNCTION set_user_u(text) TO dba; GRANT newbs TO bob; -- joe will be able to escalate without set_user() via su @@ -72,6 +73,9 @@ ERROR: "SET log_statement" blocked by set_user config BEGIN; SET LOCAL log_statement = 'none'; ABORT; ERROR: "SET log_statement" blocked by set_user config -- test reset_user +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" SELECT reset_user(); reset_user ------------ @@ -84,6 +88,48 @@ SELECT SESSION_USER, CURRENT_USER; dba | dba (1 row) +-- test set_user and reset_user with token +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + +SELECT set_user('bob', 'secret'); + set_user +---------- + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" +SELECT reset_user(); -- should fail +ERROR: reset token required but not provided +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +SELECT reset_user('secret'); -- succeed + reset_user +------------ + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + RESET SESSION AUTHORIZATION; ALTER SYSTEM SET wal_level = minimal; COPY (select 42) TO PROGRAM 'cat'; diff --git a/expected/set_user_1.out b/expected/set_user_1.out index da0ba7c..1021f30 100644 --- a/expected/set_user_1.out +++ b/expected/set_user_1.out @@ -73,6 +73,9 @@ ERROR: "SET log_statement" blocked by set_user config BEGIN; SET LOCAL log_statement = 'none'; ABORT; ERROR: "SET log_statement" blocked by set_user config -- test reset_user +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" SELECT reset_user(); reset_user ------------ @@ -85,6 +88,48 @@ SELECT SESSION_USER, CURRENT_USER; dba | dba (1 row) +-- test set_user and reset_user with token +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + +SELECT set_user('bob', 'secret'); + set_user +---------- + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" +SELECT reset_user(); -- should fail +ERROR: reset token required but not provided +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +SELECT reset_user('secret'); -- succeed + reset_user +------------ + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + RESET SESSION AUTHORIZATION; ALTER SYSTEM SET wal_level = minimal; ERROR: syntax error at or near "SYSTEM" diff --git a/expected/set_user_2.out b/expected/set_user_2.out index 7537c77..e79da1b 100644 --- a/expected/set_user_2.out +++ b/expected/set_user_2.out @@ -75,6 +75,9 @@ ERROR: "SET log_statement" blocked by set_user config BEGIN; SET LOCAL log_statement = 'none'; ABORT; ERROR: "SET log_statement" blocked by set_user config -- test reset_user +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" SELECT reset_user(); reset_user ------------ @@ -87,6 +90,48 @@ SELECT SESSION_USER, CURRENT_USER; dba | dba (1 row) +-- test set_user and reset_user with token +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + +SELECT set_user('bob', 'secret'); + set_user +---------- + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +RESET ROLE; -- should fail +ERROR: "RESET role" blocked by set_user +HINT: "Use `SELECT reset_user();` to reset role" +SELECT reset_user(); -- should fail +ERROR: reset token required but not provided +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | bob +(1 row) + +SELECT reset_user('secret'); -- succeed + reset_user +------------ + OK +(1 row) + +SELECT SESSION_USER, CURRENT_USER; + session_user | current_user +--------------+-------------- + dba | dba +(1 row) + RESET SESSION AUTHORIZATION; ALTER SYSTEM SET wal_level = minimal; ERROR: syntax error at or near "SYSTEM" diff --git a/sql/set_user.sql b/sql/set_user.sql index 9072e04..07f6f83 100644 --- a/sql/set_user.sql +++ b/sql/set_user.sql @@ -18,6 +18,7 @@ CREATE ROLE su NOINHERIT; -- dba is the role we want to allow to execute set_user() GRANT EXECUTE ON FUNCTION set_user(text) TO dba; +GRANT EXECUTE ON FUNCTION set_user(text,text) TO dba; GRANT EXECUTE ON FUNCTION set_user_u(text) TO dba; GRANT newbs TO bob; -- joe will be able to escalate without set_user() via su @@ -49,9 +50,22 @@ RESET log_statement; BEGIN; SET LOCAL log_statement = 'none'; ABORT; -- test reset_user +RESET ROLE; -- should fail SELECT reset_user(); SELECT SESSION_USER, CURRENT_USER; +-- test set_user and reset_user with token +SELECT SESSION_USER, CURRENT_USER; +SELECT set_user('bob', 'secret'); +SELECT SESSION_USER, CURRENT_USER; +RESET ROLE; -- should fail + +SELECT reset_user(); -- should fail +SELECT SESSION_USER, CURRENT_USER; + +SELECT reset_user('secret'); -- succeed +SELECT SESSION_USER, CURRENT_USER; + RESET SESSION AUTHORIZATION; ALTER SYSTEM SET wal_level = minimal; COPY (select 42) TO PROGRAM 'cat';