diff options
| author | Stephen Frost | 2016-04-08 20:56:27 +0000 |
|---|---|---|
| committer | Stephen Frost | 2016-04-08 20:56:27 +0000 |
| commit | 293007898d3fa5a815c1c5814df53627553f114d (patch) | |
| tree | 462f41b12ee37a4f0de5b6707bd49b734cb24668 /src/backend/commands/user.c | |
| parent | fa6075e5515c6878b2c1fe1c6435dd7ed847857d (diff) | |
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
Diffstat (limited to 'src/backend/commands/user.c')
| -rw-r--r-- | src/backend/commands/user.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 4baeaa2676e..cc3d5645343 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -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" @@ -312,6 +313,17 @@ CreateRole(CreateRoleStmt *stmt) } /* + * 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); |
