-- -- SECLABEL -- -- Test suite for SECURITY LABEL ON ROLE statements -- -- first we remove one of the worker nodes to be able to test -- citus_add_node later SELECT citus_remove_node('localhost', :worker_2_port); citus_remove_node --------------------------------------------------------------------- (1 row) -- create two roles, one with characters that need escaping CREATE ROLE user1; CREATE ROLE "user 2"; -- check an invalid label for our current dummy hook citus_test_object_relabel SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'invalid_label'; ERROR: 'invalid_label' is not a valid security label for Citus tests. -- if we disable metadata_sync, the command will not be propagated SET citus.enable_metadata_sync TO off; SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_unclassified'; SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | (2 rows) RESET citus.enable_metadata_sync; -- check that we only support propagating for roles SET citus.shard_replication_factor to 1; -- distributed table CREATE TABLE a (a int); SELECT create_distributed_table('a', 'a'); create_distributed_table --------------------------------------------------------------------- (1 row) -- distributed view CREATE VIEW v_dist AS SELECT * FROM a; -- distributed function CREATE FUNCTION notice(text) RETURNS void LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE '%', $1; END; $$; SECURITY LABEL ON TABLE a IS 'citus_classified'; NOTICE: not propagating SECURITY LABEL commands whose object type is not role HINT: Connect to worker nodes directly to manually run the same SECURITY LABEL command. SECURITY LABEL ON FUNCTION notice IS 'citus_unclassified'; NOTICE: not propagating SECURITY LABEL commands whose object type is not role HINT: Connect to worker nodes directly to manually run the same SECURITY LABEL command. SECURITY LABEL ON VIEW v_dist IS 'citus_classified'; NOTICE: not propagating SECURITY LABEL commands whose object type is not role HINT: Connect to worker nodes directly to manually run the same SECURITY LABEL command. SELECT node_type, result FROM get_citus_tests_label_provider_labels('a') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "table", "provider": "citus '!tests_label_provider"} worker_1 | (2 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('notice(text)') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "function", "provider": "citus '!tests_label_provider"} worker_1 | (2 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('v_dist') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "view", "provider": "citus '!tests_label_provider"} worker_1 | (2 rows) \c - - - :worker_1_port SECURITY LABEL ON TABLE a IS 'citus_classified'; SECURITY LABEL ON FUNCTION notice IS 'citus_unclassified'; SECURITY LABEL ON VIEW v_dist IS 'citus_classified'; \c - - - :master_port SELECT node_type, result FROM get_citus_tests_label_provider_labels('a') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "table", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "table", "provider": "citus '!tests_label_provider"} (2 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('notice(text)') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "function", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_unclassified", "objtype": "function", "provider": "citus '!tests_label_provider"} (2 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('v_dist') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "view", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "view", "provider": "citus '!tests_label_provider"} (2 rows) DROP TABLE a CASCADE; NOTICE: drop cascades to view v_dist DROP FUNCTION notice; -- test that SECURITY LABEL statement is actually propagated for ROLES SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; -- we have exactly one provider loaded, so we may not include the provider in the command SECURITY LABEL for "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified'; NOTICE: issuing SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx SECURITY LABEL ON ROLE user1 IS NULL; NOTICE: issuing SECURITY LABEL ON ROLE user1 IS NULL DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx SECURITY LABEL ON ROLE user1 IS 'citus_unclassified'; NOTICE: issuing SECURITY LABEL ON ROLE user1 IS 'citus_unclassified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx SECURITY LABEL for "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus_classified'; NOTICE: issuing SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus_classified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx \c - - - :worker_1_port SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; -- command from the worker node should be propagated to the coordinator SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} (2 rows) SECURITY LABEL for "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified'; NOTICE: issuing SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} (2 rows) RESET citus.log_remote_commands; SECURITY LABEL for "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus ''!unclassified'; SELECT node_type, result FROM get_citus_tests_label_provider_labels('"user 2"') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} (2 rows) \c - - - :master_port SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} (2 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('"user 2"') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} (2 rows) -- add a new node and check that it also propagates the SECURITY LABEL statement to the new node SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; SELECT 1 FROM citus_add_node('localhost', :worker_2_port); NOTICE: issuing SELECT worker_create_or_alter_role('user1', 'CREATE ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL', 'ALTER ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing SELECT worker_create_or_alter_role('user 2', 'CREATE ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL', 'ALTER ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus ''!unclassified' DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx ?column? --------------------------------------------------------------------- 1 (1 row) SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_2 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} (3 rows) SELECT node_type, result FROM get_citus_tests_label_provider_labels('"user 2"') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_2 | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} (3 rows) -- disable the GUC and check that the command is not propagated SET citus.enable_alter_role_propagation TO off; SECURITY LABEL ON ROLE user1 IS 'citus_unclassified'; NOTICE: not propagating SECURITY LABEL commands to other nodes HINT: Connect to other nodes directly to manually assign necessary labels. SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_2 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} (3 rows) \c - - - :worker_2_port SET citus.log_remote_commands TO on; SET citus.grep_remote_commands = '%SECURITY LABEL%'; SET citus.enable_alter_role_propagation TO off; SECURITY LABEL ON ROLE user1 IS 'citus ''!unclassified'; NOTICE: not propagating SECURITY LABEL commands to other nodes HINT: Connect to other nodes directly to manually assign necessary labels. SELECT node_type, result FROM get_citus_tests_label_provider_labels('user1') ORDER BY node_type; node_type | result --------------------------------------------------------------------- coordinator | {"label": "citus_unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_1 | {"label": "citus_classified", "objtype": "role", "provider": "citus '!tests_label_provider"} worker_2 | {"label": "citus '!unclassified", "objtype": "role", "provider": "citus '!tests_label_provider"} (3 rows) RESET citus.enable_alter_role_propagation; -- cleanup RESET citus.log_remote_commands; DROP ROLE user1, "user 2";