Skip to content

Commit cf25813

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

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
@@ -460,6 +460,37 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
460460
}
461461
}
462462

463+
/*
464+
* If the current user isn't a superuser, make them an admin of the new
465+
* role so that they can administer the new object they just created.
466+
* Superusers will be able to do that anyway.
467+
*
468+
* The grantor of record for this implicit grant is the bootstrap
469+
* superuser, which means that the CREATEROLE user cannot revoke the
470+
* grant. They can however grant the created role back to themselves with
471+
* different options, since they enjoy ADMIN OPTION on it.
472+
*/
473+
if (!superuser())
474+
{
475+
RoleSpec *current_role = makeNode(RoleSpec);
476+
List *memberSpecs;
477+
List *memberIds = list_make1_oid(GetUserId());
478+
479+
current_role->roletype = ROLESPEC_CURRENT_ROLE;
480+
current_role->location = -1;
481+
memberSpecs = list_make1(current_role);
482+
483+
AddRoleMems(stmt->role, roleid,
484+
memberSpecs, memberIds,
485+
BOOTSTRAP_SUPERUSERID, true);
486+
487+
/*
488+
* We must make the implicit grant visible to the code below, else the
489+
* additional grants will fail.
490+
*/
491+
CommandCounterIncrement();
492+
}
493+
463494
/*
464495
* Add the specified members to this new role. adminmembers get the admin
465496
* option, rolemembers don't.
@@ -1429,7 +1460,7 @@ AddRoleMems(const char *rolename, Oid roleid,
14291460
* present. Nonetheless, inasmuch as users might look to it for a crude
14301461
* audit trail, let only superusers impute the grant to a third party.
14311462
*/
1432-
if (grantorId != GetUserId() && !superuser())
1463+
if (grantorId != GetUserId() && grantorId != BOOTSTRAP_SUPERUSERID && !superuser())
14331464
ereport(ERROR,
14341465
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
14351466
errmsg("must be superuser to set grantor")));

0 commit comments

Comments
 (0)