Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 38df84c

Browse files
committed
Eliminate fixed token-length limit in hba.c.
Historically, hba.c limited tokens in the authentication configuration files (pg_hba.conf and pg_ident.conf) to less than 256 bytes. We have seen a few reports of this limit causing problems; notably, for moderately-complex LDAP configurations. Let's get rid of the fixed limit by using a StringInfo instead of a fixed-size buffer. This actually takes less code than before, since we can get rid of a nontrivial error recovery stanza. It's doubtless a hair slower, but parsing the content of the HBA files should in no way be performance-critical. Although this is a pretty straightforward patch, it doesn't seem worth the risk to back-patch given the small number of complaints to date. In released branches, we'll just raise MAX_TOKEN to ameliorate the problem. Discussion: https://postgr.es/m/1588937.1690221208@sss.pgh.pa.us
1 parent 320c311 commit 38df84c

File tree

1 file changed

+26
-48
lines changed

1 file changed

+26
-48
lines changed

src/backend/libpq/hba.c

+26-48
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@
5656
#endif
5757

5858

59-
#define MAX_TOKEN 256
60-
6159
/* callback data for check_network_callback */
6260
typedef struct check_network_data
6361
{
@@ -161,8 +159,8 @@ pg_isblank(const char c)
161159
* commas, beginning of line, and end of line. Blank means space or tab.
162160
*
163161
* Tokens can be delimited by double quotes (this allows the inclusion of
164-
* blanks or '#', but not newlines). As in SQL, write two double-quotes
165-
* to represent a double quote.
162+
* commas, blanks, and '#', but not newlines). As in SQL, write two
163+
* double-quotes to represent a double quote.
166164
*
167165
* Comments (started by an unquoted '#') are skipped, i.e. the remainder
168166
* of the line is ignored.
@@ -171,39 +169,34 @@ pg_isblank(const char c)
171169
* Thus, if a continuation occurs within quoted text or a comment, the
172170
* quoted text or comment is considered to continue to the next line.)
173171
*
174-
* The token, if any, is returned at *buf (a buffer of size bufsz), and
175-
* *lineptr is advanced past the token.
172+
* The token, if any, is returned into buf (replacing any previous
173+
* contents), and *lineptr is advanced past the token.
176174
*
177175
* Also, we set *initial_quote to indicate whether there was quoting before
178176
* the first character. (We use that to prevent "@x" from being treated
179177
* as a file inclusion request. Note that @"x" should be so treated;
180178
* we want to allow that to support embedded spaces in file paths.)
181179
*
182180
* We set *terminating_comma to indicate whether the token is terminated by a
183-
* comma (which is not returned).
181+
* comma (which is not returned, nor advanced over).
184182
*
185-
* In event of an error, log a message at ereport level elevel, and also
186-
* set *err_msg to a string describing the error. Currently the only
187-
* possible error is token too long for buf.
183+
* The only possible error condition is lack of terminating quote, but we
184+
* currently do not detect that, but just return the rest of the line.
188185
*
189-
* If successful: store null-terminated token at *buf and return true.
190-
* If no more tokens on line: set *buf = '\0' and return false.
191-
* If error: fill buf with truncated or misformatted token and return false.
186+
* If successful: store dequoted token in buf and return true.
187+
* If no more tokens on line: set buf to empty and return false.
192188
*/
193189
static bool
194-
next_token(char **lineptr, char *buf, int bufsz,
195-
bool *initial_quote, bool *terminating_comma,
196-
int elevel, char **err_msg)
190+
next_token(char **lineptr, StringInfo buf,
191+
bool *initial_quote, bool *terminating_comma)
197192
{
198193
int c;
199-
char *start_buf = buf;
200-
char *end_buf = buf + (bufsz - 1);
201194
bool in_quote = false;
202195
bool was_quote = false;
203196
bool saw_quote = false;
204197

205-
Assert(end_buf > start_buf);
206-
198+
/* Initialize output parameters */
199+
resetStringInfo(buf);
207200
*initial_quote = false;
208201
*terminating_comma = false;
209202

@@ -226,22 +219,6 @@ next_token(char **lineptr, char *buf, int bufsz,
226219
break;
227220
}
228221

229-
if (buf >= end_buf)
230-
{
231-
*buf = '\0';
232-
ereport(elevel,
233-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
234-
errmsg("authentication file token too long, skipping: \"%s\"",
235-
start_buf)));
236-
*err_msg = "authentication file token too long";
237-
/* Discard remainder of line */
238-
while ((c = (*(*lineptr)++)) != '\0')
239-
;
240-
/* Un-eat the '\0', in case we're called again */
241-
(*lineptr)--;
242-
return false;
243-
}
244-
245222
/* we do not pass back a terminating comma in the token */
246223
if (c == ',' && !in_quote)
247224
{
@@ -250,7 +227,7 @@ next_token(char **lineptr, char *buf, int bufsz,
250227
}
251228

252229
if (c != '"' || was_quote)
253-
*buf++ = c;
230+
appendStringInfoChar(buf, c);
254231

255232
/* Literal double-quote is two double-quotes */
256233
if (in_quote && c == '"')
@@ -262,7 +239,7 @@ next_token(char **lineptr, char *buf, int bufsz,
262239
{
263240
in_quote = !in_quote;
264241
saw_quote = true;
265-
if (buf == start_buf)
242+
if (buf->len == 0)
266243
*initial_quote = true;
267244
}
268245

@@ -275,9 +252,7 @@ next_token(char **lineptr, char *buf, int bufsz,
275252
*/
276253
(*lineptr)--;
277254

278-
*buf = '\0';
279-
280-
return (saw_quote || buf > start_buf);
255+
return (saw_quote || buf->len > 0);
281256
}
282257

283258
/*
@@ -409,21 +384,22 @@ static List *
409384
next_field_expand(const char *filename, char **lineptr,
410385
int elevel, int depth, char **err_msg)
411386
{
412-
char buf[MAX_TOKEN];
387+
StringInfoData buf;
413388
bool trailing_comma;
414389
bool initial_quote;
415390
List *tokens = NIL;
416391

392+
initStringInfo(&buf);
393+
417394
do
418395
{
419-
if (!next_token(lineptr, buf, sizeof(buf),
420-
&initial_quote, &trailing_comma,
421-
elevel, err_msg))
396+
if (!next_token(lineptr, &buf,
397+
&initial_quote, &trailing_comma))
422398
break;
423399

424400
/* Is this referencing a file? */
425-
if (!initial_quote && buf[0] == '@' && buf[1] != '\0')
426-
tokens = tokenize_expand_file(tokens, filename, buf + 1,
401+
if (!initial_quote && buf.len > 1 && buf.data[0] == '@')
402+
tokens = tokenize_expand_file(tokens, filename, buf.data + 1,
427403
elevel, depth + 1, err_msg);
428404
else
429405
{
@@ -434,11 +410,13 @@ next_field_expand(const char *filename, char **lineptr,
434410
* for the list of tokens.
435411
*/
436412
oldcxt = MemoryContextSwitchTo(tokenize_context);
437-
tokens = lappend(tokens, make_auth_token(buf, initial_quote));
413+
tokens = lappend(tokens, make_auth_token(buf.data, initial_quote));
438414
MemoryContextSwitchTo(oldcxt);
439415
}
440416
} while (trailing_comma && (*err_msg == NULL));
441417

418+
pfree(buf.data);
419+
442420
return tokens;
443421
}
444422

0 commit comments

Comments
 (0)