@@ -460,6 +460,37 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
460
460
}
461
461
}
462
462
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
+
463
494
/*
464
495
* Add the specified members to this new role. adminmembers get the admin
465
496
* option, rolemembers don't.
@@ -1429,7 +1460,7 @@ AddRoleMems(const char *rolename, Oid roleid,
1429
1460
* present. Nonetheless, inasmuch as users might look to it for a crude
1430
1461
* audit trail, let only superusers impute the grant to a third party.
1431
1462
*/
1432
- if (grantorId != GetUserId () && !superuser ())
1463
+ if (grantorId != GetUserId () && grantorId != BOOTSTRAP_SUPERUSERID && !superuser ())
1433
1464
ereport (ERROR ,
1434
1465
(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
1435
1466
errmsg ("must be superuser to set grantor" )));
0 commit comments