When reading pg_hba.conf and similar files, do not treat @file as an inclusion

unless (1) the @ isn't quoted and (2) the filename isn't empty.  This guards
against unexpectedly treating usernames or other strings in "flat files"
as inclusion requests, as seen in a recent trouble report from Ed L.
The empty-filename case would be guaranteed to misbehave anyway, because our
subsequent path-munging behavior results in trying to read the directory
containing the current input file.

I think this might finally explain the report at
http://archives.postgresql.org/pgsql-bugs/2004-05/msg00132.php
of a crash after printing "authentication file token too long, skipping",
since I was able to duplicate that message (though not a crash) on a
platform where stdio doesn't refuse to read directories.  We never got
far in investigating that problem, but now I'm suspicious that the trigger
condition was an @ in the flat password file.

Back-patch to all active branches since the problem can be demonstrated in all
branches except HEAD.  The test case, creating a user named "@", doesn't cause
a problem in HEAD since we got rid of the flat password file.  Nonetheless it
seems like a good idea to not consider quoted @ as a file inclusion spec,
so I changed HEAD too.
This commit is contained in:
Tom Lane 2010-03-06 00:46:27 +00:00
parent f82e8e7f6f
commit 821ed69bde
2 changed files with 13 additions and 7 deletions

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.116.2.5 2010/03/03 20:31:50 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.116.2.6 2010/03/06 00:46:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -89,8 +89,8 @@ pg_isblank(const char c)
* next line or EOF, whichever comes first. Allow spaces in quoted * next line or EOF, whichever comes first. Allow spaces in quoted
* strings. Terminate on unquoted commas. Handle comments. * strings. Terminate on unquoted commas. Handle comments.
*/ */
void static void
next_token(FILE *fp, char *buf, const int bufsz) next_token(FILE *fp, char *buf, int bufsz, bool *initial_quote)
{ {
int c; int c;
char *start_buf = buf; char *start_buf = buf;
@ -98,6 +98,8 @@ next_token(FILE *fp, char *buf, const int bufsz)
bool in_quote = false; bool in_quote = false;
bool was_quote = false; bool was_quote = false;
*initial_quote = false;
/* Move over initial whitespace and commas */ /* Move over initial whitespace and commas */
while ((c = getc(fp)) != EOF && (pg_isblank(c) || c == ',')) while ((c = getc(fp)) != EOF && (pg_isblank(c) || c == ','))
; ;
@ -149,7 +151,11 @@ next_token(FILE *fp, char *buf, const int bufsz)
was_quote = false; was_quote = false;
if (c == '"') if (c == '"')
{
in_quote = !in_quote; in_quote = !in_quote;
if (buf == start_buf)
*initial_quote = true;
}
c = getc(fp); c = getc(fp);
} }
@ -178,12 +184,13 @@ next_token_expand(FILE *file)
char buf[MAX_TOKEN]; char buf[MAX_TOKEN];
char *comma_str = pstrdup(""); char *comma_str = pstrdup("");
bool trailing_comma; bool trailing_comma;
bool initial_quote;
char *incbuf; char *incbuf;
int needed; int needed;
do do
{ {
next_token(file, buf, sizeof(buf)); next_token(file, buf, sizeof(buf), &initial_quote);
if (!*buf) if (!*buf)
break; break;
@ -196,7 +203,7 @@ next_token_expand(FILE *file)
trailing_comma = false; trailing_comma = false;
/* Is this referencing a file? */ /* Is this referencing a file? */
if (buf[0] == '@') if (!initial_quote && buf[0] == '@' && buf[1] != '\0')
incbuf = tokenize_inc_file(buf + 1); incbuf = tokenize_inc_file(buf + 1);
else else
incbuf = pstrdup(buf); incbuf = pstrdup(buf);

View File

@ -4,7 +4,7 @@
* Interface to hba.c * Interface to hba.c
* *
* *
* $Id: hba.h,v 1.33 2003/04/17 22:26:01 tgl Exp $ * $Id: hba.h,v 1.33.4.1 2010/03/06 00:46:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -45,7 +45,6 @@ typedef struct Port hbaPort;
#define MAX_TOKEN 256 #define MAX_TOKEN 256
extern void next_token(FILE *fp, char *buf, const int bufsz);
extern List **get_user_line(const char *user); extern List **get_user_line(const char *user);
extern void load_hba(void); extern void load_hba(void);
extern void load_ident(void); extern void load_ident(void);