Skip to content

Commit d586e23

Browse files
knizhnikKonstantin Knizhnik
authored andcommitted
Make it possible to grant self created roles (#297)
Co-authored-by: Konstantin Knizhnik <knizhnik@neon.tech>
1 parent fee0f62 commit d586e23

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/backend/commands/user.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,37 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
498498
}
499499
}
500500

501+
/*
502+
* If the current user isn't a superuser, make them an admin of the new
503+
* role so that they can administer the new object they just created.
504+
* Superusers will be able to do that anyway.
505+
*
506+
* The grantor of record for this implicit grant is the bootstrap
507+
* superuser, which means that the CREATEROLE user cannot revoke the
508+
* grant. They can however grant the created role back to themselves with
509+
* different options, since they enjoy ADMIN OPTION on it.
510+
*/
511+
if (!superuser())
512+
{
513+
RoleSpec *current_role = makeNode(RoleSpec);
514+
List *memberSpecs;
515+
List *memberIds = list_make1_oid(GetUserId());
516+
517+
current_role->roletype = ROLESPEC_CURRENT_ROLE;
518+
current_role->location = -1;
519+
memberSpecs = list_make1(current_role);
520+
521+
AddRoleMems(stmt->role, roleid,
522+
memberSpecs, memberIds,
523+
BOOTSTRAP_SUPERUSERID, true);
524+
525+
/*
526+
* We must make the implicit grant visible to the code below, else the
527+
* additional grants will fail.
528+
*/
529+
CommandCounterIncrement();
530+
}
531+
501532
/*
502533
* Add the specified members to this new role. adminmembers get the admin
503534
* option, rolemembers don't.
@@ -1521,7 +1552,7 @@ AddRoleMems(const char *rolename, Oid roleid,
15211552
* use an explicit grantor specification to take advantage of the session
15221553
* user's self-admin right.
15231554
*/
1524-
if (grantorId != GetUserId() && !superuser())
1555+
if (grantorId != GetUserId() && grantorId != BOOTSTRAP_SUPERUSERID && !superuser())
15251556
ereport(ERROR,
15261557
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
15271558
errmsg("must be superuser to set grantor")));

0 commit comments

Comments
 (0)