1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-09 13:09:39 +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:
Stephen Frost
2016-04-08 16:56:27 -04:00
parent fa6075e551
commit 293007898d
21 changed files with 226 additions and 13 deletions

View File

@@ -747,6 +747,9 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
Oid newowner = get_rolespec_oid(stmt->newowner, false);
check_rolespec_name(stmt->newowner,
"Cannot make reserved roles owners of objects.");
switch (stmt->objectType)
{
case OBJECT_DATABASE:

View File

@@ -1148,6 +1148,10 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
else
useId = get_rolespec_oid(stmt->user, false);
/* Additional check to protect reserved role names */
check_rolespec_name(stmt->user,
"Cannot specify reserved role as mapping user.");
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
@@ -1248,6 +1252,10 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
else
useId = get_rolespec_oid(stmt->user, false);
/* Additional check to protect reserved role names */
check_rolespec_name(stmt->user,
"Cannot alter reserved role mapping user.");
srv = GetForeignServerByName(stmt->servername, false);
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
@@ -1337,6 +1345,11 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
else
{
useId = get_rolespec_oid(stmt->user, stmt->missing_ok);
/* Additional check to protect reserved role names */
check_rolespec_name(stmt->user,
"Cannot remove reserved role mapping user.");
if (!OidIsValid(useId))
{
/*

View File

@@ -176,8 +176,13 @@ policy_role_list_to_array(List *roles, int *num_roles)
return role_oids;
}
else
{
/* Additional check to protect reserved role names */
check_rolespec_name((Node *) spec,
"Cannot specify reserved role as policy target");
role_oids[i++] =
ObjectIdGetDatum(get_rolespec_oid((Node *) spec, false));
}
}
return role_oids;

View File

@@ -65,6 +65,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
else
owner_uid = saved_uid;
/* Additional check to protect reserved role names */
check_rolespec_name(stmt->authrole,
"Cannot specify reserved role as owner.");
/* fill schema name with the user name if not specified */
if (!schemaName)
{

View File

@@ -3566,6 +3566,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
(List *) cmd->def, lockmode);
break;
case AT_ChangeOwner: /* ALTER OWNER */
check_rolespec_name(cmd->newowner,
"Cannot specify reserved role as owner.");
ATExecChangeOwner(RelationGetRelid(rel),
get_rolespec_oid(cmd->newowner, false),
false, lockmode);

View File

@@ -256,6 +256,10 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
else
ownerId = GetUserId();
/* Additional check to protect reserved role names */
check_rolespec_name(stmt->owner,
"Cannot specify reserved role as owner.");
/* Unix-ify the offered path, and strip any trailing slashes */
location = pstrdup(stmt->location);
canonicalize_path(location);

View File

@@ -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);

View File

@@ -854,6 +854,9 @@ check_role(char **newval, void **extra, GucSource source)
roleid = InvalidOid;
is_superuser = false;
}
/* Do not allow setting role to a reserved role. */
else if (strncmp(*newval, "pg_", 3) == 0)
return false;
else
{
if (!IsTransactionState())