Fixes grantor order issue

pull/7549/head
gurkanindibay 2024-03-04 11:55:16 +03:00
parent 7d9ff348c7
commit 6ed8ad222c
4 changed files with 197 additions and 0 deletions

View File

@ -1828,6 +1828,12 @@ ExpandRolesToGroups(Oid roleid)
ObjectAddressSet(definition->data.address, AuthIdRelationId, membership->roleid);
roles = lappend(roles, definition);
DependencyDefinition *definition1 = palloc0(sizeof(DependencyDefinition));
definition1->mode = DependencyObjectAddress;
ObjectAddressSet(definition1->data.address, AuthIdRelationId, membership->grantor);
roles = lappend(roles, definition1);
}
systable_endscan(scanDescriptor);

View File

@ -0,0 +1,109 @@
-- Active: 1700033167033@@localhost@9700@gurkanindibay@public
--In below tests, complex role hierarchy is created and then granted by support is tested.
select 1 from citus_remove_node ('localhost',:worker_2_port);
?column?
---------------------------------------------------------------------
1
(1 row)
create role role1;
create role role2;
create role role3;
create role role4;
create role "role5'_test";
grant role2 to role1 with admin option;
grant role2 to role3 with admin option granted by role1;
grant role3 to role4 with admin option;
grant role3 to "role5'_test" granted by role4;
grant role2 to "role5'_test" granted by role3;
grant role4 to "role5'_test" with admin option;
grant role4 to role1 with admin option GRANTED BY "role5'_test";
ERROR: Citus can not handle circular dependencies between distributed objects
DETAIL: "role role1" circularly depends itself, resolve circular dependency first
grant role4 to role3 with admin option GRANTED BY role1;
ERROR: permission denied to grant privileges as role "role1"
DETAIL: The grantor must have the ADMIN option on role "role4".
grant role3 to role1 with admin option GRANTED BY role4;
ERROR: Citus can not handle circular dependencies between distributed objects
DETAIL: "role role1" circularly depends itself, resolve circular dependency first
grant "role5'_test" to role1 with admin option;
ERROR: Citus can not handle circular dependencies between distributed objects
DETAIL: "role role1" circularly depends itself, resolve circular dependency first
grant "role5'_test" to role3 with admin option GRANTED BY role1;
ERROR: permission denied to grant privileges as role "role1"
DETAIL: The grantor must have the ADMIN option on role "role5'_test".
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option, inherit_option,set_option FROM pg_auth_members pa;
role | member | grantor | admin_option | inherit_option | set_option
---------------------------------------------------------------------
pg_read_all_settings | pg_monitor | postgres | f | t | t
pg_read_all_stats | pg_monitor | postgres | f | t | t
pg_stat_scan_tables | pg_monitor | postgres | f | t | t
role2 | role1 | postgres | t | t | t
role2 | role3 | role1 | t | t | t
role3 | role4 | postgres | t | t | t
role3 | "role5'_test" | role4 | f | t | t
role2 | "role5'_test" | role3 | f | t | t
role4 | "role5'_test" | postgres | t | t | t
(9 rows)
select result FROM run_command_on_all_nodes(
$$
SELECT array_to_json(array_agg(row_to_json(t)))
FROM (
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
FROM pg_auth_members
WHERE member::regrole::text in
('role1','role2','role3','role4','"role5''_test"')
order by member::regrole::text, roleid::regrole::text
) t
$$
);
result
---------------------------------------------------------------------
[{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}]
[{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}]
(2 rows)
set citus.log_remote_commands to on;
set citus.grep_remote_commands to '%GRANT%';
select 1 from citus_add_node ('localhost',:worker_2_port);
NOTICE: issuing CREATE SCHEMA IF NOT EXISTS public AUTHORIZATION pg_database_owner;SET ROLE pg_database_owner;GRANT USAGE ON SCHEMA public TO pg_database_owner;;GRANT CREATE ON SCHEMA public TO pg_database_owner;;RESET ROLE;SET ROLE pg_database_owner;GRANT USAGE ON SCHEMA public TO PUBLIC;;RESET ROLE
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing CREATE SCHEMA IF NOT EXISTS information_schema AUTHORIZATION postgres;SET ROLE postgres;GRANT USAGE ON SCHEMA information_schema TO postgres;;GRANT CREATE ON SCHEMA information_schema TO postgres;;RESET ROLE;SET ROLE postgres;GRANT USAGE ON SCHEMA information_schema TO PUBLIC;;RESET ROLE
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_create_or_alter_role('role1', 'CREATE ROLE role1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE role1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');GRANT role2 TO role1 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_create_or_alter_role('role3', 'CREATE ROLE role3 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE role3 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');GRANT role2 TO role3 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY role1;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_create_or_alter_role('role4', 'CREATE ROLE role4 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE role4 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');GRANT role3 TO role4 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_create_or_alter_role('role5''_test', 'CREATE ROLE "role5''_test" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE "role5''_test" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');GRANT role2 TO "role5'_test" WITH INHERIT TRUE GRANTED BY role3;;GRANT role3 TO "role5'_test" WITH INHERIT TRUE GRANTED BY role4;;GRANT role4 TO "role5'_test" WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
?column?
---------------------------------------------------------------------
1
(1 row)
set citus.log_remote_commands to off;
reset citus.grep_remote_commands;
--clean all resources
drop role role1,role2,role3,role4,"role5'_test";
select result FROM run_command_on_all_nodes(
$$
SELECT array_to_json(array_agg(row_to_json(t)))
FROM (
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
FROM pg_auth_members
WHERE member::regrole::text in
('role1','role2','role3','role4','"role5''_test"')
order by member::regrole::text, roleid::regrole::text
) t
$$
);
result
---------------------------------------------------------------------
(3 rows)

View File

@ -63,6 +63,7 @@ test: alter_database_propagation
test: citus_shards
test: reassign_owned
test: granted_by_support
# ----------
# multi_citus_tools tests utility functions written for citus tools

View File

@ -0,0 +1,81 @@
-- Active: 1700033167033@@localhost@9700@gurkanindibay@public
--In below tests, complex role hierarchy is created and then granted by support is tested.
select 1 from citus_remove_node ('localhost',:worker_2_port);
create role role1;
create role role2;
create role role3;
create role role4;
create role "role5'_test";
grant role2 to role1 with admin option;
grant role2 to role3 with admin option granted by role1;
grant role3 to role4 with admin option;
grant role3 to "role5'_test" granted by role4;
grant role2 to "role5'_test" granted by role3;
grant role4 to "role5'_test" with admin option;
grant role4 to role1 with admin option GRANTED BY "role5'_test";
grant role4 to role3 with admin option GRANTED BY role1;
grant role3 to role1 with admin option GRANTED BY role4;
grant "role5'_test" to role1 with admin option;
grant "role5'_test" to role3 with admin option GRANTED BY role1;
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option, inherit_option,set_option FROM pg_auth_members pa;
select result FROM run_command_on_all_nodes(
$$
SELECT array_to_json(array_agg(row_to_json(t)))
FROM (
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
FROM pg_auth_members
WHERE member::regrole::text in
('role1','role2','role3','role4','"role5''_test"')
order by member::regrole::text, roleid::regrole::text
) t
$$
);
set citus.log_remote_commands to on;
set citus.grep_remote_commands to '%GRANT%';
select 1 from citus_add_node ('localhost',:worker_2_port);
set citus.log_remote_commands to off;
reset citus.grep_remote_commands;
--clean all resources
drop role role1,role2,role3,role4,"role5'_test";
select result FROM run_command_on_all_nodes(
$$
SELECT array_to_json(array_agg(row_to_json(t)))
FROM (
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
FROM pg_auth_members
WHERE member::regrole::text in
('role1','role2','role3','role4','"role5''_test"')
order by member::regrole::text, roleid::regrole::text
) t
$$
);