From e049238a07581bfc5b08c0e6b45598e1e788e54b Mon Sep 17 00:00:00 2001 From: Matvey Arye Date: Wed, 19 Jun 2019 14:29:16 -0400 Subject: [PATCH] Adjust permissions on internal functions The following functions have had permission checks added or adjusted: ts_chunk_index_clone ts_chunk_index_replace ts_hypertable_insert_blocker_trigger_add ts_current_license_key ts_calculate_chunk_interval ts_chunk_adaptive_set The following functions have been removed from the regular SQL install. They are only installed and used in tests: dimension_calculate_default_range_open dimension_calculate_default_range_closed --- sql/chunk.sql | 14 ----------- sql/updates/latest-dev.sql | 3 +++ src/chunk_adaptive.c | 9 +++++++ src/chunk_index.c | 10 ++++++++ src/hypertable.c | 4 ++- src/license_guc.c | 11 ++++++++ test/expected/edition.out | 47 ++++++++++++++++++++++++++++++++--- test/sql/chunks.sql | 16 ++++++++++++ test/sql/edition.sql | 20 +++++++++++++-- tsl/test/expected/edition.out | 12 +-------- tsl/test/sql/edition.sql | 1 - 11 files changed, 114 insertions(+), 33 deletions(-) diff --git a/sql/chunk.sql b/sql/chunk.sql index 2370938d2..3dc4b314f 100644 --- a/sql/chunk.sql +++ b/sql/chunk.sql @@ -2,20 +2,6 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-APACHE for a copy of the license. -CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_open( - dimension_value BIGINT, - interval_length BIGINT, - OUT range_start BIGINT, - OUT range_end BIGINT) - AS '@MODULE_PATHNAME@', 'ts_dimension_calculate_open_range_default' LANGUAGE C STABLE; - -CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed( - dimension_value BIGINT, - num_slices SMALLINT, - OUT range_start BIGINT, - OUT range_end BIGINT) - AS '@MODULE_PATHNAME@', 'ts_dimension_calculate_closed_range_default' LANGUAGE C STABLE; - -- Built-in function for calculating the next chunk interval when -- using adaptive chunking. The function can be replaced by a -- user-defined function with the same signature. diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index f6f087878..a99875a1d 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -2,3 +2,6 @@ ALTER TABLE _timescaledb_catalog.telemetry_metadata ADD COLUMN include_in_teleme ALTER TABLE _timescaledb_catalog.telemetry_metadata ALTER COLUMN include_in_telemetry DROP DEFAULT; ALTER TABLE _timescaledb_catalog.telemetry_metadata RENAME TO metadata; ALTER INDEX _timescaledb_catalog.telemetry_metadata_pkey RENAME TO metadata_pkey; + +DROP FUNCTION IF EXISTS _timescaledb_internal.dimension_calculate_default_range_open(bigint, bigint); +DROP FUNCTION IF EXISTS _timescaledb_internal.dimension_calculate_default_range_closed(bigint, smallint); diff --git a/src/chunk_adaptive.c b/src/chunk_adaptive.c index 52c8e5cf5..184d8f3c6 100644 --- a/src/chunk_adaptive.c +++ b/src/chunk_adaptive.c @@ -421,6 +421,7 @@ ts_calculate_chunk_interval(PG_FUNCTION_ARGS) int num_undersized_intervals = 0; double interval_diff; double undersized_fillfactor = 0.0; + AclResult acl_result; if (PG_NARGS() != CHUNK_SIZING_FUNC_NARGS) elog(ERROR, "invalid number of arguments"); @@ -435,6 +436,12 @@ ts_calculate_chunk_interval(PG_FUNCTION_ARGS) ht = ts_hypertable_get_by_id(hypertable_id); + acl_result = pg_class_aclcheck(ht->main_table_relid, GetUserId(), ACL_SELECT); + if (acl_result != ACLCHECK_OK) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied for table %s", ht->fd.table_name.data))); + Assert(ht != NULL); dim = ts_hyperspace_get_dimension_by_id(ht->space, dimension_id); @@ -749,6 +756,8 @@ ts_chunk_adaptive_set(PG_FUNCTION_ARGS) if (!OidIsValid(info.table_relid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("table does not exist"))); + ts_hypertable_permissions_check(info.table_relid, GetUserId()); + hcache = ts_hypertable_cache_pin(); ht = ts_hypertable_cache_get_entry(hcache, info.table_relid); diff --git a/src/chunk_index.c b/src/chunk_index.c index d9e843384..fad1abc96 100644 --- a/src/chunk_index.c +++ b/src/chunk_index.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "export.h" #include "chunk_index.h" @@ -1094,6 +1095,8 @@ ts_chunk_index_clone(PG_FUNCTION_ARGS) chunk = ts_chunk_get_by_relid(chunk_index_rel->rd_index->indrelid, 0, true); ts_chunk_index_get_by_indexrelid(chunk, chunk_index_oid, &cim); + ts_hypertable_permissions_check(cim.hypertableoid, GetUserId()); + hypertable_rel = heap_open(cim.hypertableoid, AccessShareLock); /* Need ShareLock on the heap relation we are creating indexes on */ @@ -1123,12 +1126,19 @@ ts_chunk_index_replace(PG_FUNCTION_ARGS) Oid chunk_index_oid_old = PG_GETARG_OID(0); Oid chunk_index_oid_new = PG_GETARG_OID(1); Relation index_rel; + Chunk *chunk; + ChunkIndexMapping cim; Oid constraint_oid; char *name; index_rel = relation_open(chunk_index_oid_old, ShareLock); + /* check permissions */ + chunk = ts_chunk_get_by_relid(index_rel->rd_index->indrelid, 0, true); + ts_chunk_index_get_by_indexrelid(chunk, chunk_index_oid_old, &cim); + ts_hypertable_permissions_check(cim.hypertableoid, GetUserId()); + name = pstrdup(RelationGetRelationName(index_rel)); constraint_oid = get_index_constraint(chunk_index_oid_old); diff --git a/src/hypertable.c b/src/hypertable.c index e508ae254..d13caa248 100644 --- a/src/hypertable.c +++ b/src/hypertable.c @@ -70,7 +70,7 @@ ts_rel_get_owner(Oid relid) if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("relation with OID %u does not exist", relid))); + errmsg("unable to get owner for relation with OID %u: does not exist", relid))); ownerid = ((Form_pg_class) GETSTRUCT(tuple))->relowner; @@ -1351,6 +1351,8 @@ ts_hypertable_insert_blocker_trigger_add(PG_FUNCTION_ARGS) Oid relid = PG_GETARG_OID(0); Oid old_trigger; + ts_hypertable_permissions_check(relid, GetUserId()); + if (table_has_tuples(relid, AccessShareLock)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/license_guc.c b/src/license_guc.c index f22a4999e..b80fc1890 100644 --- a/src/license_guc.c +++ b/src/license_guc.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "extension_constants.h" #include "export.h" @@ -320,6 +322,15 @@ ts_enterprise_enabled(PG_FUNCTION_ARGS) PGDLLEXPORT Datum ts_current_license_key(PG_FUNCTION_ARGS) { +#if PG96 + if (!superuser()) +#else + if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) +#endif + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser or a member of pg_read_all_settings to examine the " + "license key"))); Assert(ts_guc_license_key != NULL); PG_RETURN_TEXT_P(cstring_to_text(ts_guc_license_key)); } diff --git a/test/expected/edition.out b/test/expected/edition.out index ca25ef791..2b6c9f7ff 100644 --- a/test/expected/edition.out +++ b/test/expected/edition.out @@ -1,6 +1,7 @@ -- 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 SELECT _timescaledb_internal.current_license_key(); current_license_key --------------------- @@ -60,16 +61,54 @@ BEGIN END; $$ LANGUAGE PLPGSQL; +SELECT * FROM timescaledb_information.license; + edition | expired | expiration_time +-----------+---------+----------------- + community | f | infinity +(1 row) + +SELECT * FROM _timescaledb_internal.enterprise_enabled(); + enterprise_enabled +-------------------- + f +(1 row) + +SELECT * FROM _timescaledb_internal.tsl_loaded(); + tsl_loaded +------------ + t +(1 row) + +SELECT * FROM _timescaledb_internal.license_expiration_time(); + license_expiration_time +------------------------- + infinity +(1 row) + +SELECT * FROM _timescaledb_internal.print_license_expiration_info(); + print_license_expiration_info +------------------------------- + +(1 row) + +SELECT * FROM _timescaledb_internal.license_edition(); + license_edition +----------------- + community +(1 row) + SELECT get_sqlstate($$SELECT _timescaledb_internal.current_db_set_license_key('ApacheOnly')$$); get_sqlstate -------------- 42501 (1 row) -select * from timescaledb_information.license; - edition | expired | expiration_time ------------+---------+----------------- - community | f | infinity +SELECT get_sqlstate($$SHOW timescaledb.license_key;$$); + get_sqlstate +-------------- + 42501 (1 row) +SELECT * FROM _timescaledb_internal.current_license_key(); +ERROR: must be superuser or a member of pg_read_all_settings to examine the license key drop function get_sqlstate(TEXT); diff --git a/test/sql/chunks.sql b/test/sql/chunks.sql index 16e8dedca..b886ff6cd 100644 --- a/test/sql/chunks.sql +++ b/test/sql/chunks.sql @@ -11,6 +11,22 @@ \o /dev/null +\c :TEST_DBNAME :ROLE_SUPERUSER +CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_open( + dimension_value BIGINT, + interval_length BIGINT, + OUT range_start BIGINT, + OUT range_end BIGINT) + AS :MODULE_PATHNAME, 'ts_dimension_calculate_open_range_default' LANGUAGE C STABLE; + +CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed( + dimension_value BIGINT, + num_slices SMALLINT, + OUT range_start BIGINT, + OUT range_end BIGINT) + AS :MODULE_PATHNAME, 'ts_dimension_calculate_closed_range_default' LANGUAGE C STABLE; + +\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER --open SELECT assert_equal(0::bigint, actual_range_start), assert_equal(10::bigint, actual_range_end) FROM _timescaledb_internal.dimension_calculate_default_range_open(0,10) AS res(actual_range_start, actual_range_end); diff --git a/test/sql/edition.sql b/test/sql/edition.sql index 6ffb738e5..0684adeca 100644 --- a/test/sql/edition.sql +++ b/test/sql/edition.sql @@ -2,6 +2,9 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-APACHE for a copy of the license. + +\c :TEST_DBNAME :ROLE_SUPERUSER + SELECT _timescaledb_internal.current_license_key(); SELECT _timescaledb_internal.tsl_loaded(); SELECT _timescaledb_internal.enterprise_enabled(); @@ -42,6 +45,19 @@ END; $$ LANGUAGE PLPGSQL; +--allowed +SELECT * FROM timescaledb_information.license; +SELECT * FROM _timescaledb_internal.enterprise_enabled(); +SELECT * FROM _timescaledb_internal.tsl_loaded(); +SELECT * FROM _timescaledb_internal.license_expiration_time(); +SELECT * FROM _timescaledb_internal.print_license_expiration_info(); +SELECT * FROM _timescaledb_internal.license_edition(); + + +--disallowd +\set ON_ERROR_STOP 0 SELECT get_sqlstate($$SELECT _timescaledb_internal.current_db_set_license_key('ApacheOnly')$$); -select * from timescaledb_information.license; -drop function get_sqlstate(TEXT); \ No newline at end of file +SELECT get_sqlstate($$SHOW timescaledb.license_key;$$); +SELECT * FROM _timescaledb_internal.current_license_key(); +\set ON_ERROR_STOP 1 +drop function get_sqlstate(TEXT); diff --git a/tsl/test/expected/edition.out b/tsl/test/expected/edition.out index ab2c48975..67595b8b1 100644 --- a/tsl/test/expected/edition.out +++ b/tsl/test/expected/edition.out @@ -1,12 +1,6 @@ -- 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. -SELECT _timescaledb_internal.current_license_key(); - current_license_key ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - E1eyJlbmRfdGltZSI6IjIwMTgtMTAtMDEgKzAwMDAiLCAic3RhcnRfdGltZSI6IjIwMTgtMDktMDEgKzAwMDAiLCAiaWQiOiI0OTBGQjI2MC1BMjkyLTRBRDktOUFBMi0wMzYwODM1NzkxQjgiLCAia2luZCI6InRyaWFsIn0K -(1 row) - SELECT _timescaledb_internal.tsl_loaded(); tsl_loaded ------------ @@ -30,11 +24,7 @@ select * from timescaledb_information.license; SET timescaledb.license_key='CommunityLicense'; ERROR: permission denied to set parameter "timescaledb.license_key" SELECT _timescaledb_internal.current_license_key(); - current_license_key ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - E1eyJlbmRfdGltZSI6IjIwMTgtMTAtMDEgKzAwMDAiLCAic3RhcnRfdGltZSI6IjIwMTgtMDktMDEgKzAwMDAiLCAiaWQiOiI0OTBGQjI2MC1BMjkyLTRBRDktOUFBMi0wMzYwODM1NzkxQjgiLCAia2luZCI6InRyaWFsIn0K -(1 row) - +ERROR: must be superuser or a member of pg_read_all_settings to examine the license key SELECT _timescaledb_internal.tsl_loaded(); tsl_loaded ------------ diff --git a/tsl/test/sql/edition.sql b/tsl/test/sql/edition.sql index 46ab74a50..8853ac8ba 100644 --- a/tsl/test/sql/edition.sql +++ b/tsl/test/sql/edition.sql @@ -2,7 +2,6 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-TIMESCALE for a copy of the license. -SELECT _timescaledb_internal.current_license_key(); SELECT _timescaledb_internal.tsl_loaded(); SELECT _timescaledb_internal.enterprise_enabled(); select * from timescaledb_information.license;