@@ -498,6 +498,37 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
498
498
}
499
499
}
500
500
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
+
501
532
/*
502
533
* Add the specified members to this new role. adminmembers get the admin
503
534
* option, rolemembers don't.
@@ -1521,7 +1552,7 @@ AddRoleMems(const char *rolename, Oid roleid,
1521
1552
* use an explicit grantor specification to take advantage of the session
1522
1553
* user's self-admin right.
1523
1554
*/
1524
- if (grantorId != GetUserId () && !superuser ())
1555
+ if (grantorId != GetUserId () && grantorId != BOOTSTRAP_SUPERUSERID && !superuser ())
1525
1556
ereport (ERROR ,
1526
1557
(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
1527
1558
errmsg ("must be superuser to set grantor" )));
0 commit comments