diff --git a/.unreleased/pr_6439 b/.unreleased/pr_6439 new file mode 100644 index 000000000..7e377d8d5 --- /dev/null +++ b/.unreleased/pr_6439 @@ -0,0 +1,3 @@ +Fixes: #6439 Fix compressed chunk permission handling on PG16 + +Thanks: @adriangb for reporting an issue with security barrier views on pg16 diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c index a8aa8662b..326c2a92b 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c @@ -1642,6 +1642,20 @@ decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, Chunk root->simple_rel_array[compressed_index] = NULL; RelOptInfo *compressed_rel = build_simple_rel(root, compressed_index, NULL); + +#if PG16_GE + /* + * When initially creating the RTE we add a RTEPerminfo entry for the + * RTE but that is only to make build_simple_rel happy. + * Asserts in the permission check code will fail with an RTEPerminfo + * with no permissions to check so we remove it again here as we don't + * want permission checks on the compressed chunks when querying + * hypertables with compressed data. + */ + root->parse->rteperminfos = list_delete_last(root->parse->rteperminfos); + info->compressed_rte->perminfoindex = 0; +#endif + /* github issue :1558 * set up top_parent_relids for this rel as the same as the * original hypertable, otherwise eq classes are not computed correctly @@ -1858,9 +1872,8 @@ decompress_chunk_make_rte(Oid compressed_relid, LOCKMODE lockmode, Query *parse) rte->insertedCols = NULL; rte->updatedCols = NULL; #else - /* add perminfo for the new RTE */ - RTEPermissionInfo *perminfo = addRTEPermissionInfo(&parse->rteperminfos, rte); - perminfo->requiredPerms |= ACL_SELECT; + /* Add empty perminfo for the new RTE to make build_simple_rel happy. */ + addRTEPermissionInfo(&parse->rteperminfos, rte); #endif return rte; diff --git a/tsl/test/shared/expected/security_barrier.out b/tsl/test/shared/expected/security_barrier.out new file mode 100644 index 000000000..67c0aaab7 --- /dev/null +++ b/tsl/test/shared/expected/security_barrier.out @@ -0,0 +1,56 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +\c :TEST_DBNAME :ROLE_SUPERUSER +CREATE TABLE test_security_barrier (time TIMESTAMPTZ NOT NULL, tenant TEXT NOT NULL, data TEXT); +SELECT FROM create_hypertable('test_security_barrier', by_range('time')); +(1 row) + +INSERT INTO test_security_barrier(time, tenant, data) VALUES +('2020-01-01', :'ROLE_DEFAULT_PERM_USER','data1'), +('2020-01-01', :'ROLE_DEFAULT_PERM_USER_2','data2'); +CREATE VIEW test_security_barrier_view WITH (security_barrier) AS SELECT * FROM test_security_barrier WHERE tenant = current_user; +GRANT SELECT ON test_security_barrier_view TO :ROLE_DEFAULT_PERM_USER; +GRANT SELECT ON test_security_barrier_view TO :ROLE_DEFAULT_PERM_USER_2; +SET ROLE :ROLE_DEFAULT_PERM_USER; +SELECT * FROM test_security_barrier_view; + time | tenant | data +------------------------------+-------------------+------- + Wed Jan 01 00:00:00 2020 PST | default_perm_user | data1 +(1 row) + +RESET ROLE; +SET ROLE :ROLE_DEFAULT_PERM_USER_2; +SELECT * FROM test_security_barrier_view; + time | tenant | data +------------------------------+---------------------+------- + Wed Jan 01 00:00:00 2020 PST | default_perm_user_2 | data2 +(1 row) + +RESET ROLE; +ALTER TABLE test_security_barrier SET (timescaledb.compress); +-- Compress the chunk +SELECT compress_chunk(show_chunks('test_security_barrier')) IS NOT NULL AS compressed; + compressed + t +(1 row) + +SET ROLE :ROLE_DEFAULT_PERM_USER; +SELECT * FROM test_security_barrier_view; + time | tenant | data +------------------------------+-------------------+------- + Wed Jan 01 00:00:00 2020 PST | default_perm_user | data1 +(1 row) + +RESET ROLE; +SET ROLE :ROLE_DEFAULT_PERM_USER_2; +SELECT * FROM test_security_barrier_view; + time | tenant | data +------------------------------+---------------------+------- + Wed Jan 01 00:00:00 2020 PST | default_perm_user_2 | data2 +(1 row) + +RESET ROLE; +DROP TABLE test_security_barrier CASCADE; +NOTICE: drop cascades to table _timescaledb_internal.compress_hyper_X_X_chunk +NOTICE: drop cascades to view test_security_barrier_view diff --git a/tsl/test/shared/sql/CMakeLists.txt b/tsl/test/shared/sql/CMakeLists.txt index a7f485d90..a2396b4cf 100644 --- a/tsl/test/shared/sql/CMakeLists.txt +++ b/tsl/test/shared/sql/CMakeLists.txt @@ -7,6 +7,7 @@ set(TEST_FILES_SHARED constraint_exclusion_prepared.sql decompress_join.sql decompress_placeholdervar.sql + security_barrier.sql subtract_integer_from_now.sql) set(TEST_TEMPLATES_SHARED diff --git a/tsl/test/shared/sql/security_barrier.sql b/tsl/test/shared/sql/security_barrier.sql new file mode 100644 index 000000000..df53ec0d4 --- /dev/null +++ b/tsl/test/shared/sql/security_barrier.sql @@ -0,0 +1,41 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. + +\c :TEST_DBNAME :ROLE_SUPERUSER + +CREATE TABLE test_security_barrier (time TIMESTAMPTZ NOT NULL, tenant TEXT NOT NULL, data TEXT); +SELECT FROM create_hypertable('test_security_barrier', by_range('time')); + +INSERT INTO test_security_barrier(time, tenant, data) VALUES +('2020-01-01', :'ROLE_DEFAULT_PERM_USER','data1'), +('2020-01-01', :'ROLE_DEFAULT_PERM_USER_2','data2'); + +CREATE VIEW test_security_barrier_view WITH (security_barrier) AS SELECT * FROM test_security_barrier WHERE tenant = current_user; + +GRANT SELECT ON test_security_barrier_view TO :ROLE_DEFAULT_PERM_USER; +GRANT SELECT ON test_security_barrier_view TO :ROLE_DEFAULT_PERM_USER_2; + +SET ROLE :ROLE_DEFAULT_PERM_USER; +SELECT * FROM test_security_barrier_view; +RESET ROLE; + +SET ROLE :ROLE_DEFAULT_PERM_USER_2; +SELECT * FROM test_security_barrier_view; +RESET ROLE; + +ALTER TABLE test_security_barrier SET (timescaledb.compress); + +-- Compress the chunk +SELECT compress_chunk(show_chunks('test_security_barrier')) IS NOT NULL AS compressed; + +SET ROLE :ROLE_DEFAULT_PERM_USER; +SELECT * FROM test_security_barrier_view; +RESET ROLE; + +SET ROLE :ROLE_DEFAULT_PERM_USER_2; +SELECT * FROM test_security_barrier_view; +RESET ROLE; + +DROP TABLE test_security_barrier CASCADE; +