Commit 371087d0 authored by Daniel Gustafsson's avatar Daniel Gustafsson

Fix GRANTED BY support in REVOKE ROLE statements

Commit 6aaaa76b added support for the GRANTED BY clause in GRANT and
REVOKE statements, but missed adding support for checking the role in
the REVOKE ROLE case. Fix by checking that the parsed role matches the
CURRENT_ROLE/CURRENT_USER requirement, and also add some tests for it.
Backpatch to v14 where GRANTED BY support was introduced.

Discussion: https://postgr.es/m/B7F6699A-A984-4943-B9BF-CEB84C003527@yesql.se
Backpatch-through: 14
parent 1cc13b83
......@@ -1319,7 +1319,18 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
{
grantor = get_rolespec_oid(stmt->grantor, false);
/*
* Currently, this clause is only for SQL compatibility, not very
* interesting otherwise.
*/
if (grantor != GetUserId())
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("grantor must be current user")));
}
else
grantor = GetUserId();
......
......@@ -7181,6 +7181,7 @@ RevokeRoleStmt:
n->admin_opt = false;
n->granted_roles = $2;
n->grantee_roles = $4;
n->grantor = $5;
n->behavior = $6;
$$ = (Node*)n;
}
......@@ -7191,6 +7192,7 @@ RevokeRoleStmt:
n->admin_opt = true;
n->granted_roles = $5;
n->grantee_roles = $7;
n->grantor = $8;
n->behavior = $9;
$$ = (Node*)n;
}
......
......@@ -29,6 +29,7 @@ CREATE USER regress_priv_user5; -- duplicate
ERROR: role "regress_priv_user5" already exists
CREATE USER regress_priv_user6;
CREATE USER regress_priv_user7;
CREATE ROLE regress_priv_role;
GRANT pg_read_all_data TO regress_priv_user6;
GRANT pg_write_all_data TO regress_priv_user7;
CREATE GROUP regress_priv_group1;
......@@ -44,6 +45,14 @@ CREATE FUNCTION leak(integer,integer) RETURNS boolean
LANGUAGE internal IMMUTABLE STRICT; -- but deliberately not LEAKPROOF
ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1;
-- test owner privileges
GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE;
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo; -- error
ERROR: role "foo" does not exist
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2; -- error
ERROR: grantor must be current user
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER;
REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE;
DROP ROLE regress_priv_role;
SET SESSION AUTHORIZATION regress_priv_user1;
SELECT session_user, current_user;
session_user | current_user
......
......@@ -32,6 +32,7 @@ CREATE USER regress_priv_user5;
CREATE USER regress_priv_user5; -- duplicate
CREATE USER regress_priv_user6;
CREATE USER regress_priv_user7;
CREATE ROLE regress_priv_role;
GRANT pg_read_all_data TO regress_priv_user6;
GRANT pg_write_all_data TO regress_priv_user7;
......@@ -53,6 +54,13 @@ ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1;
-- test owner privileges
GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE;
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo; -- error
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2; -- error
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER;
REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE;
DROP ROLE regress_priv_role;
SET SESSION AUTHORIZATION regress_priv_user1;
SELECT session_user, current_user;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment