Skip to content

Commit

Permalink
Allow anyone to use size utilities on distributed hypertables
Browse files Browse the repository at this point in the history
This change removes a check for `USAGE` privileges on data nodes
required to query the data node using utility commands, such as
`hypertable_size`. Normally, PostgreSQL doesn't require `USAGE` on a
foreign server to query its remote tables. Also, size utilities, like
`pg_table_size` can be used by anyone---even roles without any
privileges on a table. The behavior on distributed hypertables is now
consistent with PostgreSQL.
  • Loading branch information
erimatnor committed Oct 15, 2021
1 parent cb13754 commit 8b14c7a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
12 changes: 8 additions & 4 deletions tsl/src/data_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -1577,12 +1577,16 @@ data_node_name_list_check_acl(List *data_node_names, AclMode mode)

foreach (lc, data_node_names)
{
/* Validate the servers, but privilege check is optional */
ForeignServer *server = GetForeignServerByName(lfirst(lc), false);

/* Must have permissions on the server object */
aclresult = pg_foreign_server_aclcheck(server->serverid, curuserid, mode);
if (mode != ACL_NO_CHECK)
{
/* Must have permissions on the server object */
aclresult = pg_foreign_server_aclcheck(server->serverid, curuserid, mode);

if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
}
}
}
6 changes: 3 additions & 3 deletions tsl/src/remote/dist_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ ts_dist_cmd_params_invoke_on_data_nodes(const char *sql, StmtParams *params, Lis
switch (nodeTag(data_nodes))
{
case T_OidList:
data_nodes = data_node_oids_to_node_name_list(data_nodes, ACL_USAGE);
data_nodes = data_node_oids_to_node_name_list(data_nodes, ACL_NO_CHECK);
break;
case T_List:
/* Already in the format we want. Just check permissions. */
data_node_name_list_check_acl(data_nodes, ACL_USAGE);
/* Already in the format we want */
data_node_name_list_check_acl(data_nodes, ACL_NO_CHECK);
break;
default:
elog(ERROR, "invalid list type %u", nodeTag(data_nodes));
Expand Down
35 changes: 35 additions & 0 deletions tsl/test/sql/dist_util.sql
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,41 @@ SELECT * FROM chunk_compression_stats('nondisttable') ORDER BY chunk_schema, chu
SELECT * FROM hypertable_index_size('disttable_pkey');
SELECT * FROM hypertable_index_size('nondisttable_pkey');

-- Make sure functions work for non-superuser
CREATE TABLE size_test_table (value int);
INSERT INTO size_test_table SELECT * FROM generate_series(0, 10000);

SET ROLE :ROLE_1;

-- No query permissions
\set ON_ERROR_STOP 0
SELECT count(*) FROM disttable;
SELECT count(*) FROM size_test_table;
\set ON_ERROR_STOP 1

-- Size functions work anyway, similar to pg_table_size, et al.
SELECT * FROM pg_table_size('size_test_table');
SELECT * FROM pg_table_size('disttable');
SELECT * FROM pg_table_size('nondisttable');
SELECT * FROM hypertable_size('disttable');
SELECT * FROM hypertable_size('nondisttable');
SELECT * FROM hypertable_detailed_size('disttable') ORDER BY node_name;
SELECT * FROM hypertable_detailed_size('nondisttable') ORDER BY node_name;
SELECT * FROM chunks_detailed_size('disttable') ORDER BY chunk_schema, chunk_name, node_name;
SELECT * FROM chunks_detailed_size('nondisttable') ORDER BY chunk_schema, chunk_name, node_name;
SELECT * FROM hypertable_compression_stats('disttable') ORDER BY node_name;
SELECT * FROM hypertable_compression_stats('nondisttable') ORDER BY node_name;
SELECT * FROM chunk_compression_stats('disttable') ORDER BY chunk_schema, chunk_name, node_name;
SELECT * FROM chunk_compression_stats('nondisttable') ORDER BY chunk_schema, chunk_name, node_name;
SELECT * FROM hypertable_index_size('disttable_pkey');
SELECT * FROM hypertable_index_size('nondisttable_pkey');

RESET ROLE;
GRANT SELECT ON disttable TO :ROLE_1;
SET ROLE :ROLE_1;
-- Querying should now work
SELECT count(*) FROM disttable;

-- Make sure timescaledb.ssl_dir and passfile gucs can be read by a non-superuser
\c :TEST_DBNAME :ROLE_1
\unset ECHO
Expand Down

0 comments on commit 8b14c7a

Please sign in to comment.