1717#include "access/htup_details.h"
1818#include "access/xact.h"
1919#include "catalog/binary_upgrade.h"
20+ #include "catalog/catalog.h"
2021#include "catalog/dependency.h"
2122#include "catalog/indexing.h"
2223#include "catalog/objectaccess.h"
@@ -311,6 +312,17 @@ CreateRole(CreateRoleStmt *stmt)
311312 errmsg ("permission denied to create role" )));
312313 }
313314
315+ /*
316+ * Check that the user is not trying to create a role in the reserved
317+ * "pg_" namespace.
318+ */
319+ if (IsReservedName (stmt -> role ))
320+ ereport (ERROR ,
321+ (errcode (ERRCODE_RESERVED_NAME ),
322+ errmsg ("role name \"%s\" is reserved" ,
323+ stmt -> role ),
324+ errdetail ("Role names starting with \"pg_\" are reserved." )));
325+
314326 /*
315327 * Check the pg_authid relation to be certain the role doesn't already
316328 * exist.
@@ -507,6 +519,9 @@ AlterRole(AlterRoleStmt *stmt)
507519 DefElem * dbypassRLS = NULL ;
508520 Oid roleid ;
509521
522+ check_rolespec_name (stmt -> role ,
523+ "Cannot alter reserved roles." );
524+
510525 /* Extract options from the statement node tree */
511526 foreach (option , stmt -> options )
512527 {
@@ -857,6 +872,9 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
857872
858873 if (stmt -> role )
859874 {
875+ check_rolespec_name (stmt -> role ,
876+ "Cannot alter reserved roles." );
877+
860878 roletuple = get_rolespec_tuple (stmt -> role );
861879 roleid = HeapTupleGetOid (roletuple );
862880
@@ -1117,6 +1135,7 @@ RenameRole(const char *oldname, const char *newname)
11171135 int i ;
11181136 Oid roleid ;
11191137 ObjectAddress address ;
1138+ Form_pg_authid authform ;
11201139
11211140 rel = heap_open (AuthIdRelationId , RowExclusiveLock );
11221141 dsc = RelationGetDescr (rel );
@@ -1136,6 +1155,7 @@ RenameRole(const char *oldname, const char *newname)
11361155 */
11371156
11381157 roleid = HeapTupleGetOid (oldtuple );
1158+ authform = (Form_pg_authid ) GETSTRUCT (oldtuple );
11391159
11401160 if (roleid == GetSessionUserId ())
11411161 ereport (ERROR ,
@@ -1146,6 +1166,24 @@ RenameRole(const char *oldname, const char *newname)
11461166 (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
11471167 errmsg ("current user cannot be renamed" )));
11481168
1169+ /*
1170+ * Check that the user is not trying to rename a system role and
1171+ * not trying to rename a role into the reserved "pg_" namespace.
1172+ */
1173+ if (IsReservedName (NameStr (authform -> rolname )))
1174+ ereport (ERROR ,
1175+ (errcode (ERRCODE_RESERVED_NAME ),
1176+ errmsg ("role name \"%s\" is reserved" ,
1177+ NameStr (authform -> rolname )),
1178+ errdetail ("Role names starting with \"pg_\" are reserved." )));
1179+
1180+ if (IsReservedName (newname ))
1181+ ereport (ERROR ,
1182+ (errcode (ERRCODE_RESERVED_NAME ),
1183+ errmsg ("role name \"%s\" is reserved" ,
1184+ newname ),
1185+ errdetail ("Role names starting with \"pg_\" are reserved." )));
1186+
11491187 /* make sure the new name doesn't exist */
11501188 if (SearchSysCacheExists1 (AUTHNAME , CStringGetDatum (newname )))
11511189 ereport (ERROR ,
@@ -1224,10 +1262,18 @@ GrantRole(GrantRoleStmt *stmt)
12241262 ListCell * item ;
12251263
12261264 if (stmt -> grantor )
1265+ {
1266+ check_rolespec_name (stmt -> grantor ,
1267+ "Cannot specify reserved role as grantor." );
12271268 grantor = get_rolespec_oid (stmt -> grantor , false);
1269+ }
12281270 else
12291271 grantor = GetUserId ();
12301272
1273+ foreach (item , stmt -> grantee_roles )
1274+ check_rolespec_name (lfirst (item ),
1275+ "Cannot GRANT roles to a reserved role." );
1276+
12311277 grantee_ids = roleSpecsToIds (stmt -> grantee_roles );
12321278
12331279 /* AccessShareLock is enough since we aren't modifying pg_authid */
@@ -1318,6 +1364,9 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
13181364 errmsg ("permission denied to reassign objects" )));
13191365 }
13201366
1367+ check_rolespec_name (stmt -> newrole ,
1368+ "Cannot specify reserved role as owner." );
1369+
13211370 /* Must have privileges on the receiving side too */
13221371 newrole = get_rolespec_oid (stmt -> newrole , false);
13231372
0 commit comments