Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcbe6e48

Browse files
committed
Add TAP tests for include directives in HBA end ident files
This commit adds a basic set of authentication tests to check after thenew keywords added bya54b658 for the HBA and ident files, aka"include", "include_if_exists" and "include_dir".This includes checks for all the positive cases originally proposed,where valid contents are generated for the HBA and ident files withoutany errors happening in the server, checking as well the contents oftheir respective system views. The error handling will be evaluatedseparately (-DEXEC_BACKEND makes that trickier), and what we have herecovers most of the ground I would like to see covered if one manipulatesthe tokenization logic of hba.c in the future.While on it, some coverage is added for files included with '@' fordatabase or user name lists.Author: Julien RouhaudReviewed-by: Michael PaquierDiscussion:https://postgr.es/m/20220223045959.35ipdsvbxcstrhya@jrouhaud
1 parentec25ba6 commitcbe6e48

File tree

2 files changed

+299
-0
lines changed

2 files changed

+299
-0
lines changed

‎src/test/authentication/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ tests += {
77
't/001_password.pl',
88
't/002_saslprep.pl',
99
't/003_peer.pl',
10+
't/004_file_inclusion.pl',
1011
],
1112
},
1213
}
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
2+
# Copyright (c) 2021-2022, PostgreSQL Global Development Group
3+
4+
# Tests for include directives in HBA and ident files. This test can
5+
# only run with Unix-domain sockets.
6+
7+
use strict;
8+
use warnings;
9+
use PostgreSQL::Test::Cluster;
10+
use PostgreSQL::Test::Utils;
11+
use File::Basenameqw(basename);
12+
use Test::More;
13+
use Data::Dumper;
14+
if (!$use_unix_sockets)
15+
{
16+
planskip_all=>
17+
"authentication tests cannot run without Unix-domain sockets";
18+
}
19+
20+
# Stores the number of lines created for each file. hba_rule and ident_rule
21+
# are used to respectively track pg_hba_file_rules.rule_number and
22+
# pg_ident_file_mappings.map_number, which are the global counters associated
23+
# to each view tracking the priority of each entry processed.
24+
my%line_counters = ('hba_rule'=> 0,'ident_rule'=> 0);
25+
26+
# Add some data to the given HBA configuration file, generating the contents
27+
# expected to match pg_hba_file_rules.
28+
#
29+
# Note that this function maintains %line_counters, used to generate the
30+
# catalog output for file lines and rule numbers.
31+
#
32+
# If the entry starts with "include", the function does not increase
33+
# the general hba rule number as an include directive generates no data
34+
# in pg_hba_file_rules.
35+
#
36+
# This function returns the entry of pg_hba_file_rules expected when this
37+
# is loaded by the backend.
38+
subadd_hba_line
39+
{
40+
my$node =shift;
41+
my$filename =shift;
42+
my$entry =shift;
43+
my$globline;
44+
my$fileline;
45+
my@tokens;
46+
my$line;
47+
48+
# Append the entry to the given file
49+
$node->append_conf($filename,$entry);
50+
51+
my$base_filename = basename($filename);
52+
53+
# Get the current %line_counters for the file.
54+
if (notdefined$line_counters{$filename})
55+
{
56+
$line_counters{$filename} = 0;
57+
}
58+
$fileline = ++$line_counters{$filename};
59+
60+
# Include directive, that does not generate a view entry.
61+
return''if ($entry =~qr/^include/);
62+
63+
# Increment pg_hba_file_rules.rule_number and save it.
64+
$globline = ++$line_counters{'hba_rule'};
65+
66+
# Generate the expected pg_hba_file_rules line
67+
@tokens =split(//,$entry);
68+
$tokens[1] ='{' .$tokens[1] .'}';# database
69+
$tokens[2] ='{' .$tokens[2] .'}';# user_name
70+
71+
# Append empty options and error
72+
push@tokens,'';
73+
push@tokens,'';
74+
75+
# Final line expected, output of the SQL query.
76+
$line ="";
77+
$line .="\n"if ($globline > 1);
78+
$line .="$globline|$base_filename|$fileline|";
79+
$line .=join('|',@tokens);
80+
81+
return$line;
82+
}
83+
84+
# Add some data to the given ident configuration file, generating the
85+
# contents expected to match pg_ident_file_mappings.
86+
#
87+
# Note that this function maintains %line_counters, generating catalog
88+
# entries for the file line and the map number.
89+
#
90+
# If the entry starts with "include", the function does not increase
91+
# the general map number as an include directive generates no data in
92+
# pg_ident_file_mappings.
93+
#
94+
# This works pretty much the same as add_hba_line() above, except that it
95+
# returns an entry to match with pg_ident_file_mappings.
96+
subadd_ident_line
97+
{
98+
my$node =shift;
99+
my$filename =shift;
100+
my$entry =shift;
101+
my$globline;
102+
my$fileline;
103+
my@tokens;
104+
my$line;
105+
106+
my$base_filename = basename($filename);
107+
108+
# Append the entry to the given file
109+
$node->append_conf($filename,$entry);
110+
111+
# Get the current %line_counters counter for the file
112+
if (notdefined$line_counters{$filename})
113+
{
114+
$line_counters{$filename} = 0;
115+
}
116+
$fileline = ++$line_counters{$filename};
117+
118+
# Include directive, that does not generate a view entry.
119+
return''if ($entry =~qr/^include/);
120+
121+
# Increment pg_ident_file_mappings.map_number and get it.
122+
$globline = ++$line_counters{'ident_rule'};
123+
124+
# Generate the expected pg_ident_file_mappings line
125+
@tokens =split(//,$entry);
126+
# Append empty error
127+
push@tokens,'';
128+
129+
# Final line expected, output of the SQL query.
130+
$line ="";
131+
$line .="\n"if ($globline > 1);
132+
$line .="$globline|$base_filename|$fileline|";
133+
$line .=join('|',@tokens);
134+
135+
return$line;
136+
}
137+
138+
# Locations for the entry points of the HBA and ident files.
139+
my$hba_file ='subdir1/pg_hba_custom.conf';
140+
my$ident_file ='subdir2/pg_ident_custom.conf';
141+
142+
my$node = PostgreSQL::Test::Cluster->new('primary');
143+
$node->init;
144+
$node->start;
145+
146+
my$data_dir =$node->data_dir;
147+
148+
note"Generating HBA structure with include directives";
149+
150+
my$hba_expected ='';
151+
my$ident_expected ='';
152+
153+
# customise main auth file names
154+
$node->safe_psql('postgres',
155+
"ALTER SYSTEM SET hba_file = '$data_dir/$hba_file'");
156+
$node->safe_psql('postgres',
157+
"ALTER SYSTEM SET ident_file = '$data_dir/$ident_file'");
158+
159+
# Remove the original ones, this node links to non-default ones now.
160+
unlink("$data_dir/pg_hba.conf");
161+
unlink("$data_dir/pg_ident.conf");
162+
163+
# Generate HBA contents with include directives.
164+
mkdir("$data_dir/subdir1");
165+
mkdir("$data_dir/hba_inc");
166+
mkdir("$data_dir/hba_inc_if");
167+
mkdir("$data_dir/hba_pos");
168+
169+
# First, make sure that we will always be able to connect.
170+
$hba_expected .= add_hba_line($node,"$hba_file",'local all all trust');
171+
172+
# "include". Note that as $hba_file is located in $data_dir/subdir1,
173+
# pg_hba_pre.conf is located at the root of the data directory.
174+
$hba_expected .=
175+
add_hba_line($node,"$hba_file","include ../pg_hba_pre.conf");
176+
$hba_expected .=
177+
add_hba_line($node,'pg_hba_pre.conf',"local pre all reject");
178+
$hba_expected .= add_hba_line($node,"$hba_file","local all all reject");
179+
add_hba_line($node,"$hba_file","include ../hba_pos/pg_hba_pos.conf");
180+
$hba_expected .=
181+
add_hba_line($node,'hba_pos/pg_hba_pos.conf',"local pos all reject");
182+
# When an include directive refers to a relative path, it is compiled
183+
# from the base location of the file loaded from.
184+
$hba_expected .=
185+
add_hba_line($node,'hba_pos/pg_hba_pos.conf',"include pg_hba_pos2.conf");
186+
$hba_expected .=
187+
add_hba_line($node,'hba_pos/pg_hba_pos2.conf',"local pos2 all reject");
188+
$hba_expected .=
189+
add_hba_line($node,'hba_pos/pg_hba_pos2.conf',"local pos3 all reject");
190+
191+
# include_if_exists data, nothing generated for the catalog.
192+
# Missing file, no catalog entries.
193+
$hba_expected .=
194+
add_hba_line($node,"$hba_file","include_if_exists ../hba_inc_if/none");
195+
# File with some contents loaded.
196+
$hba_expected .=
197+
add_hba_line($node,"$hba_file","include_if_exists ../hba_inc_if/some");
198+
$hba_expected .=
199+
add_hba_line($node,'hba_inc_if/some',"local if_some all reject");
200+
201+
# include_dir
202+
$hba_expected .= add_hba_line($node,"$hba_file","include_dir ../hba_inc");
203+
$hba_expected .=
204+
add_hba_line($node,'hba_inc/01_z.conf',"local dir_z all reject");
205+
$hba_expected .=
206+
add_hba_line($node,'hba_inc/02_a.conf',"local dir_a all reject");
207+
# Garbage file not suffixed by .conf, so it will be ignored.
208+
$node->append_conf('hba_inc/garbageconf',"should not be included");
209+
210+
# Authentication file expanded in an existing entry for database names.
211+
# As it is expanded, ignore the output generated.
212+
add_hba_line($node,$hba_file,'local @../dbnames.conf all reject');
213+
$node->append_conf('dbnames.conf',"db1");
214+
$node->append_conf('dbnames.conf',"db3");
215+
$hba_expected .="\n"
216+
.$line_counters{'hba_rule'} ."|"
217+
. basename($hba_file) ."|"
218+
.$line_counters{$hba_file}
219+
.'|local|{db1,db3}|{all}|reject||';
220+
221+
note"Generating ident structure with include directives";
222+
223+
mkdir("$data_dir/subdir2");
224+
mkdir("$data_dir/ident_inc");
225+
mkdir("$data_dir/ident_inc_if");
226+
mkdir("$data_dir/ident_pos");
227+
228+
# include. Note that pg_ident_pre.conf is located at the root of the data
229+
# directory.
230+
$ident_expected .=
231+
add_ident_line($node,"$ident_file","include ../pg_ident_pre.conf");
232+
$ident_expected .= add_ident_line($node,'pg_ident_pre.conf',"pre foo bar");
233+
$ident_expected .= add_ident_line($node,"$ident_file","test a b");
234+
$ident_expected .= add_ident_line($node,"$ident_file",
235+
"include ../ident_pos/pg_ident_pos.conf");
236+
$ident_expected .=
237+
add_ident_line($node,'ident_pos/pg_ident_pos.conf',"pos foo bar");
238+
# When an include directive refers to a relative path, it is compiled
239+
# from the base location of the file loaded from.
240+
$ident_expected .= add_ident_line($node,'ident_pos/pg_ident_pos.conf',
241+
"include pg_ident_pos2.conf");
242+
$ident_expected .=
243+
add_ident_line($node,'ident_pos/pg_ident_pos2.conf',"pos2 foo bar");
244+
$ident_expected .=
245+
add_ident_line($node,'ident_pos/pg_ident_pos2.conf',"pos3 foo bar");
246+
247+
# include_if_exists
248+
# Missing file, no catalog entries.
249+
$ident_expected .= add_ident_line($node,"$ident_file",
250+
"include_if_exists ../ident_inc_if/none");
251+
# File with some contents loaded.
252+
$ident_expected .= add_ident_line($node,"$ident_file",
253+
"include_if_exists ../ident_inc_if/some");
254+
$ident_expected .=
255+
add_ident_line($node,'ident_inc_if/some',"if_some foo bar");
256+
257+
# include_dir
258+
$ident_expected .=
259+
add_ident_line($node,"$ident_file","include_dir ../ident_inc");
260+
$ident_expected .=
261+
add_ident_line($node,'ident_inc/01_z.conf',"dir_z foo bar");
262+
$ident_expected .=
263+
add_ident_line($node,'ident_inc/02_a.conf',"dir_a foo bar");
264+
# Garbage file not suffixed by .conf, so it will be ignored.
265+
$node->append_conf('ident_inc/garbageconf',"should not be included");
266+
267+
$node->restart;
268+
269+
# Note that the base path is filtered out, keeping only the file name
270+
# to bypass portability issues. The configuration files had better
271+
# have unique names.
272+
my$contents =$node->safe_psql(
273+
'postgres',
274+
qq(SELECT rule_number,
275+
regexp_replace(file_name, '.*/', ''),
276+
line_number,
277+
type,
278+
database,
279+
user_name,
280+
auth_method,
281+
options,
282+
error
283+
FROM pg_hba_file_rules ORDER BY rule_number;));
284+
is($contents,$hba_expected,'check contents of pg_hba_file_rules');
285+
286+
$contents =$node->safe_psql(
287+
'postgres',
288+
qq(SELECT map_number,
289+
regexp_replace(file_name, '.*/', ''),
290+
line_number,
291+
map_name,
292+
sys_name,
293+
pg_username,
294+
error
295+
FROM pg_ident_file_mappings ORDER BY map_number));
296+
is($contents,$ident_expected,'check contents of pg_ident_file_mappings');
297+
298+
done_testing();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp