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

Commit56bc82a

Browse files
committed
Make inherited TRUNCATE perform access permission checks on parent table only.
Previously, TRUNCATE command through a parent table checked thepermissions on not only the parent table but also the children tablesinherited from it. This was a bug and inherited queries should performaccess permission checks on the parent table only. This commit fixesthat bug.Back-patch to all supported branches.Author: Amit LangoteReviewed-by: Fujii MasaoDiscussion:https://postgr.es/m/CAHGQGwFHdSvifhJE+-GSNqUHSfbiKxaeQQ7HGcYz6SC2n_oDcg@mail.gmail.com
1 parent8fc33e6 commit56bc82a

File tree

3 files changed

+84
-18
lines changed

3 files changed

+84
-18
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ struct DropRelationCallbackState
262262
#defineATT_COMPOSITE_TYPE0x0010
263263
#defineATT_FOREIGN_TABLE0x0020
264264

265-
staticvoidtruncate_check_rel(Relationrel);
265+
staticvoidtruncate_check_rel(Oidrelid,Form_pg_classreltuple);
266+
staticvoidtruncate_check_perms(Oidrelid,Form_pg_classreltuple);
267+
staticvoidtruncate_check_activity(Relationrel);
266268
staticList*MergeAttributes(List*schema,List*supers,charrelpersistence,
267269
List**supOids,List**supconstr,int*supOidCount);
268270
staticboolMergeCheckConstraint(List*constraints,char*name,Node*expr);
@@ -1018,7 +1020,11 @@ ExecuteTruncate(TruncateStmt *stmt)
10181020
heap_close(rel,lockmode);
10191021
continue;
10201022
}
1021-
truncate_check_rel(rel);
1023+
1024+
truncate_check_rel(myrelid,rel->rd_rel);
1025+
truncate_check_perms(myrelid,rel->rd_rel);
1026+
truncate_check_activity(rel);
1027+
10221028
rels=lappend(rels,rel);
10231029
relids=lappend_oid(relids,myrelid);
10241030

@@ -1054,7 +1060,15 @@ ExecuteTruncate(TruncateStmt *stmt)
10541060
continue;
10551061
}
10561062

1057-
truncate_check_rel(rel);
1063+
/*
1064+
* Inherited TRUNCATE commands perform access
1065+
* permission checks on the parent table only.
1066+
* So we skip checking the children's permissions
1067+
* and don't call truncate_check_perms() here.
1068+
*/
1069+
truncate_check_rel(RelationGetRelid(rel),rel->rd_rel);
1070+
truncate_check_activity(rel);
1071+
10581072
rels=lappend(rels,rel);
10591073
relids=lappend_oid(relids,childrelid);
10601074
}
@@ -1088,7 +1102,9 @@ ExecuteTruncate(TruncateStmt *stmt)
10881102
ereport(NOTICE,
10891103
(errmsg("truncate cascades to table \"%s\"",
10901104
RelationGetRelationName(rel))));
1091-
truncate_check_rel(rel);
1105+
truncate_check_rel(relid,rel->rd_rel);
1106+
truncate_check_perms(relid,rel->rd_rel);
1107+
truncate_check_activity(rel);
10921108
rels=lappend(rels,rel);
10931109
relids=lappend_oid(relids,relid);
10941110
}
@@ -1289,30 +1305,45 @@ ExecuteTruncate(TruncateStmt *stmt)
12891305
* Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate
12901306
*/
12911307
staticvoid
1292-
truncate_check_rel(Relationrel)
1308+
truncate_check_rel(Oidrelid,Form_pg_classreltuple)
12931309
{
1294-
AclResultaclresult;
1310+
char*relname=NameStr(reltuple->relname);
12951311

12961312
/* Only allow truncate on regular tables */
1297-
if (rel->rd_rel->relkind!=RELKIND_RELATION)
1313+
if (reltuple->relkind!=RELKIND_RELATION)
12981314
ereport(ERROR,
12991315
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1300-
errmsg("\"%s\" is not a table",
1301-
RelationGetRelationName(rel))));
1316+
errmsg("\"%s\" is not a table",relname)));
13021317

1303-
/* Permissions checks */
1304-
aclresult=pg_class_aclcheck(RelationGetRelid(rel),GetUserId(),
1305-
ACL_TRUNCATE);
1306-
if (aclresult!=ACLCHECK_OK)
1307-
aclcheck_error(aclresult,ACL_KIND_CLASS,
1308-
RelationGetRelationName(rel));
1309-
1310-
if (!allowSystemTableMods&&IsSystemRelation(rel))
1318+
if (!allowSystemTableMods&&IsSystemClass(relid,reltuple))
13111319
ereport(ERROR,
13121320
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
13131321
errmsg("permission denied: \"%s\" is a system catalog",
1314-
RelationGetRelationName(rel))));
1322+
relname)));
1323+
}
13151324

1325+
/*
1326+
* Check that current user has the permission to truncate given relation.
1327+
*/
1328+
staticvoid
1329+
truncate_check_perms(Oidrelid,Form_pg_classreltuple)
1330+
{
1331+
char*relname=NameStr(reltuple->relname);
1332+
AclResultaclresult;
1333+
1334+
/* Permissions checks */
1335+
aclresult=pg_class_aclcheck(relid,GetUserId(),ACL_TRUNCATE);
1336+
if (aclresult!=ACLCHECK_OK)
1337+
aclcheck_error(aclresult,ACL_KIND_CLASS,relname);
1338+
}
1339+
1340+
/*
1341+
* Set of extra sanity checks to check if a given relation is safe to
1342+
* truncate.
1343+
*/
1344+
staticvoid
1345+
truncate_check_activity(Relationrel)
1346+
{
13161347
/*
13171348
* Don't allow truncate on temp tables of other backends ... their local
13181349
* buffer manager is not going to cope.

‎src/test/regress/expected/privileges.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,27 @@ SELECT oid FROM atestp2; -- ok
656656
-----
657657
(0 rows)
658658

659+
-- child's permissions do not apply when operating on parent
660+
SET SESSION AUTHORIZATION regressuser1;
661+
REVOKE ALL ON atestc FROM regressuser2;
662+
GRANT ALL ON atestp1 TO regressuser2;
663+
SET SESSION AUTHORIZATION regressuser2;
664+
SELECT f2 FROM atestp1; -- ok
665+
f2
666+
----
667+
(0 rows)
668+
669+
SELECT f2 FROM atestc; -- fail
670+
ERROR: permission denied for relation atestc
671+
DELETE FROM atestp1; -- ok
672+
DELETE FROM atestc; -- fail
673+
ERROR: permission denied for relation atestc
674+
UPDATE atestp1 SET f1 = 1; -- ok
675+
UPDATE atestc SET f1 = 1; -- fail
676+
ERROR: permission denied for relation atestc
677+
TRUNCATE atestp1; -- ok
678+
TRUNCATE atestc; -- fail
679+
ERROR: permission denied for relation atestc
659680
-- privileges on functions, languages
660681
-- switch to superuser
661682
\c -

‎src/test/regress/sql/privileges.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,20 @@ SELECT fy FROM atestp2; -- ok
414414
SELECT atestp2FROM atestp2;-- ok
415415
SELECToidFROM atestp2;-- ok
416416

417+
-- child's permissions do not apply when operating on parent
418+
SET SESSION AUTHORIZATION regressuser1;
419+
REVOKE ALLON atestcFROM regressuser2;
420+
GRANT ALLON atestp1 TO regressuser2;
421+
SET SESSION AUTHORIZATION regressuser2;
422+
SELECT f2FROM atestp1;-- ok
423+
SELECT f2FROM atestc;-- fail
424+
DELETEFROM atestp1;-- ok
425+
DELETEFROM atestc;-- fail
426+
UPDATE atestp1SET f1=1;-- ok
427+
UPDATE atestcSET f1=1;-- fail
428+
TRUNCATE atestp1;-- ok
429+
TRUNCATE atestc;-- fail
430+
417431
-- privileges on functions, languages
418432

419433
-- switch to superuser

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp