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

Lines changed: 26 additions & 48 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy