Skip to content

Commit

Permalink
Fix corner case of NULL/empty arrays comparison for roles
Browse files Browse the repository at this point in the history
  • Loading branch information
Tener committed Feb 22, 2024
1 parent 469f3bd commit cdeda4c
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/srv/db/postgres/sql/activate-user.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ BEGIN
-- match what the user currently has.
IF EXISTS (SELECT usename FROM pg_stat_activity WHERE usename = username) THEN
SELECT CAST(array_agg(rolname) as varchar[]) INTO cur_roles FROM pg_auth_members JOIN pg_roles ON roleid = pg_roles.oid WHERE member=(SELECT oid FROM pg_roles WHERE rolname = username) AND rolname != 'teleport-auto-user';
-- both `cur_roles` and `roles` may be NULL; we want to work with empty arrays instead.
cur_roles := COALESCE(cur_roles, ARRAY[]::varchar[]);
roles := COALESCE(roles, ARRAY[]::varchar[]);
-- "a <@ b" checks if all unique elements in "a" are contained by
-- "b". Using length check plus "contains" check to avoid sorting.
IF ARRAY_LENGTH(roles, 1) = ARRAY_LENGTH(cur_roles, 1) AND roles <@ cur_roles THEN
IF cardinality(roles) = cardinality(cur_roles) AND roles <@ cur_roles THEN
RETURN;
END IF;
RAISE EXCEPTION SQLSTATE 'TP002' USING MESSAGE = 'TP002: User has active connections and roles have changed';
Expand Down

0 comments on commit cdeda4c

Please sign in to comment.