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

Commit3c4e26a

Browse files
committed
In username-map substitution, cope with more than one \1.
If the system-name field of a pg_ident.conf line is a regexcontaining capturing parentheses, you can write \1 in theuser-name field to represent the captured part of the systemname. But what happens if you write \1 more than once?The only reasonable expectation IMO is that each \1 getsreplaced, but presently our code replaces only the first.Fix that.Also, improve the tests for this feature to exercise caseswhere a non-empty string needs to be substituted for \1.The previous testing didn't inspire much faith that itwas verifying correct operation of the substitution code.Given the lack of field complaints about this, I don'tfeel a need to back-patch.Reported-by: David G. Johnston <david.g.johnston@gmail.com>Author: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/CAKFQuwZu6kZ8ZPvJ3pWXig+6UX4nTVK-hdL_ZS3fSdps=RJQQQ@mail.gmail.com
1 parent092f3c6 commit3c4e26a

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

‎src/backend/libpq/hba.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,8 +2873,11 @@ check_ident_usermap(IdentLine *identLine, const char *usermap_name,
28732873
!token_has_regexp(identLine->pg_user)&&
28742874
(ofs=strstr(identLine->pg_user->string,"\\1"))!=NULL)
28752875
{
2876+
constchar*repl_str;
2877+
size_trepl_len;
2878+
char*old_pg_user;
28762879
char*expanded_pg_user;
2877-
intoffset;
2880+
size_toffset;
28782881

28792882
/* substitution of the first argument requested */
28802883
if (matches[1].rm_so<0)
@@ -2886,18 +2889,33 @@ check_ident_usermap(IdentLine *identLine, const char *usermap_name,
28862889
*error_p= true;
28872890
return;
28882891
}
2892+
repl_str=system_user+matches[1].rm_so;
2893+
repl_len=matches[1].rm_eo-matches[1].rm_so;
28892894

28902895
/*
2891-
* length: original length minus length of \1 plus length of match
2892-
* plus null terminator
2896+
* It's allowed to have more than one \1 in the string, and we'll
2897+
* replace them all. But that's pretty unusual so we optimize on
2898+
* the assumption of only one occurrence, which motivates doing
2899+
* repeated replacements instead of making two passes over the
2900+
* string to determine the final length right away.
28932901
*/
2894-
expanded_pg_user=palloc0(strlen(identLine->pg_user->string)-2+ (matches[1].rm_eo-matches[1].rm_so)+1);
2895-
offset=ofs-identLine->pg_user->string;
2896-
memcpy(expanded_pg_user,identLine->pg_user->string,offset);
2897-
memcpy(expanded_pg_user+offset,
2898-
system_user+matches[1].rm_so,
2899-
matches[1].rm_eo-matches[1].rm_so);
2900-
strcat(expanded_pg_user,ofs+2);
2902+
old_pg_user=identLine->pg_user->string;
2903+
do
2904+
{
2905+
/*
2906+
* length: current length minus length of \1 plus length of
2907+
* replacement plus null terminator
2908+
*/
2909+
expanded_pg_user=palloc(strlen(old_pg_user)-2+repl_len+1);
2910+
/* ofs points into the old_pg_user string at this point */
2911+
offset=ofs-old_pg_user;
2912+
memcpy(expanded_pg_user,old_pg_user,offset);
2913+
memcpy(expanded_pg_user+offset,repl_str,repl_len);
2914+
strcpy(expanded_pg_user+offset+repl_len,ofs+2);
2915+
if (old_pg_user!=identLine->pg_user->string)
2916+
pfree(old_pg_user);
2917+
old_pg_user=expanded_pg_user;
2918+
}while ((ofs=strstr(old_pg_user+offset+repl_len,"\\1"))!=NULL);
29012919

29022920
/*
29032921
* Mark the token as quoted, so it will only be compared literally

‎src/test/authentication/t/003_peer.pl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ sub test_role
171171

172172
# Test with regular expression in user name map.
173173
# Extract the last 3 characters from the system_user
174-
# or the entire system_user (if its length is <= -3).
174+
# or the entire system_user name (if its length is <= 3).
175+
# We trust this will not include any regex metacharacters.
175176
my$regex_test_string =substr($system_user, -3);
176177

177178
# Success as the system user regular expression matches.
@@ -210,12 +211,17 @@ sub test_role
210211
log_like=>
211212
[qr/connection authenticated: identity="$system_user" method=peer/]);
212213

214+
# Create target role for \1 tests.
215+
my$mapped_name ="test${regex_test_string}map${regex_test_string}user";
216+
$node->safe_psql('postgres',"CREATE ROLE$mapped_name LOGIN");
217+
213218
# Success as the regular expression matches and \1 is replaced in the given
214219
# subexpression.
215-
reset_pg_ident($node,'mypeermap',qq{/^$system_user(.*)\$},'test\1mapuser');
220+
reset_pg_ident($node,'mypeermap',qq{/^.*($regex_test_string)\$},
221+
'test\1map\1user');
216222
test_role(
217223
$node,
218-
qq{testmapuser},
224+
$mapped_name,
219225
'peer',
220226
0,
221227
'with regular expression in user name map with \1 replaced',
@@ -224,11 +230,11 @@ sub test_role
224230

225231
# Success as the regular expression matches and \1 is replaced in the given
226232
# subexpression, even if quoted.
227-
reset_pg_ident($node,'mypeermap',qq{/^$system_user(.*)\$},
228-
'"test\1mapuser"');
233+
reset_pg_ident($node,'mypeermap',qq{/^.*($regex_test_string)\$},
234+
'"test\1map\1user"');
229235
test_role(
230236
$node,
231-
qq{testmapuser},
237+
$mapped_name,
232238
'peer',
233239
0,
234240
'with regular expression in user name map with quoted \1 replaced',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp