Skip to content

Commit 0f2bc84

Browse files
committed
fix: search path and migration grants
search_path not set on pgbouncer.get_auth and later migrations don't apply permissions correctly.
1 parent 75c8517 commit 0f2bc84

File tree

7 files changed

+70
-4
lines changed

7 files changed

+70
-4
lines changed

ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ BEGIN
1414
SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow
1515
WHERE usename = p_usename;
1616
END;
17-
$$ LANGUAGE plpgsql SECURITY DEFINER;
17+
$$ LANGUAGE plpgsql
18+
SET search_path = ''
19+
SECURITY DEFINER;
1820

1921
REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC;
2022
GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- migrate:up
2+
3+
create or replace function pgbouncer.get_auth(p_usename text) returns table (username text, password text)
4+
language plpgsql
5+
set search_path = ''
6+
security definer
7+
as $$
8+
begin
9+
raise debug 'PgBouncer auth request: %', p_usename;
10+
11+
return query
12+
select
13+
rolname::text,
14+
case when rolvaliduntil < now()
15+
then null
16+
else rolpassword::text
17+
end
18+
from pg_authid
19+
where rolname=$1 and rolcanlogin;
20+
end;
21+
$$;
22+
23+
revoke execute on function pgbouncer.get_auth(text) from public;
24+
grant execute on function pgbouncer.get_auth(text) to pgbouncer;
25+
-- migrate:down
26+

migrations/schema-15.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,9 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
477477
--
478478

479479
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
480-
LANGUAGE plpgsql SECURITY DEFINER
480+
LANGUAGE plpgsql
481+
SET search_path = ''
482+
SECURITY DEFINER
481483
AS $_$
482484
begin
483485
raise debug 'PgBouncer auth request: %', p_usename;
@@ -494,6 +496,8 @@ begin
494496
end;
495497
$_$;
496498

499+
REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC;
500+
GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer;
497501

498502
SET default_tablespace = '';
499503

migrations/schema-17.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,9 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
478478
--
479479

480480
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
481-
LANGUAGE plpgsql SECURITY DEFINER
481+
LANGUAGE plpgsql
482+
SET search_path = ''
483+
SECURITY DEFINER
482484
AS $_$
483485
begin
484486
raise debug 'PgBouncer auth request: %', p_usename;
@@ -495,6 +497,8 @@ begin
495497
end;
496498
$_$;
497499

500+
REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC;
501+
GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer;
498502

499503
SET default_tablespace = '';
500504

migrations/schema-orioledb-17.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,9 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
492492
--
493493

494494
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
495-
LANGUAGE plpgsql SECURITY DEFINER
495+
LANGUAGE plpgsql
496+
SET search_path = ''
497+
SECURITY DEFINER
496498
AS $_$
497499
begin
498500
raise debug 'PgBouncer auth request: %', p_usename;
@@ -509,6 +511,8 @@ begin
509511
end;
510512
$_$;
511513

514+
REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC;
515+
GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer;
512516

513517
SET default_tablespace = '';
514518

nix/tests/expected/pgbouncer.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,21 @@ select pgbouncer.get_auth('test_valid_user_password');
8383
(test_valid_user_password,SCRAM-SHA-256$4096:testsaltbase64$storedkeybase64$serverkeybase64)
8484
(1 row)
8585

86+
87+
-- Test pgbouncer.get_auth is executable by the pgbouncer user
88+
set role pgbouncer;
89+
select pgbouncer.get_auth('test_expired_user_password');
90+
get_auth
91+
-------------------------------
92+
(test_expired_user_password,)
93+
(1 row)
94+
reset role;
95+
96+
-- and not other non-superusers
97+
set role postgres;
98+
select pgbouncer.get_auth('test_expired_user_password');
99+
ERROR: permission denied for function get_auth
100+
reset role;
101+
86102
drop role test_expired_user_password;
87103
drop role test_valid_user_password;

nix/tests/sql/pgbouncer.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,15 @@ select pgbouncer.get_auth('test_expired_user_password');
6262

6363
select pgbouncer.get_auth('test_valid_user_password');
6464

65+
-- Test pgbouncer.get_auth is executable by the pgbouncer user
66+
set role pgbouncer;
67+
select pgbouncer.get_auth('test_expired_user_password');
68+
reset role;
69+
70+
-- and not other non-superusers
71+
set role postgres;
72+
select pgbouncer.get_auth('test_expired_user_password');
73+
reset role;
74+
6575
drop role test_expired_user_password;
6676
drop role test_valid_user_password;

0 commit comments

Comments
 (0)