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

Commit4b96c03

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 parent603e03b commit4b96c03

File tree

3 files changed

+85
-19
lines changed

3 files changed

+85
-19
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,9 @@ struct DropRelationCallbackState
291291
#definechild_dependency_type(child_is_partition)\
292292
((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
293293

294-
staticvoidtruncate_check_rel(Relationrel);
294+
staticvoidtruncate_check_rel(Oidrelid,Form_pg_classreltuple);
295+
staticvoidtruncate_check_perms(Oidrelid,Form_pg_classreltuple);
296+
staticvoidtruncate_check_activity(Relationrel);
295297
staticList*MergeAttributes(List*schema,List*supers,charrelpersistence,
296298
boolis_partition,List**supOids,List**supconstr,
297299
int*supOidCount);
@@ -1242,7 +1244,11 @@ ExecuteTruncate(TruncateStmt *stmt)
12421244
heap_close(rel,lockmode);
12431245
continue;
12441246
}
1245-
truncate_check_rel(rel);
1247+
1248+
truncate_check_rel(myrelid,rel->rd_rel);
1249+
truncate_check_perms(myrelid,rel->rd_rel);
1250+
truncate_check_activity(rel);
1251+
12461252
rels=lappend(rels,rel);
12471253
relids=lappend_oid(relids,myrelid);
12481254

@@ -1278,7 +1284,15 @@ ExecuteTruncate(TruncateStmt *stmt)
12781284
continue;
12791285
}
12801286

1281-
truncate_check_rel(rel);
1287+
/*
1288+
* Inherited TRUNCATE commands perform access
1289+
* permission checks on the parent table only.
1290+
* So we skip checking the children's permissions
1291+
* and don't call truncate_check_perms() here.
1292+
*/
1293+
truncate_check_rel(RelationGetRelid(rel),rel->rd_rel);
1294+
truncate_check_activity(rel);
1295+
12821296
rels=lappend(rels,rel);
12831297
relids=lappend_oid(relids,childrelid);
12841298
}
@@ -1317,7 +1331,9 @@ ExecuteTruncate(TruncateStmt *stmt)
13171331
ereport(NOTICE,
13181332
(errmsg("truncate cascades to table \"%s\"",
13191333
RelationGetRelationName(rel))));
1320-
truncate_check_rel(rel);
1334+
truncate_check_rel(relid,rel->rd_rel);
1335+
truncate_check_perms(relid,rel->rd_rel);
1336+
truncate_check_activity(rel);
13211337
rels=lappend(rels,rel);
13221338
relids=lappend_oid(relids,relid);
13231339
}
@@ -1530,35 +1546,50 @@ ExecuteTruncate(TruncateStmt *stmt)
15301546
* Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate
15311547
*/
15321548
staticvoid
1533-
truncate_check_rel(Relationrel)
1549+
truncate_check_rel(Oidrelid,Form_pg_classreltuple)
15341550
{
1535-
AclResultaclresult;
1551+
char*relname=NameStr(reltuple->relname);
15361552

15371553
/*
15381554
* Only allow truncate on regular tables and partitioned tables (although,
15391555
* the latter are only being included here for the following checks; no
15401556
* physical truncation will occur in their case.)
15411557
*/
1542-
if (rel->rd_rel->relkind!=RELKIND_RELATION&&
1543-
rel->rd_rel->relkind!=RELKIND_PARTITIONED_TABLE)
1558+
if (reltuple->relkind!=RELKIND_RELATION&&
1559+
reltuple->relkind!=RELKIND_PARTITIONED_TABLE)
15441560
ereport(ERROR,
15451561
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1546-
errmsg("\"%s\" is not a table",
1547-
RelationGetRelationName(rel))));
1548-
1549-
/* Permissions checks */
1550-
aclresult=pg_class_aclcheck(RelationGetRelid(rel),GetUserId(),
1551-
ACL_TRUNCATE);
1552-
if (aclresult!=ACLCHECK_OK)
1553-
aclcheck_error(aclresult,ACL_KIND_CLASS,
1554-
RelationGetRelationName(rel));
1562+
errmsg("\"%s\" is not a table",relname)));
15551563

1556-
if (!allowSystemTableMods&&IsSystemRelation(rel))
1564+
if (!allowSystemTableMods&&IsSystemClass(relid,reltuple))
15571565
ereport(ERROR,
15581566
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
15591567
errmsg("permission denied: \"%s\" is a system catalog",
1560-
RelationGetRelationName(rel))));
1568+
relname)));
1569+
}
1570+
1571+
/*
1572+
* Check that current user has the permission to truncate given relation.
1573+
*/
1574+
staticvoid
1575+
truncate_check_perms(Oidrelid,Form_pg_classreltuple)
1576+
{
1577+
char*relname=NameStr(reltuple->relname);
1578+
AclResultaclresult;
15611579

1580+
/* Permissions checks */
1581+
aclresult=pg_class_aclcheck(relid,GetUserId(),ACL_TRUNCATE);
1582+
if (aclresult!=ACLCHECK_OK)
1583+
aclcheck_error(aclresult,ACL_KIND_CLASS,relname);
1584+
}
1585+
1586+
/*
1587+
* Set of extra sanity checks to check if a given relation is safe to
1588+
* truncate.
1589+
*/
1590+
staticvoid
1591+
truncate_check_activity(Relationrel)
1592+
{
15621593
/*
15631594
* Don't allow truncate on temp tables of other backends ... their local
15641595
* 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
@@ -695,6 +695,27 @@ SELECT oid FROM atestp2; -- ok
695695
-----
696696
(0 rows)
697697

698+
-- child's permissions do not apply when operating on parent
699+
SET SESSION AUTHORIZATION regress_user1;
700+
REVOKE ALL ON atestc FROM regress_user2;
701+
GRANT ALL ON atestp1 TO regress_user2;
702+
SET SESSION AUTHORIZATION regress_user2;
703+
SELECT f2 FROM atestp1; -- ok
704+
f2
705+
----
706+
(0 rows)
707+
708+
SELECT f2 FROM atestc; -- fail
709+
ERROR: permission denied for relation atestc
710+
DELETE FROM atestp1; -- ok
711+
DELETE FROM atestc; -- fail
712+
ERROR: permission denied for relation atestc
713+
UPDATE atestp1 SET f1 = 1; -- ok
714+
UPDATE atestc SET f1 = 1; -- fail
715+
ERROR: permission denied for relation atestc
716+
TRUNCATE atestp1; -- ok
717+
TRUNCATE atestc; -- fail
718+
ERROR: permission denied for relation atestc
698719
-- privileges on functions, languages
699720
-- switch to superuser
700721
\c -

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,20 @@ SELECT fy FROM atestp2; -- ok
446446
SELECT atestp2FROM atestp2;-- ok
447447
SELECToidFROM atestp2;-- ok
448448

449+
-- child's permissions do not apply when operating on parent
450+
SET SESSION AUTHORIZATION regress_user1;
451+
REVOKE ALLON atestcFROM regress_user2;
452+
GRANT ALLON atestp1 TO regress_user2;
453+
SET SESSION AUTHORIZATION regress_user2;
454+
SELECT f2FROM atestp1;-- ok
455+
SELECT f2FROM atestc;-- fail
456+
DELETEFROM atestp1;-- ok
457+
DELETEFROM atestc;-- fail
458+
UPDATE atestp1SET f1=1;-- ok
459+
UPDATE atestcSET f1=1;-- fail
460+
TRUNCATE atestp1;-- ok
461+
TRUNCATE atestc;-- fail
462+
449463
-- privileges on functions, languages
450464

451465
-- switch to superuser

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp