Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2930078

Browse files
committed
Reserve the "pg_" namespace for roles
This will prevent users from creating roles which begin with "pg_" andwill 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
1 parentfa6075e commit2930078

File tree

21 files changed

+226
-13
lines changed

21 files changed

+226
-13
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,13 +1365,15 @@ testdb=>
13651365

13661366

13671367
<varlistentry>
1368-
<term><literal>\dg[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
1368+
<term><literal>\dg[S+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
13691369
<listitem>
13701370
<para>
13711371
Lists database roles.
13721372
(Since the concepts of <quote>users</> and <quote>groups</> have been
13731373
unified into <quote>roles</>, this command is now equivalent to
13741374
<literal>\du</literal>.)
1375+
By default, only user-created roles are shown; supply the
1376+
<literal>S</literal> modifier to include system roles.
13751377
If <replaceable class="parameter">pattern</replaceable> is specified,
13761378
only those roles whose names match the pattern are listed.
13771379
If the form <literal>\dg+</literal> is used, additional information
@@ -1525,13 +1527,15 @@ testdb=&gt;
15251527
</varlistentry>
15261528

15271529
<varlistentry>
1528-
<term><literal>\du[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
1530+
<term><literal>\du[S+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
15291531
<listitem>
15301532
<para>
15311533
Lists database roles.
15321534
(Since the concepts of <quote>users</> and <quote>groups</> have been
15331535
unified into <quote>roles</>, this command is now equivalent to
15341536
<literal>\dg</literal>.)
1537+
By default, only user-created roles are shown; supply the
1538+
<literal>S</literal> modifier to include system roles.
15351539
If <replaceable class="parameter">pattern</replaceable> is specified,
15361540
only those roles whose names match the pattern are listed.
15371541
If the form <literal>\du+</literal> is used, additional information

‎src/backend/catalog/aclchk.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ ExecuteGrantStmt(GrantStmt *stmt)
423423
grantee_uid=ACL_ID_PUBLIC;
424424
break;
425425
default:
426+
if (!IsBootstrapProcessingMode())
427+
check_rolespec_name((Node*)grantee,
428+
"Cannot GRANT or REVOKE privileges to or from a reserved role.");
426429
grantee_uid=get_rolespec_oid((Node*)grantee, false);
427430
break;
428431
}
@@ -918,6 +921,8 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
918921
grantee_uid=ACL_ID_PUBLIC;
919922
break;
920923
default:
924+
check_rolespec_name((Node*)grantee,
925+
"Cannot GRANT or REVOKE default privileges to or from a reserved role.");
921926
grantee_uid=get_rolespec_oid((Node*)grantee, false);
922927
break;
923928
}
@@ -1008,6 +1013,8 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
10081013
{
10091014
RoleSpec*rolespec=lfirst(rolecell);
10101015

1016+
check_rolespec_name((Node*)rolespec,
1017+
"Cannot alter default privileges for reserved role.");
10111018
iacls.roleid=get_rolespec_oid((Node*)rolespec, false);
10121019

10131020
/*

‎src/backend/catalog/catalog.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,9 @@ IsToastNamespace(Oid namespaceId)
184184
*True iff name starts with the pg_ prefix.
185185
*
186186
*For some classes of objects, the prefix pg_ is reserved for
187-
*system objects only. As of 8.0, this is only true for
188-
*schema and tablespace names.
187+
*system objects only. As of 8.0, this was only true for
188+
*schema and tablespace names. With 9.6, this is also true
189+
*for roles.
189190
*/
190191
bool
191192
IsReservedName(constchar*name)

‎src/backend/commands/alter.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,9 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
747747
{
748748
Oidnewowner=get_rolespec_oid(stmt->newowner, false);
749749

750+
check_rolespec_name(stmt->newowner,
751+
"Cannot make reserved roles owners of objects.");
752+
750753
switch (stmt->objectType)
751754
{
752755
caseOBJECT_DATABASE:

‎src/backend/commands/foreigncmds.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,10 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
11481148
else
11491149
useId=get_rolespec_oid(stmt->user, false);
11501150

1151+
/* Additional check to protect reserved role names */
1152+
check_rolespec_name(stmt->user,
1153+
"Cannot specify reserved role as mapping user.");
1154+
11511155
/* Check that the server exists. */
11521156
srv=GetForeignServerByName(stmt->servername, false);
11531157

@@ -1248,6 +1252,10 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
12481252
else
12491253
useId=get_rolespec_oid(stmt->user, false);
12501254

1255+
/* Additional check to protect reserved role names */
1256+
check_rolespec_name(stmt->user,
1257+
"Cannot alter reserved role mapping user.");
1258+
12511259
srv=GetForeignServerByName(stmt->servername, false);
12521260

12531261
umId=GetSysCacheOid2(USERMAPPINGUSERSERVER,
@@ -1337,6 +1345,11 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
13371345
else
13381346
{
13391347
useId=get_rolespec_oid(stmt->user,stmt->missing_ok);
1348+
1349+
/* Additional check to protect reserved role names */
1350+
check_rolespec_name(stmt->user,
1351+
"Cannot remove reserved role mapping user.");
1352+
13401353
if (!OidIsValid(useId))
13411354
{
13421355
/*

‎src/backend/commands/policy.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,13 @@ policy_role_list_to_array(List *roles, int *num_roles)
176176
returnrole_oids;
177177
}
178178
else
179+
{
180+
/* Additional check to protect reserved role names */
181+
check_rolespec_name((Node*)spec,
182+
"Cannot specify reserved role as policy target");
179183
role_oids[i++]=
180184
ObjectIdGetDatum(get_rolespec_oid((Node*)spec, false));
185+
}
181186
}
182187

183188
returnrole_oids;

‎src/backend/commands/schemacmds.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
6565
else
6666
owner_uid=saved_uid;
6767

68+
/* Additional check to protect reserved role names */
69+
check_rolespec_name(stmt->authrole,
70+
"Cannot specify reserved role as owner.");
71+
6872
/* fill schema name with the user name if not specified */
6973
if (!schemaName)
7074
{

‎src/backend/commands/tablecmds.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,6 +3566,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
35663566
(List*)cmd->def,lockmode);
35673567
break;
35683568
caseAT_ChangeOwner:/* ALTER OWNER */
3569+
check_rolespec_name(cmd->newowner,
3570+
"Cannot specify reserved role as owner.");
35693571
ATExecChangeOwner(RelationGetRelid(rel),
35703572
get_rolespec_oid(cmd->newowner, false),
35713573
false,lockmode);

‎src/backend/commands/tablespace.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
256256
else
257257
ownerId=GetUserId();
258258

259+
/* Additional check to protect reserved role names */
260+
check_rolespec_name(stmt->owner,
261+
"Cannot specify reserved role as owner.");
262+
259263
/* Unix-ify the offered path, and strip any trailing slashes */
260264
location=pstrdup(stmt->location);
261265
canonicalize_path(location);

‎src/backend/commands/user.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
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
Oidroleid;
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
inti;
11181136
Oidroleid;
11191137
ObjectAddressaddress;
1138+
Form_pg_authidauthform;
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

‎src/backend/commands/variable.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,9 @@ check_role(char **newval, void **extra, GucSource source)
854854
roleid=InvalidOid;
855855
is_superuser= false;
856856
}
857+
/* Do not allow setting role to a reserved role. */
858+
elseif (strncmp(*newval,"pg_",3)==0)
859+
return false;
857860
else
858861
{
859862
if (!IsTransactionState())

‎src/backend/utils/adt/acl.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include<ctype.h>
1818

1919
#include"access/htup_details.h"
20+
#include"catalog/catalog.h"
2021
#include"catalog/namespace.h"
2122
#include"catalog/pg_authid.h"
2223
#include"catalog/pg_auth_members.h"
@@ -5247,3 +5248,41 @@ get_rolespec_name(const Node *node)
52475248

52485249
returnrolename;
52495250
}
5251+
5252+
/*
5253+
* Given a RoleSpec, throw an error if the name is reserved, using detail_msg,
5254+
* if provided.
5255+
*
5256+
* If node is NULL, no error is thrown. If detail_msg is NULL then no detail
5257+
* message is provided.
5258+
*/
5259+
void
5260+
check_rolespec_name(constNode*node,constchar*detail_msg)
5261+
{
5262+
RoleSpec*role;
5263+
5264+
if (!node)
5265+
return;
5266+
5267+
role= (RoleSpec*)node;
5268+
5269+
Assert(IsA(node,RoleSpec));
5270+
5271+
if (role->roletype!=ROLESPEC_CSTRING)
5272+
return;
5273+
5274+
if (IsReservedName(role->rolename))
5275+
{
5276+
if (detail_msg)
5277+
ereport(ERROR,
5278+
(errcode(ERRCODE_RESERVED_NAME),
5279+
errmsg("role \"%s\" is reserved",
5280+
role->rolename),
5281+
errdetail("%s",detail_msg)));
5282+
else
5283+
ereport(ERROR,
5284+
(errcode(ERRCODE_RESERVED_NAME),
5285+
errmsg("role \"%s\" is reserved",
5286+
role->rolename)));
5287+
}
5288+
}

‎src/bin/pg_dump/pg_dumpall.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ dumpRoles(PGconn *conn)
665665
inti;
666666

667667
/* note: rolconfig is dumped later */
668-
if (server_version >=90500)
668+
if (server_version >=90600)
669669
printfPQExpBuffer(buf,
670670
"SELECT oid, rolname, rolsuper, rolinherit, "
671671
"rolcreaterole, rolcreatedb, "
@@ -674,6 +674,7 @@ dumpRoles(PGconn *conn)
674674
"pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
675675
"rolname = current_user AS is_current_user "
676676
"FROM pg_authid "
677+
"WHERE rolname !~ '^pg_' "
677678
"ORDER BY 2");
678679
elseif (server_version >=90100)
679680
printfPQExpBuffer(buf,
@@ -771,6 +772,13 @@ dumpRoles(PGconn *conn)
771772
auth_oid=atooid(PQgetvalue(res,i,i_oid));
772773
rolename=PQgetvalue(res,i,i_rolname);
773774

775+
if (strncmp(rolename,"pg_",3)==0)
776+
{
777+
fprintf(stderr,_("%s: role name starting with 'pg_' skipped (%s)\n"),
778+
progname,rolename);
779+
continue;
780+
}
781+
774782
resetPQExpBuffer(buf);
775783

776784
if (binary_upgrade)
@@ -896,6 +904,7 @@ dumpRoleMembership(PGconn *conn)
896904
"LEFT JOIN pg_authid ur on ur.oid = a.roleid "
897905
"LEFT JOIN pg_authid um on um.oid = a.member "
898906
"LEFT JOIN pg_authid ug on ug.oid = a.grantor "
907+
"WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
899908
"ORDER BY 1,2,3");
900909

901910
if (PQntuples(res)>0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp