Get lines of pg_hba.conf with trust method from user with minimal privileges
-
29-12-2020 - |
Question
I try on PostgreSQL 9.3 to get the lines of pg_hba.conf
where the authentication method is trust
from user with minimal privileges. I wrote a function, but it doesn't work:
create function public.get_pghba_with_trust()
returns TABLE (
TYPE text
, DATABASE text
, PGUSER text
, ADDRESS text
, METHOD text)
as
$$
SELECT *
FROM regexp_split_to_table(pg_read_file('pg_hba.conf'),'\n') t(a)
WHERE a ~ '^[^#].*trust\s*$';
$$
language sql
security definer;
This returns an error:
ERROR: return type mismatch in function declared to return record
DETAIL: Final statement returns too few columns.
CONTEXT: SQL function "get_pghba_with_trust"
Grant execute on function
grant execute on function get_pghba_with_trust() to redcheck;
Try other function
CREATE OR REPLACE FUNCTION get_pghba_with_trust() RETURNS text AS $$
DECLARE
trust text;
BEGIN
SELECT * INTO trust from regexp_split_to_table(pg_read_file('pg_hba.conf'),'\n') t(a) WHERE a ~ '^[^#].*trust\s*$';
IF NOT FOUND THEN
RETURN 'not used';
ELSE
RETURN trust;
END IF;
END;
$$ LANGUAGE plpgsql security definer;
Grant execute on function
grant execute on function get_pghba_with_trust() to redcheck;
Try run function get_pghba_with_trust
SELECT * FROM get_pghba_with_trust();
Error:
ERROR: must be superuser TO READ files
CONTEXT: SQL STATEMENT "SELECT * from regexp_split_to_table(pg_read_file('pg_hba.conf'),'\n') t(a) WHERE a ~ '^[^#].*trust\s*$'" PL/pgSQL FUNCTION get_pghba_with_trust() line 5 AT SQL STATEMENT
How get lines of pg_hba.conf on PostgreSQL 9.3 with trust method from user with minimal privileges?
La solution 3
CREATE FUNCTION PUBLIC.list_settings
CREATE FUNCTION PUBLIC.list_settings
() returns setof pg_catalog.pg_settings
AS
$$
SELECT *
FROM pg_catalog.pg_settings;
$$ LANGUAGE SQL security definer;
Then grant execute on that function to your user:
GRANT EXECUTE ON FUNCTION PUBLIC.list_settings() TO the_user;
which then has just to run:
SELECT *
FROM regexp_split_to_table(PUBLIC.list_settings(),'\n') t(a)
WHERE a ~ '^[^#].*trust\s*$';
Or other choice
CREATE FUNCTION f_showfile
CREATE FUNCTION f_showfile(myfile text) RETURNS text AS $x$
BEGIN
RETURN pg_read_file(myfile, 0, 1000000);
END;
$x$ LANGUAGE PLPGSQL SECURITY DEFINER;
GRANT EXECUTE ON FUNCTION public.f_showfile
GRANT EXECUTE ON FUNCTION public.f_showfile (text) TO the_user;
Get lines with trust string from pg_hba.conf
SELECT *
FROM regexp_split_to_table(f_showfile('pg_hba.conf'),'\n') t(a)
WHERE a ~ '^[^#].*trust\s*$';
Get lines with primary_conninfo string from recovery.conf
SELECT *
FROM regexp_split_to_table(f_showfile('recovery.conf'),'\n') t(a)
WHERE a ~ '^ *primary_conninfo';
Autres conseils
You are nearly there, just have to process the output from pg_read_file()
as it returns each line of pg_hba.conf
as a single value. The following query will do the trick:
WITH file (line) AS (
SELECT regexp_split_to_array(a, '\t+')
FROM regexp_split_to_table(pg_read_file('pg_hba.conf'), '\n') AS t(a)
WHERE a ~ '^[^#].*trust\s*$'
)
SELECT line[1] AS type,
line[2] AS database,
line[3] AS username,
CASE WHEN array_length(line, 1) = 4 THEN NULL ELSE line[4] END AS range,
CASE WHEN array_length(line, 1) = 4 THEN line[4] ELSE line[5] END AS method
FROM file;
This might not work in all cases that are possible in pg_hba.conf
, though - you can tweak this query if you need to.
As you already noticed, pg_read_file()
can be run only by superusers. This is the very reason why you need SECURITY DEFINER
on your function. In order to make it work, you have to create the function as a superuser. (Note that changing owner after a non-superuser created the function doesn't work. If this is your case, drop the function first an create it anew, as a superuser this time.)
Starting with PostgreSQL 10, there's a built-in pg_hba_file_rules
system view that provides this information. From https://www.postgresql.org/docs/10/static/view-pg-hba-file-rules.html :
The view pg_hba_file_rules provides a summary of the contents of the client authentication configuration file, pg_hba.conf. A row appears in this view for each non-empty, non-comment line in the file, with annotations indicating whether the rule could be applied successfully.
This view can be helpful for checking whether planned changes in the authentication configuration file will work, or for diagnosing a previous failure. Note that this view reports on the current contents of the file, not on what was last loaded by the server.
The permission to read on this view and the underlying function can be granted to a non-superuser:
grant execute on function pg_catalog.pg_hba_file_rules() to somerole;
grant select on pg_catalog.pg_hba_file_rules to somerole;
which then has just to run:
select * from pg_hba_file_rules WHERE auth_method = 'trust';