@ -117,7 +117,8 @@ static const char *const UserAuthName[] =
static List * tokenize_inc_file ( List * tokens , const char * outer_filename ,
static List * tokenize_inc_file ( List * tokens , const char * outer_filename ,
const char * inc_filename , int elevel , char * * err_msg ) ;
const char * inc_filename , int elevel ,
int depth , char * * err_msg ) ;
static bool parse_hba_auth_opt ( char * name , char * val , HbaLine * hbaline ,
static bool parse_hba_auth_opt ( char * name , char * val , HbaLine * hbaline ,
int elevel , char * * err_msg ) ;
int elevel , char * * err_msg ) ;
static int regcomp_auth_token ( AuthToken * token , char * filename , int line_num ,
static int regcomp_auth_token ( AuthToken * token , char * filename , int line_num ,
@ -414,7 +415,7 @@ regexec_auth_token(const char *match, AuthToken *token, size_t nmatch,
*/
*/
static List *
static List *
next_field_expand ( const char * filename , char * * lineptr ,
next_field_expand ( const char * filename , char * * lineptr ,
int elevel , char * * err_msg )
int elevel , int depth , char * * err_msg )
{
{
char buf [ MAX_TOKEN ] ;
char buf [ MAX_TOKEN ] ;
bool trailing_comma ;
bool trailing_comma ;
@ -431,7 +432,7 @@ next_field_expand(const char *filename, char **lineptr,
/* Is this referencing a file? */
/* Is this referencing a file? */
if ( ! initial_quote & & buf [ 0 ] = = ' @ ' & & buf [ 1 ] ! = ' \0 ' )
if ( ! initial_quote & & buf [ 0 ] = = ' @ ' & & buf [ 1 ] ! = ' \0 ' )
tokens = tokenize_inc_file ( tokens , filename , buf + 1 ,
tokens = tokenize_inc_file ( tokens , filename , buf + 1 ,
elevel , err_msg ) ;
elevel , depth + 1 , err_msg ) ;
else
else
tokens = lappend ( tokens , make_auth_token ( buf , initial_quote ) ) ;
tokens = lappend ( tokens , make_auth_token ( buf , initial_quote ) ) ;
} while ( trailing_comma & & ( * err_msg = = NULL ) ) ;
} while ( trailing_comma & & ( * err_msg = = NULL ) ) ;
@ -459,6 +460,7 @@ tokenize_inc_file(List *tokens,
const char * outer_filename ,
const char * outer_filename ,
const char * inc_filename ,
const char * inc_filename ,
int elevel ,
int elevel ,
int depth ,
char * * err_msg )
char * * err_msg )
{
{
char * inc_fullname ;
char * inc_fullname ;
@ -468,24 +470,18 @@ tokenize_inc_file(List *tokens,
MemoryContext linecxt ;
MemoryContext linecxt ;
inc_fullname = AbsoluteConfigLocation ( inc_filename , outer_filename ) ;
inc_fullname = AbsoluteConfigLocation ( inc_filename , outer_filename ) ;
inc_file = open_auth_file ( inc_fullname , elevel , depth , err_msg ) ;
inc_file = AllocateFile ( inc_fullname , " r " ) ;
if ( inc_file = = NULL )
if ( inc_file = = NULL )
{
{
int save_errno = errno ;
/* error already logged */
ereport ( elevel ,
( errcode_for_file_access ( ) ,
errmsg ( " could not open secondary authentication file \" @%s \" as \" %s \" : %m " ,
inc_filename , inc_fullname ) ) ) ;
* err_msg = psprintf ( " could not open secondary authentication file \" @%s \" as \" %s \" : %s " ,
inc_filename , inc_fullname , strerror ( save_errno ) ) ;
pfree ( inc_fullname ) ;
pfree ( inc_fullname ) ;
return tokens ;
return tokens ;
}
}
/* There is possible recursion here if the file contains @ */
/* There is possible recursion here if the file contains @ */
linecxt = tokenize_auth_file ( inc_fullname , inc_file , & inc_lines , elevel ) ;
linecxt = tokenize_auth_file ( inc_fullname , inc_file , & inc_lines , elevel ,
depth ) ;
FreeFile ( inc_file ) ;
FreeFile ( inc_file ) ;
pfree ( inc_fullname ) ;
pfree ( inc_fullname ) ;
@ -521,6 +517,59 @@ tokenize_inc_file(List *tokens,
return tokens ;
return tokens ;
}
}
/*
* open_auth_file
* Open the given file .
*
* filename : the absolute path to the target file
* elevel : message logging level
* depth : recursion level when opening the file
* err_msg : details about the error
*
* Return value is the opened file . On error , returns NULL with details
* about the error stored in " err_msg " .
*/
FILE *
open_auth_file ( const char * filename , int elevel , int depth ,
char * * err_msg )
{
FILE * file ;
/*
* Reject too - deep include nesting depth . This is just a safety check to
* avoid dumping core due to stack overflow if an include file loops back
* to itself . The maximum nesting depth is pretty arbitrary .
*/
if ( depth > 10 )
{
ereport ( elevel ,
( errcode_for_file_access ( ) ,
errmsg ( " could not open file \" %s \" : maximum nesting depth exceeded " ,
filename ) ) ) ;
if ( err_msg )
* err_msg = psprintf ( " could not open file \" %s \" : maximum nesting depth exceeded " ,
filename ) ;
return NULL ;
}
file = AllocateFile ( filename , " r " ) ;
if ( file = = NULL )
{
int save_errno = errno ;
ereport ( elevel ,
( errcode_for_file_access ( ) ,
errmsg ( " could not open file \" %s \" : %m " ,
filename ) ) ) ;
if ( err_msg )
* err_msg = psprintf ( " could not open file \" %s \" : %s " ,
filename , strerror ( save_errno ) ) ;
return NULL ;
}
return file ;
}
/*
/*
* tokenize_auth_file
* tokenize_auth_file
* Tokenize the given file .
* Tokenize the given file .
@ -532,6 +581,7 @@ tokenize_inc_file(List *tokens,
* file : the already - opened target file
* file : the already - opened target file
* tok_lines : receives output list
* tok_lines : receives output list
* elevel : message logging level
* elevel : message logging level
* depth : level of recursion when tokenizing the target file
*
*
* Errors are reported by logging messages at ereport level elevel and by
* Errors are reported by logging messages at ereport level elevel and by
* adding TokenizedAuthLine structs containing non - null err_msg fields to the
* adding TokenizedAuthLine structs containing non - null err_msg fields to the
@ -542,7 +592,7 @@ tokenize_inc_file(List *tokens,
*/
*/
MemoryContext
MemoryContext
tokenize_auth_file ( const char * filename , FILE * file , List * * tok_lines ,
tokenize_auth_file ( const char * filename , FILE * file , List * * tok_lines ,
int elevel )
int elevel , int depth )
{
{
int line_number = 1 ;
int line_number = 1 ;
StringInfoData buf ;
StringInfoData buf ;
@ -613,7 +663,7 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
List * current_field ;
List * current_field ;
current_field = next_field_expand ( filename , & lineptr ,
current_field = next_field_expand ( filename , & lineptr ,
elevel , & err_msg ) ;
elevel , depth , & err_msg ) ;
/* add field to line, unless we are at EOL or comment start */
/* add field to line, unless we are at EOL or comment start */
if ( current_field ! = NIL )
if ( current_field ! = NIL )
current_line = lappend ( current_line , current_field ) ;
current_line = lappend ( current_line , current_field ) ;
@ -2332,17 +2382,14 @@ load_hba(void)
MemoryContext oldcxt ;
MemoryContext oldcxt ;
MemoryContext hbacxt ;
MemoryContext hbacxt ;
file = AllocateF ile( HbaFileName , " r " ) ;
file = open_auth_f ile( HbaFileName , LOG , 0 , NULL ) ;
if ( file = = NULL )
if ( file = = NULL )
{
{
ereport ( LOG ,
/* error already logged */
( errcode_for_file_access ( ) ,
errmsg ( " could not open configuration file \" %s \" : %m " ,
HbaFileName ) ) ) ;
return false ;
return false ;
}
}
linecxt = tokenize_auth_file ( HbaFileName , file , & hba_lines , LOG ) ;
linecxt = tokenize_auth_file ( HbaFileName , file , & hba_lines , LOG , 0 ) ;
FreeFile ( file ) ;
FreeFile ( file ) ;
/* Now parse all the lines */
/* Now parse all the lines */
@ -2703,18 +2750,15 @@ load_ident(void)
MemoryContext ident_context ;
MemoryContext ident_context ;
IdentLine * newline ;
IdentLine * newline ;
file = AllocateFile ( IdentFileName , " r " ) ;
/* not FATAL ... we just won't do any special ident maps */
file = open_auth_file ( IdentFileName , LOG , 0 , NULL ) ;
if ( file = = NULL )
if ( file = = NULL )
{
{
/* not fatal ... we just won't do any special ident maps */
/* error already logged */
ereport ( LOG ,
( errcode_for_file_access ( ) ,
errmsg ( " could not open usermap file \" %s \" : %m " ,
IdentFileName ) ) ) ;
return false ;
return false ;
}
}
linecxt = tokenize_auth_file ( IdentFileName , file , & ident_lines , LOG ) ;
linecxt = tokenize_auth_file ( IdentFileName , file , & ident_lines , LOG , 0 ) ;
FreeFile ( file ) ;
FreeFile ( file ) ;
/* Now parse all the lines */
/* Now parse all the lines */