Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Revert commit de0177788b.
authorFujii Masao <fujii@postgresql.org>
Mon, 3 Feb 2020 03:37:59 +0000 (12:37 +0900)
committerFujii Masao <fujii@postgresql.org>
Mon, 3 Feb 2020 03:37:59 +0000 (12:37 +0900)
This commit reverts the fix "Make inherited TRUNCATE perform access
permission checks on parent table only" only in the back branches.

It's not hard to imagine that there are some applications expecting
the old behavior and the fix breaks their security. To avoid this
compatibility problem, we decided to apply the fix only in HEAD and
revert it in all supported back branches.

Discussion: https://postgr.es/m/21015.1580400165@sss.pgh.pa.us

src/backend/commands/tablecmds.c
src/test/regress/expected/privileges.out
src/test/regress/sql/privileges.sql

index c651047711cdd63c7ea5197c0b3cb0e3c207ec08..f3d64c6a9ece9c9f31f0bdc791ca9ff45ac9f036 100644 (file)
@@ -302,7 +302,6 @@ struct DropRelationCallbackState
    ((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
 
 static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
-static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
 static void truncate_check_activity(Relation rel);
 static void RangeVarCallbackForTruncate(const RangeVar *relation,
                                        Oid relId, Oid oldRelId, void *arg);
@@ -1591,12 +1590,6 @@ ExecuteTruncate(TruncateStmt *stmt)
                    continue;
                }
 
-               /*
-                * Inherited TRUNCATE commands perform access
-                * permission checks on the parent table only.
-                * So we skip checking the children's permissions
-                * and don't call truncate_check_perms() here.
-                */
                truncate_check_rel(RelationGetRelid(rel), rel->rd_rel);
                truncate_check_activity(rel);
 
@@ -1683,7 +1676,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
                        (errmsg("truncate cascades to table \"%s\"",
                                RelationGetRelationName(rel))));
                truncate_check_rel(relid, rel->rd_rel);
-               truncate_check_perms(relid, rel->rd_rel);
                truncate_check_activity(rel);
                rels = lappend(rels, rel);
                relids = lappend_oid(relids, relid);
@@ -1934,6 +1926,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
 static void
 truncate_check_rel(Oid relid, Form_pg_class reltuple)
 {
+   AclResult   aclresult;
    char       *relname = NameStr(reltuple->relname);
 
    /*
@@ -1947,27 +1940,17 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple)
                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                 errmsg("\"%s\" is not a table", relname)));
 
-   if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
-       ereport(ERROR,
-               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                errmsg("permission denied: \"%s\" is a system catalog",
-                       relname)));
-}
-
-/*
- * Check that current user has the permission to truncate given relation.
- */
-static void
-truncate_check_perms(Oid relid, Form_pg_class reltuple)
-{
-   char       *relname = NameStr(reltuple->relname);
-   AclResult   aclresult;
-
    /* Permissions checks */
    aclresult = pg_class_aclcheck(relid, GetUserId(), ACL_TRUNCATE);
    if (aclresult != ACLCHECK_OK)
        aclcheck_error(aclresult, get_relkind_objtype(reltuple->relkind),
                       relname);
+
+   if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
+       ereport(ERROR,
+               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                errmsg("permission denied: \"%s\" is a system catalog",
+                       relname)));
 }
 
 /*
@@ -14903,7 +14886,6 @@ RangeVarCallbackForTruncate(const RangeVar *relation,
        elog(ERROR, "cache lookup failed for relation %u", relId);
 
    truncate_check_rel(relId, (Form_pg_class) GETSTRUCT(tuple));
-   truncate_check_perms(relId, (Form_pg_class) GETSTRUCT(tuple));
 
    ReleaseSysCache(tuple);
 }
index bc8e198097e86978be0924ff93fe7efdc6a4be8e..0ddbd8e89fd55809ab4a0ab254a50a50f7ac04f2 100644 (file)
@@ -695,27 +695,6 @@ SELECT tableoid FROM atestp2; -- ok
 ----------
 (0 rows)
 
--- child's permissions do not apply when operating on parent
-SET SESSION AUTHORIZATION regress_priv_user1;
-REVOKE ALL ON atestc FROM regress_priv_user2;
-GRANT ALL ON atestp1 TO regress_priv_user2;
-SET SESSION AUTHORIZATION regress_priv_user2;
-SELECT f2 FROM atestp1; -- ok
- f2 
-----
-(0 rows)
-
-SELECT f2 FROM atestc; -- fail
-ERROR:  permission denied for table atestc
-DELETE FROM atestp1; -- ok
-DELETE FROM atestc; -- fail
-ERROR:  permission denied for table atestc
-UPDATE atestp1 SET f1 = 1; -- ok
-UPDATE atestc SET f1 = 1; -- fail
-ERROR:  permission denied for table atestc
-TRUNCATE atestp1; -- ok
-TRUNCATE atestc; -- fail
-ERROR:  permission denied for table atestc
 -- privileges on functions, languages
 -- switch to superuser
 \c -
index dfe2603fe2ebfc70685d6487a0d5f9a4919c2efd..f15d1f377370bdcb637fb9bb07cd076ff74ef6f2 100644 (file)
@@ -446,20 +446,6 @@ SELECT fy FROM atestp2; -- ok
 SELECT atestp2 FROM atestp2; -- ok
 SELECT tableoid FROM atestp2; -- ok
 
--- child's permissions do not apply when operating on parent
-SET SESSION AUTHORIZATION regress_priv_user1;
-REVOKE ALL ON atestc FROM regress_priv_user2;
-GRANT ALL ON atestp1 TO regress_priv_user2;
-SET SESSION AUTHORIZATION regress_priv_user2;
-SELECT f2 FROM atestp1; -- ok
-SELECT f2 FROM atestc; -- fail
-DELETE FROM atestp1; -- ok
-DELETE FROM atestc; -- fail
-UPDATE atestp1 SET f1 = 1; -- ok
-UPDATE atestc SET f1 = 1; -- fail
-TRUNCATE atestp1; -- ok
-TRUNCATE atestc; -- fail
-
 -- privileges on functions, languages
 
 -- switch to superuser