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

Commite6f1e56

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 parentb0afdca commite6f1e56

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ struct DropRelationCallbackState
304304
((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
305305

306306
static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
307+
static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
307308
static void truncate_check_activity(Relation rel);
308309
static void RangeVarCallbackForTruncate(const RangeVar *relation,
309310
Oid relId, Oid oldRelId, void *arg);
@@ -1615,6 +1616,12 @@ ExecuteTruncate(TruncateStmt *stmt)
16151616
continue;
16161617
}
16171618

1619+
/*
1620+
* Inherited TRUNCATE commands perform access
1621+
* permission checks on the parent table only.
1622+
* So we skip checking the children's permissions
1623+
* and don't call truncate_check_perms() here.
1624+
*/
16181625
truncate_check_rel(RelationGetRelid(rel), rel->rd_rel);
16191626
truncate_check_activity(rel);
16201627

@@ -1701,6 +1708,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
17011708
(errmsg("truncate cascades to table \"%s\"",
17021709
RelationGetRelationName(rel))));
17031710
truncate_check_rel(relid, rel->rd_rel);
1711+
truncate_check_perms(relid, rel->rd_rel);
17041712
truncate_check_activity(rel);
17051713
rels = lappend(rels, rel);
17061714
relids = lappend_oid(relids, relid);
@@ -1951,7 +1959,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
19511959
static void
19521960
truncate_check_rel(Oid relid, Form_pg_class reltuple)
19531961
{
1954-
AclResultaclresult;
19551962
char *relname = NameStr(reltuple->relname);
19561963

19571964
/*
@@ -1965,12 +1972,6 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple)
19651972
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
19661973
errmsg("\"%s\" is not a table", relname)));
19671974

1968-
/* Permissions checks */
1969-
aclresult = pg_class_aclcheck(relid, GetUserId(), ACL_TRUNCATE);
1970-
if (aclresult != ACLCHECK_OK)
1971-
aclcheck_error(aclresult, get_relkind_objtype(reltuple->relkind),
1972-
relname);
1973-
19741975
if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
19751976
ereport(ERROR,
19761977
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -1980,6 +1981,22 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple)
19801981
InvokeObjectTruncateHook(relid);
19811982
}
19821983

1984+
/*
1985+
* Check that current user has the permission to truncate given relation.
1986+
*/
1987+
static void
1988+
truncate_check_perms(Oid relid, Form_pg_class reltuple)
1989+
{
1990+
char *relname = NameStr(reltuple->relname);
1991+
AclResultaclresult;
1992+
1993+
/* Permissions checks */
1994+
aclresult = pg_class_aclcheck(relid, GetUserId(), ACL_TRUNCATE);
1995+
if (aclresult != ACLCHECK_OK)
1996+
aclcheck_error(aclresult, get_relkind_objtype(reltuple->relkind),
1997+
relname);
1998+
}
1999+
19832000
/*
19842001
* Set of extra sanity checks to check if a given relation is safe to
19852002
* truncate. This is split with truncate_check_rel() as
@@ -15292,6 +15309,7 @@ RangeVarCallbackForTruncate(const RangeVar *relation,
1529215309
elog(ERROR, "cache lookup failed for relation %u", relId);
1529315310

1529415311
truncate_check_rel(relId, (Form_pg_class) GETSTRUCT(tuple));
15312+
truncate_check_perms(relId, (Form_pg_class) GETSTRUCT(tuple));
1529515313

1529615314
ReleaseSysCache(tuple);
1529715315
}

‎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 tableoid FROM atestp2; -- ok
695695
----------
696696
(0 rows)
697697

698+
-- child's permissions do not apply when operating on parent
699+
SET SESSION AUTHORIZATION regress_priv_user1;
700+
REVOKE ALL ON atestc FROM regress_priv_user2;
701+
GRANT ALL ON atestp1 TO regress_priv_user2;
702+
SET SESSION AUTHORIZATION regress_priv_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 table atestc
710+
DELETE FROM atestp1; -- ok
711+
DELETE FROM atestc; -- fail
712+
ERROR: permission denied for table atestc
713+
UPDATE atestp1 SET f1 = 1; -- ok
714+
UPDATE atestc SET f1 = 1; -- fail
715+
ERROR: permission denied for table atestc
716+
TRUNCATE atestp1; -- ok
717+
TRUNCATE atestc; -- fail
718+
ERROR: permission denied for table 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
SELECT tableoidFROM atestp2;-- ok
448448

449+
-- child's permissions do not apply when operating on parent
450+
SET SESSION AUTHORIZATION regress_priv_user1;
451+
REVOKE ALLON atestcFROM regress_priv_user2;
452+
GRANT ALLON atestp1 TO regress_priv_user2;
453+
SET SESSION AUTHORIZATION regress_priv_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