Propagate privileges from hypertables to chunks

Whenever chunks are created, no privileges are added to the chunks.
For accesses that go through the hypertable permission checks are
ignored so reads and writes will succeed anyway. However, for direct
accesses to the chunks, permission checks are done, which creates
problems for, e.g., `pg_dump`.

This commit fixes this by propagating `GRANT` and `REVOKE` statements
to the chunks when executed on the hypertable, and whenever new chunks
are created, privileges are copied from the hypertable.

This commit do not propagate privileges for distributed hypertables,
this is in a separate commit.
This commit is contained in:
Mats Kindahl 2020-07-23 19:42:02 +02:00 committed by Mats Kindahl
parent 43f2c31b3e
commit 6f64f959db
9 changed files with 619 additions and 2 deletions

View File

@ -657,6 +657,54 @@ get_am_name_for_rel(Oid relid)
} }
#endif #endif
static void
copy_hypertable_acl_to_relid(Hypertable *ht, Oid relid)
{
HeapTuple ht_tuple;
bool is_null;
Datum acl_datum;
Relation class_rel;
/* We open it here since there is no point in trying to update the tuples
* if we cannot open the Relation catalog table */
class_rel = table_open(RelationRelationId, RowExclusiveLock);
ht_tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(ht->main_table_relid));
Assert(HeapTupleIsValid(ht_tuple));
/* We only bother about setting the chunk ACL if the hypertable ACL is
* non-null */
acl_datum = SysCacheGetAttr(RELOID, ht_tuple, Anum_pg_class_relacl, &is_null);
if (!is_null)
{
HeapTuple chunk_tuple, newtuple;
Datum new_val[Natts_pg_class] = { 0 };
bool new_null[Natts_pg_class] = { false };
bool new_repl[Natts_pg_class] = { false };
Acl *acl = DatumGetAclP(acl_datum);
new_repl[Anum_pg_class_relacl - 1] = true;
new_val[Anum_pg_class_relacl - 1] = PointerGetDatum(acl);
/* Find the tuple for the chunk in `pg_class` */
chunk_tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
Assert(HeapTupleIsValid(chunk_tuple));
/* Update the relacl for the chunk tuple to use the acl from the hypertable */
newtuple = heap_modify_tuple(chunk_tuple,
RelationGetDescr(class_rel),
new_val,
new_null,
new_repl);
CatalogTupleUpdate(class_rel, &newtuple->t_self, newtuple);
heap_freetuple(newtuple);
ReleaseSysCache(chunk_tuple);
}
ReleaseSysCache(ht_tuple);
table_close(class_rel, RowExclusiveLock);
}
/* /*
* Create a chunk's table. * Create a chunk's table.
* *
@ -729,6 +777,13 @@ ts_chunk_create_table(Chunk *chunk, Hypertable *ht, const char *tablespacename)
objaddr = DefineRelation(&stmt.base, chunk->relkind, rel->rd_rel->relowner, NULL, NULL); objaddr = DefineRelation(&stmt.base, chunk->relkind, rel->rd_rel->relowner, NULL, NULL);
/* Make the newly defined relation visible so that we can update the
* ACL. */
CommandCounterIncrement();
/* Copy acl from hypertable to chunk relation record */
copy_hypertable_acl_to_relid(ht, objaddr.objectId);
if (chunk->relkind == RELKIND_RELATION) if (chunk->relkind == RELKIND_RELATION)
{ {
/* /*

View File

@ -251,6 +251,16 @@ process_add_hypertable(ProcessUtilityArgs *args, Hypertable *ht)
args->hypertable_list = lappend_oid(args->hypertable_list, ht->main_table_relid); args->hypertable_list = lappend_oid(args->hypertable_list, ht->main_table_relid);
} }
static void
add_chunk_oid(Hypertable *ht, Oid chunk_relid, void *vargs)
{
ProcessUtilityArgs *args = vargs;
GrantStmt *stmt = castNode(GrantStmt, args->parsetree);
Chunk *chunk = ts_chunk_get_by_relid(chunk_relid, true);
RangeVar *rv = makeRangeVar(NameStr(chunk->fd.schema_name), NameStr(chunk->fd.table_name), -1);
stmt->objects = lappend(stmt->objects, rv);
}
static bool static bool
block_on_foreign_server(const char *const server_name) block_on_foreign_server(const char *const server_name)
{ {
@ -1035,6 +1045,7 @@ process_grant_and_revoke(ProcessUtilityArgs *args)
{ {
/* Here we know that there is at least one hypertable */ /* Here we know that there is at least one hypertable */
process_add_hypertable(args, ht); process_add_hypertable(args, ht);
foreach_chunk(ht, add_chunk_oid, args);
} }
} }

View File

@ -0,0 +1,248 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE TABLE conditions(
time TIMESTAMPTZ NOT NULL,
device INTEGER,
temperature FLOAT
);
-- Create a hypertable and show that it does not have any privileges
SELECT * FROM create_hypertable('conditions', 'time', chunk_time_interval => '5 days'::interval);
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
1 | public | conditions | t
(1 row)
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-01 00:00'::timestamp, '2018-12-10 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------+-------------------+----------
public | conditions | table | | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | | |
_timescaledb_internal | _hyper_1_2_chunk | table | | |
_timescaledb_internal | _hyper_1_3_chunk | table | | |
(3 rows)
-- Add privileges and show that they propagate to the chunks
GRANT SELECT, INSERT ON conditions TO PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(3 rows)
-- Create some more chunks and show that they also get the privileges.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-10 00:00'::timestamp, '2018-12-20 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_4_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
_timescaledb_internal | _hyper_1_5_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(5 rows)
-- Revoke one of the privileges and show that it propagate to the
-- chunks.
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_4_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_5_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(5 rows)
-- Add some more chunks and show that it inherits the grants from the
-- hypertable.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-20 00:00'::timestamp, '2018-12-30 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_4_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_5_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_6_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
_timescaledb_internal | _hyper_1_7_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(7 rows)
-- Change grants of one chunk explicitly and check that it is possible
\z _timescaledb_internal._hyper_1_1_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
GRANT UPDATE ON _timescaledb_internal._hyper_1_1_chunk TO PUBLIC;
\z _timescaledb_internal._hyper_1_1_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =rw/super_user | |
(1 row)
REVOKE SELECT ON _timescaledb_internal._hyper_1_1_chunk FROM PUBLIC;
\z _timescaledb_internal._hyper_1_1_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_1_chunk | table | super_user=arwdDxt/super_user+| |
| | | =w/super_user | |
(1 row)
-- Check that revoking a permission first on the chunk and then on the
-- hypertable that was added through the hypertable (INSERT and
-- SELECT, in this case) still do not copy permissions from the
-- hypertable (so there should not be a select permission to public on
-- the chunk but there should be one on the hypertable).
GRANT INSERT ON conditions TO PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(1 row)
\z _timescaledb_internal._hyper_1_2_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user+| |
| | | =ar/super_user | |
(1 row)
REVOKE SELECT ON _timescaledb_internal._hyper_1_2_chunk FROM PUBLIC;
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
\z _timescaledb_internal._hyper_1_2_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_2_chunk | table | super_user=arwdDxt/super_user | |
(1 row)
-- Check that granting permissions through hypertable does not remove
-- separate grants on chunk.
GRANT UPDATE ON _timescaledb_internal._hyper_1_3_chunk TO PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
\z _timescaledb_internal._hyper_1_3_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =rw/super_user | |
(1 row)
GRANT INSERT ON conditions TO PUBLIC;
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------------------+-------------------+----------
public | conditions | table | super_user=arwdDxt/super_user+| |
| | | =r/super_user | |
(1 row)
\z _timescaledb_internal._hyper_1_3_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+------------------+-------+-------------------------------+-------------------+----------
_timescaledb_internal | _hyper_1_3_chunk | table | super_user=arwdDxt/super_user+| |
| | | =rw/super_user | |
(1 row)

View File

@ -559,6 +559,7 @@ INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge');
SET SESSION AUTHORIZATION regress_rls_bob; SET SESSION AUTHORIZATION regress_rls_bob;
INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga'); -- Must fail with unique violation, revealing presence of did we can't see INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga'); -- Must fail with unique violation, revealing presence of did we can't see
ERROR: duplicate key value violates unique constraint "5_10_document_pkey" ERROR: duplicate key value violates unique constraint "5_10_document_pkey"
DETAIL: Key (did)=(8) already exists.
SELECT * FROM document WHERE did = 8; -- and confirm we can't see it SELECT * FROM document WHERE did = 8; -- and confirm we can't see it
did | cid | dlevel | dauthor | dtitle did | cid | dlevel | dauthor | dtitle
-----+-----+--------+---------+-------- -----+-----+--------+---------+--------
@ -4439,7 +4440,7 @@ INSERT INTO r1 SELECT a + 1 FROM r2 RETURNING *; -- OK
UPDATE r1 SET a = r2.a + 2 FROM r2 WHERE r1.a = r2.a RETURNING *; -- OK UPDATE r1 SET a = r2.a + 2 FROM r2 WHERE r1.a = r2.a RETURNING *; -- OK
ERROR: new row for relation "_hyper_23_105_chunk" violates check constraint "constraint_105" ERROR: new row for relation "_hyper_23_105_chunk" violates check constraint "constraint_105"
DETAIL: Failing row contains (a) = (12). DETAIL: Failing row contains (12).
DELETE FROM r1 USING r2 WHERE r1.a = r2.a + 2 RETURNING *; -- OK DELETE FROM r1 USING r2 WHERE r1.a = r2.a + 2 RETURNING *; -- OK
a | a a | a
---+--- ---+---

View File

@ -559,6 +559,7 @@ INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge');
SET SESSION AUTHORIZATION regress_rls_bob; SET SESSION AUTHORIZATION regress_rls_bob;
INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga'); -- Must fail with unique violation, revealing presence of did we can't see INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga'); -- Must fail with unique violation, revealing presence of did we can't see
ERROR: duplicate key value violates unique constraint "5_10_document_pkey" ERROR: duplicate key value violates unique constraint "5_10_document_pkey"
DETAIL: Key (did)=(8) already exists.
SELECT * FROM document WHERE did = 8; -- and confirm we can't see it SELECT * FROM document WHERE did = 8; -- and confirm we can't see it
did | cid | dlevel | dauthor | dtitle did | cid | dlevel | dauthor | dtitle
-----+-----+--------+---------+-------- -----+-----+--------+---------+--------
@ -4633,7 +4634,7 @@ INSERT INTO r1 SELECT a + 1 FROM r2 RETURNING *; -- OK
UPDATE r1 SET a = r2.a + 2 FROM r2 WHERE r1.a = r2.a RETURNING *; -- OK UPDATE r1 SET a = r2.a + 2 FROM r2 WHERE r1.a = r2.a RETURNING *; -- OK
ERROR: new row for relation "_hyper_23_105_chunk" violates check constraint "constraint_105" ERROR: new row for relation "_hyper_23_105_chunk" violates check constraint "constraint_105"
DETAIL: Failing row contains (a) = (12). DETAIL: Failing row contains (12).
DELETE FROM r1 USING r2 WHERE r1.a = r2.a + 2 RETURNING *; -- OK DELETE FROM r1 USING r2 WHERE r1.a = r2.a + 2 RETURNING *; -- OK
a | a a | a
---+--- ---+---

View File

@ -22,6 +22,7 @@ set(TEST_FILES
extension.sql extension.sql
gapfill.sql gapfill.sql
generated_as_identity.sql generated_as_identity.sql
grant_hypertable.sql
hash.sql hash.sql
histogram_test.sql histogram_test.sql
index.sql index.sql

View File

@ -0,0 +1,75 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE TABLE conditions(
time TIMESTAMPTZ NOT NULL,
device INTEGER,
temperature FLOAT
);
-- Create a hypertable and show that it does not have any privileges
SELECT * FROM create_hypertable('conditions', 'time', chunk_time_interval => '5 days'::interval);
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-01 00:00'::timestamp, '2018-12-10 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Add privileges and show that they propagate to the chunks
GRANT SELECT, INSERT ON conditions TO PUBLIC;
\z conditions
\z _timescaledb_internal.*chunk
-- Create some more chunks and show that they also get the privileges.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-10 00:00'::timestamp, '2018-12-20 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Revoke one of the privileges and show that it propagate to the
-- chunks.
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
\z _timescaledb_internal.*chunk
-- Add some more chunks and show that it inherits the grants from the
-- hypertable.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-20 00:00'::timestamp, '2018-12-30 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Change grants of one chunk explicitly and check that it is possible
\z _timescaledb_internal._hyper_1_1_chunk
GRANT UPDATE ON _timescaledb_internal._hyper_1_1_chunk TO PUBLIC;
\z _timescaledb_internal._hyper_1_1_chunk
REVOKE SELECT ON _timescaledb_internal._hyper_1_1_chunk FROM PUBLIC;
\z _timescaledb_internal._hyper_1_1_chunk
-- Check that revoking a permission first on the chunk and then on the
-- hypertable that was added through the hypertable (INSERT and
-- SELECT, in this case) still do not copy permissions from the
-- hypertable (so there should not be a select permission to public on
-- the chunk but there should be one on the hypertable).
GRANT INSERT ON conditions TO PUBLIC;
\z conditions
\z _timescaledb_internal._hyper_1_2_chunk
REVOKE SELECT ON _timescaledb_internal._hyper_1_2_chunk FROM PUBLIC;
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
\z _timescaledb_internal._hyper_1_2_chunk
-- Check that granting permissions through hypertable does not remove
-- separate grants on chunk.
GRANT UPDATE ON _timescaledb_internal._hyper_1_3_chunk TO PUBLIC;
\z conditions
\z _timescaledb_internal._hyper_1_3_chunk
GRANT INSERT ON conditions TO PUBLIC;
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
\z _timescaledb_internal._hyper_1_3_chunk

View File

@ -496,3 +496,175 @@ t |f |t
(1 row) (1 row)
DROP TABLE conditions;
DROP TABLE no_grants;
-- Check that grants and revokes are copied properly to the chunks and
-- that newly created chunks have the right privileges.
CREATE TABLE conditions(
time TIMESTAMPTZ NOT NULL,
device INTEGER,
temperature FLOAT
);
-- Create a hypertable and show that it does not have any privileges
SELECT * FROM create_hypertable('conditions', 'time', chunk_time_interval => '5 days'::interval);
hypertable_id | schema_name | table_name | created
---------------+-------------+------------+---------
3 | public | conditions | t
(1 row)
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-01 00:00'::timestamp, '2018-12-10 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-------------------+-------------------+----------
public | conditions | table | | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | | |
_timescaledb_internal | _hyper_3_36_chunk | table | | |
_timescaledb_internal | _hyper_3_37_chunk | table | | |
(3 rows)
-- Add privileges and show that they propagate to the chunks
GRANT SELECT, INSERT ON conditions TO PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-----------------------------------------------+-------------------+----------
public | conditions | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_36_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_37_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
(3 rows)
-- Create some more chunks and show that they also get the privileges.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-10 00:00'::timestamp, '2018-12-20 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-----------------------------------------------+-------------------+----------
public | conditions | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_36_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_37_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_38_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
_timescaledb_internal | _hyper_3_39_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =ar/cluster_super_user | |
(5 rows)
-- Revoke one of the privileges and show that it propagate to the
-- chunks.
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-----------------------------------------------+-------------------+----------
public | conditions | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_36_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_37_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_38_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_39_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
(5 rows)
-- Add some more chunks and show that it inherits the grants from the
-- hypertable.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-20 00:00'::timestamp, '2018-12-30 00:00'::timestamp, '1h') AS time;
\z conditions
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+------------+-------+-----------------------------------------------+-------------------+----------
public | conditions | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
(1 row)
\z _timescaledb_internal.*chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_36_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_37_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_38_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_39_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_40_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
_timescaledb_internal | _hyper_3_41_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
(7 rows)
-- Change grants of one chunk explicitly and check that it is possible
\z _timescaledb_internal._hyper_3_35_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =r/cluster_super_user | |
(1 row)
GRANT UPDATE ON _timescaledb_internal._hyper_3_35_chunk TO PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =rw/cluster_super_user | |
(1 row)
REVOKE SELECT ON _timescaledb_internal._hyper_3_35_chunk FROM PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
-----------------------+-------------------+-------+-----------------------------------------------+-------------------+----------
_timescaledb_internal | _hyper_3_35_chunk | table | cluster_super_user=arwdDxt/cluster_super_user+| |
| | | =w/cluster_super_user | |
(1 row)

View File

@ -130,3 +130,56 @@ SELECT * FROM test.remote_exec(NULL, format($$
, has_table_privilege('%s', 'no_grants', 'DELETE') AS "DELETE" , has_table_privilege('%s', 'no_grants', 'DELETE') AS "DELETE"
, has_table_privilege('%s', 'no_grants', 'INSERT') AS "INSERT"; , has_table_privilege('%s', 'no_grants', 'INSERT') AS "INSERT";
$$, :'ROLE_1', :'ROLE_1', :'ROLE_1')); $$, :'ROLE_1', :'ROLE_1', :'ROLE_1'));
DROP TABLE conditions;
DROP TABLE no_grants;
-- Check that grants and revokes are copied properly to the chunks and
-- that newly created chunks have the right privileges.
CREATE TABLE conditions(
time TIMESTAMPTZ NOT NULL,
device INTEGER,
temperature FLOAT
);
-- Create a hypertable and show that it does not have any privileges
SELECT * FROM create_hypertable('conditions', 'time', chunk_time_interval => '5 days'::interval);
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-01 00:00'::timestamp, '2018-12-10 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Add privileges and show that they propagate to the chunks
GRANT SELECT, INSERT ON conditions TO PUBLIC;
\z conditions
\z _timescaledb_internal.*chunk
-- Create some more chunks and show that they also get the privileges.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-10 00:00'::timestamp, '2018-12-20 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Revoke one of the privileges and show that it propagate to the
-- chunks.
REVOKE INSERT ON conditions FROM PUBLIC;
\z conditions
\z _timescaledb_internal.*chunk
-- Add some more chunks and show that it inherits the grants from the
-- hypertable.
INSERT INTO conditions
SELECT time, (random()*30)::int, random()*80 - 40
FROM generate_series('2018-12-20 00:00'::timestamp, '2018-12-30 00:00'::timestamp, '1h') AS time;
\z conditions
\z _timescaledb_internal.*chunk
-- Change grants of one chunk explicitly and check that it is possible
\z _timescaledb_internal._hyper_3_35_chunk
GRANT UPDATE ON _timescaledb_internal._hyper_3_35_chunk TO PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk
REVOKE SELECT ON _timescaledb_internal._hyper_3_35_chunk FROM PUBLIC;
\z _timescaledb_internal._hyper_3_35_chunk