aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2022-08-25 10:06:02 -0400
committerRobert Haas <rhaas@postgresql.org>2022-08-25 10:06:02 -0400
commite3ce2de09d814f8770b2e3b3c152b7671bcdb83f (patch)
tree1ca5cf6da0ce86056ad4e573231a44ff651e252d /src/backend/parser
parent2059c5e3b06545e7d0650dba9c665332374c3c21 (diff)
downloadpostgresql-e3ce2de09d814f8770b2e3b3c152b7671bcdb83f.tar.gz
postgresql-e3ce2de09d814f8770b2e3b3c152b7671bcdb83f.zip
Allow grant-level control of role inheritance behavior.
The GRANT statement can now specify WITH INHERIT TRUE or WITH INHERIT FALSE to control whether the member inherits the granted role's permissions. For symmetry, you can now likewise write WITH ADMIN TRUE or WITH ADMIN FALSE to turn ADMIN OPTION on or off. If a GRANT does not specify WITH INHERIT, the behavior based on whether the member role is marked INHERIT or NOINHERIT. This means that if all roles are marked INHERIT or NOINHERIT before any role grants are performed, the behavior is identical to what we had before; otherwise, it's different, because ALTER ROLE [NO]INHERIT now only changes the default behavior of future grants, and has no effect on existing ones. Patch by me. Reviewed and testing by Nathan Bossart and Tushar Ahuja, with design-level comments from various others. Discussion: http://postgr.es/m/CA+Tgmoa5Sf4PiWrfxA=sGzDKg0Ojo3dADw=wAHOhR9dggV=RmQ@mail.gmail.com
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c8bd66dd543..b5ab9d9c9a3 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -362,9 +362,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <node> utility_option_arg
%type <defelt> drop_option
%type <boolean> opt_or_replace opt_no
- opt_grant_grant_option opt_grant_admin_option
+ opt_grant_grant_option
opt_nowait opt_if_exists opt_with_data
opt_transaction_chain
+%type <list> grant_role_opt_list
+%type <defelt> grant_role_opt
+%type <node> grant_role_opt_value
%type <ival> opt_nowait_or_skip
%type <list> OptRoleList AlterOptRoleList
@@ -7848,15 +7851,26 @@ opt_grant_grant_option:
*****************************************************************************/
GrantRoleStmt:
- GRANT privilege_list TO role_list opt_grant_admin_option opt_granted_by
+ GRANT privilege_list TO role_list opt_granted_by
{
GrantRoleStmt *n = makeNode(GrantRoleStmt);
n->is_grant = true;
n->granted_roles = $2;
n->grantee_roles = $4;
- n->admin_opt = $5;
- n->grantor = $6;
+ n->opt = NIL;
+ n->grantor = $5;
+ $$ = (Node *) n;
+ }
+ | GRANT privilege_list TO role_list WITH grant_role_opt_list opt_granted_by
+ {
+ GrantRoleStmt *n = makeNode(GrantRoleStmt);
+
+ n->is_grant = true;
+ n->granted_roles = $2;
+ n->grantee_roles = $4;
+ n->opt = $6;
+ n->grantor = $7;
$$ = (Node *) n;
}
;
@@ -7867,19 +7881,22 @@ RevokeRoleStmt:
GrantRoleStmt *n = makeNode(GrantRoleStmt);
n->is_grant = false;
- n->admin_opt = false;
+ n->opt = NIL;
n->granted_roles = $2;
n->grantee_roles = $4;
n->grantor = $5;
n->behavior = $6;
$$ = (Node *) n;
}
- | REVOKE ADMIN OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior
+ | REVOKE ColId OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior
{
GrantRoleStmt *n = makeNode(GrantRoleStmt);
+ DefElem *opt;
+ opt = makeDefElem(pstrdup($2),
+ (Node *) makeBoolean(false), @2);
n->is_grant = false;
- n->admin_opt = true;
+ n->opt = list_make1(opt);
n->granted_roles = $5;
n->grantee_roles = $7;
n->grantor = $8;
@@ -7888,8 +7905,22 @@ RevokeRoleStmt:
}
;
-opt_grant_admin_option: WITH ADMIN OPTION { $$ = true; }
- | /*EMPTY*/ { $$ = false; }
+grant_role_opt_list:
+ grant_role_opt_list ',' grant_role_opt { $$ = lappend($1, $3); }
+ | grant_role_opt { $$ = list_make1($1); }
+ ;
+
+grant_role_opt:
+ ColLabel grant_role_opt_value
+ {
+ $$ = makeDefElem(pstrdup($1), $2, @1);
+ }
+ ;
+
+grant_role_opt_value:
+ OPTION { $$ = (Node *) makeBoolean(true); }
+ | TRUE_P { $$ = (Node *) makeBoolean(true); }
+ | FALSE_P { $$ = (Node *) makeBoolean(false); }
;
opt_granted_by: GRANTED BY RoleSpec { $$ = $3; }