mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Reserve the "pg_" namespace for roles
This will prevent users from creating roles which begin with "pg_" and will check for those roles before allowing an upgrade using pg_upgrade. This will allow for default roles to be provided at initdb time. Reviews by José Luis Tallón and Robert Haas
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
#include "access/htup_details.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/binary_upgrade.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/objectaccess.h"
|
||||
@ -311,6 +312,17 @@ CreateRole(CreateRoleStmt *stmt)
|
||||
errmsg("permission denied to create role")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the user is not trying to create a role in the reserved
|
||||
* "pg_" namespace.
|
||||
*/
|
||||
if (IsReservedName(stmt->role))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_RESERVED_NAME),
|
||||
errmsg("role name \"%s\" is reserved",
|
||||
stmt->role),
|
||||
errdetail("Role names starting with \"pg_\" are reserved.")));
|
||||
|
||||
/*
|
||||
* Check the pg_authid relation to be certain the role doesn't already
|
||||
* exist.
|
||||
@ -507,6 +519,9 @@ AlterRole(AlterRoleStmt *stmt)
|
||||
DefElem *dbypassRLS = NULL;
|
||||
Oid roleid;
|
||||
|
||||
check_rolespec_name(stmt->role,
|
||||
"Cannot alter reserved roles.");
|
||||
|
||||
/* Extract options from the statement node tree */
|
||||
foreach(option, stmt->options)
|
||||
{
|
||||
@ -857,6 +872,9 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
|
||||
|
||||
if (stmt->role)
|
||||
{
|
||||
check_rolespec_name(stmt->role,
|
||||
"Cannot alter reserved roles.");
|
||||
|
||||
roletuple = get_rolespec_tuple(stmt->role);
|
||||
roleid = HeapTupleGetOid(roletuple);
|
||||
|
||||
@ -1117,6 +1135,7 @@ RenameRole(const char *oldname, const char *newname)
|
||||
int i;
|
||||
Oid roleid;
|
||||
ObjectAddress address;
|
||||
Form_pg_authid authform;
|
||||
|
||||
rel = heap_open(AuthIdRelationId, RowExclusiveLock);
|
||||
dsc = RelationGetDescr(rel);
|
||||
@ -1136,6 +1155,7 @@ RenameRole(const char *oldname, const char *newname)
|
||||
*/
|
||||
|
||||
roleid = HeapTupleGetOid(oldtuple);
|
||||
authform = (Form_pg_authid) GETSTRUCT(oldtuple);
|
||||
|
||||
if (roleid == GetSessionUserId())
|
||||
ereport(ERROR,
|
||||
@ -1146,6 +1166,24 @@ RenameRole(const char *oldname, const char *newname)
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("current user cannot be renamed")));
|
||||
|
||||
/*
|
||||
* Check that the user is not trying to rename a system role and
|
||||
* not trying to rename a role into the reserved "pg_" namespace.
|
||||
*/
|
||||
if (IsReservedName(NameStr(authform->rolname)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_RESERVED_NAME),
|
||||
errmsg("role name \"%s\" is reserved",
|
||||
NameStr(authform->rolname)),
|
||||
errdetail("Role names starting with \"pg_\" are reserved.")));
|
||||
|
||||
if (IsReservedName(newname))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_RESERVED_NAME),
|
||||
errmsg("role name \"%s\" is reserved",
|
||||
newname),
|
||||
errdetail("Role names starting with \"pg_\" are reserved.")));
|
||||
|
||||
/* make sure the new name doesn't exist */
|
||||
if (SearchSysCacheExists1(AUTHNAME, CStringGetDatum(newname)))
|
||||
ereport(ERROR,
|
||||
@ -1224,10 +1262,18 @@ GrantRole(GrantRoleStmt *stmt)
|
||||
ListCell *item;
|
||||
|
||||
if (stmt->grantor)
|
||||
{
|
||||
check_rolespec_name(stmt->grantor,
|
||||
"Cannot specify reserved role as grantor.");
|
||||
grantor = get_rolespec_oid(stmt->grantor, false);
|
||||
}
|
||||
else
|
||||
grantor = GetUserId();
|
||||
|
||||
foreach(item, stmt->grantee_roles)
|
||||
check_rolespec_name(lfirst(item),
|
||||
"Cannot GRANT roles to a reserved role.");
|
||||
|
||||
grantee_ids = roleSpecsToIds(stmt->grantee_roles);
|
||||
|
||||
/* AccessShareLock is enough since we aren't modifying pg_authid */
|
||||
@ -1318,6 +1364,9 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
|
||||
errmsg("permission denied to reassign objects")));
|
||||
}
|
||||
|
||||
check_rolespec_name(stmt->newrole,
|
||||
"Cannot specify reserved role as owner.");
|
||||
|
||||
/* Must have privileges on the receiving side too */
|
||||
newrole = get_rolespec_oid(stmt->newrole, false);
|
||||
|
||||
|
Reference in New Issue
Block a user