diff --git a/tsl/src/bgw_policy/job_api.c b/tsl/src/bgw_policy/job_api.c index 47db920e6d4..870d4c06ee8 100644 --- a/tsl/src/bgw_policy/job_api.c +++ b/tsl/src/bgw_policy/job_api.c @@ -244,7 +244,7 @@ job_delete(PG_FUNCTION_ARGS) if (!has_privs_of_role(GetUserId(), job->fd.owner)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("insufficient permissions to delete job for user \"%s\"", + errmsg("insufficient permissions to delete job owned by \"%s\"", GetUserNameFromId(job->fd.owner, false)))); ts_bgw_job_delete_by_id(job_id); diff --git a/tsl/test/expected/bgw_security.out b/tsl/test/expected/bgw_security.out index 7a73f58b832..69245572d21 100644 --- a/tsl/test/expected/bgw_security.out +++ b/tsl/test/expected/bgw_security.out @@ -3,7 +3,7 @@ -- LICENSE-TIMESCALE for a copy of the license. \set ROLE_ADMIN :TEST_DBNAME _admin \c :TEST_DBNAME :ROLE_SUPERUSER -CREATE ROLE :ROLE_ADMIN; +CREATE ROLE :ROLE_ADMIN LOGIN; GRANT :ROLE_ADMIN TO :ROLE_DEFAULT_PERM_USER; \c :TEST_DBNAME :ROLE_SUPERUSER CREATE TABLE custom_log (ts integer, msg text); @@ -11,9 +11,9 @@ GRANT ALL ON custom_log TO PUBLIC; CREATE PROCEDURE custom_job(integer, jsonb) AS $$ INSERT INTO custom_log values($1, 'custom_job'); $$ LANGUAGE SQL; +SET ROLE :ROLE_ADMIN; SELECT add_job('custom_job', '1h') AS job_id \gset --- Set the owner of the job to the admin role -UPDATE _timescaledb_config.bgw_job SET owner = :'ROLE_ADMIN' WHERE id = :job_id; +RESET ROLE; SELECT id, proc_name, owner FROM _timescaledb_config.bgw_job WHERE id = :job_id; id | proc_name | owner ------+------------+----------------------- @@ -21,12 +21,23 @@ SELECT id, proc_name, owner FROM _timescaledb_config.bgw_job WHERE id = :job_id; (1 row) \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2 --- We should fail to execute the job since we do not own it or belong --- to the group that owns it. +-- We should fail to execute and delete the job since we do not own it +-- or belong to the group that owns it. \set ON_ERROR_STOP 0 CALL run_job(:job_id); ERROR: insufficient permissions to run job 1000 +SELECT delete_job(:job_id); +ERROR: insufficient permissions to delete job owned by "db_bgw_security_admin" \set ON_ERROR_STOP 1 \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER -- This should succeed since the role belongs to the job owner group. CALL run_job(:job_id); +-- This should succeed since we belong to the owners role. +SELECT delete_job(:job_id); + delete_job +------------ + +(1 row) + +\c :TEST_DBNAME :ROLE_SUPERUSER +DROP ROLE :ROLE_ADMIN; diff --git a/tsl/test/sql/bgw_security.sql b/tsl/test/sql/bgw_security.sql index 7ec19c29b01..dcfe27b6310 100644 --- a/tsl/test/sql/bgw_security.sql +++ b/tsl/test/sql/bgw_security.sql @@ -5,7 +5,7 @@ \set ROLE_ADMIN :TEST_DBNAME _admin \c :TEST_DBNAME :ROLE_SUPERUSER -CREATE ROLE :ROLE_ADMIN; +CREATE ROLE :ROLE_ADMIN LOGIN; GRANT :ROLE_ADMIN TO :ROLE_DEFAULT_PERM_USER; \c :TEST_DBNAME :ROLE_SUPERUSER @@ -17,22 +17,29 @@ CREATE PROCEDURE custom_job(integer, jsonb) AS $$ INSERT INTO custom_log values($1, 'custom_job'); $$ LANGUAGE SQL; +SET ROLE :ROLE_ADMIN; SELECT add_job('custom_job', '1h') AS job_id \gset --- Set the owner of the job to the admin role -UPDATE _timescaledb_config.bgw_job SET owner = :'ROLE_ADMIN' WHERE id = :job_id; +RESET ROLE; SELECT id, proc_name, owner FROM _timescaledb_config.bgw_job WHERE id = :job_id; \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2 --- We should fail to execute the job since we do not own it or belong --- to the group that owns it. +-- We should fail to execute and delete the job since we do not own it +-- or belong to the group that owns it. \set ON_ERROR_STOP 0 CALL run_job(:job_id); +SELECT delete_job(:job_id); \set ON_ERROR_STOP 1 \c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER -- This should succeed since the role belongs to the job owner group. CALL run_job(:job_id); + +-- This should succeed since we belong to the owners role. +SELECT delete_job(:job_id); + +\c :TEST_DBNAME :ROLE_SUPERUSER +DROP ROLE :ROLE_ADMIN;