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,
int elevel, char **err_msg);
static int regcomp_auth_token(AuthToken *token, char *filename, int line_num,
*/
static List *
next_field_expand(const char *filename, char **lineptr,
- int elevel, char **err_msg)
+ int elevel, int depth, char **err_msg)
{
char buf[MAX_TOKEN];
bool trailing_comma;
/* Is this referencing a file? */
if (!initial_quote && buf[0] == '@' && buf[1] != '\0')
tokens = tokenize_inc_file(tokens, filename, buf + 1,
- elevel, err_msg);
+ elevel, depth + 1, err_msg);
else
tokens = lappend(tokens, make_auth_token(buf, initial_quote));
} while (trailing_comma && (*err_msg == NULL));
const char *outer_filename,
const char *inc_filename,
int elevel,
+ int depth,
char **err_msg)
{
char *inc_fullname;
MemoryContext linecxt;
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)
{
- int save_errno = errno;
-
- 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));
+ /* error already logged */
pfree(inc_fullname);
return tokens;
}
/* 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);
pfree(inc_fullname);
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 the given file.
* file: the already-opened target file
* tok_lines: receives output list
* 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
* adding TokenizedAuthLine structs containing non-null err_msg fields to the
*/
MemoryContext
tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
- int elevel)
+ int elevel, int depth)
{
int line_number = 1;
StringInfoData buf;
List *current_field;
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 */
if (current_field != NIL)
current_line = lappend(current_line, current_field);
MemoryContext oldcxt;
MemoryContext hbacxt;
- file = AllocateFile(HbaFileName, "r");
+ file = open_auth_file(HbaFileName, LOG, 0, NULL);
if (file == NULL)
{
- ereport(LOG,
- (errcode_for_file_access(),
- errmsg("could not open configuration file \"%s\": %m",
- HbaFileName)));
+ /* error already logged */
return false;
}
- linecxt = tokenize_auth_file(HbaFileName, file, &hba_lines, LOG);
+ linecxt = tokenize_auth_file(HbaFileName, file, &hba_lines, LOG, 0);
FreeFile(file);
/* Now parse all the lines */
MemoryContext ident_context;
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)
{
- /* not fatal ... we just won't do any special ident maps */
- ereport(LOG,
- (errcode_for_file_access(),
- errmsg("could not open usermap file \"%s\": %m",
- IdentFileName)));
+ /* error already logged */
return false;
}
- linecxt = tokenize_auth_file(IdentFileName, file, &ident_lines, LOG);
+ linecxt = tokenize_auth_file(IdentFileName, file, &ident_lines, LOG, 0);
FreeFile(file);
/* Now parse all the lines */
* (Most other error conditions should result in a message in a view
* entry.)
*/
- file = AllocateFile(HbaFileName, "r");
- if (file == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open configuration file \"%s\": %m",
- HbaFileName)));
-
- linecxt = tokenize_auth_file(HbaFileName, file, &hba_lines, DEBUG3);
+ file = open_auth_file(HbaFileName, ERROR, 0, NULL);
+
+ linecxt = tokenize_auth_file(HbaFileName, file, &hba_lines, DEBUG3, 0);
FreeFile(file);
/* Now parse all the lines */
* (Most other error conditions should result in a message in a view
* entry.)
*/
- file = AllocateFile(IdentFileName, "r");
- if (file == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open usermap file \"%s\": %m",
- IdentFileName)));
-
- linecxt = tokenize_auth_file(IdentFileName, file, &ident_lines, DEBUG3);
+ file = open_auth_file(IdentFileName, ERROR, 0, NULL);
+
+ linecxt = tokenize_auth_file(IdentFileName, file, &ident_lines, DEBUG3, 0);
FreeFile(file);
/* Now parse all the lines */