Add error context callback when tokenizing authentication files

The parsing of the authentication files for HBA and ident entries
happens in two phases:
- Tokenization of the files, creating a list of TokenizedAuthLines.
- Validation of the HBA and ident entries, building a set of HbaLines or
IdentLines.

The second phase doing the validation provides already some error
context about the configuration file and the line where a problem
happens, but there is no such information in the first phase when
tokenizing the files.  This commit adds an ErrorContextCallback in
tokenize_auth_file(), with a context made of the line number and the
configuration file name involved in a problem.  This is useful for files
included in an HBA file for user and database lists, and it will become
much more handy to track problems for files included via a potential
@include[_dir,_if_exists].

The error context is registered so as the full chain of events is
reported when using cascaded inclusions when for example
tokenize_auth_file() recurses over itself on new files, displaying one
context line for each file gone through when tokenizing things.

Author: Michael Paquier
Reviewed-by: Julien Rouhaud
Discussion: https://postgr.es/m/Y2xUBJ+S+Z0zbxRW@paquier.xyz
This commit is contained in:
Michael Paquier 2022-11-14 11:58:10 +09:00
parent 783e8c69cb
commit ad6c52846f
2 changed files with 32 additions and 0 deletions

View File

@ -66,6 +66,11 @@ typedef struct check_network_data
bool result; /* set to true if match */
} check_network_data;
typedef struct
{
const char *filename;
int linenum;
} tokenize_error_callback_arg;
#define token_has_regexp(t) (t->regex != NULL)
#define token_is_keyword(t, k) (!t->quoted && strcmp(t->string, k) == 0)
@ -125,6 +130,7 @@ static int regcomp_auth_token(AuthToken *token, char *filename, int line_num,
char **err_msg, int elevel);
static int regexec_auth_token(const char *match, AuthToken *token,
size_t nmatch, regmatch_t pmatch[]);
static void tokenize_error_callback(void *arg);
/*
@ -570,6 +576,18 @@ open_auth_file(const char *filename, int elevel, int depth,
return file;
}
/*
* error context callback for tokenize_auth_file()
*/
static void
tokenize_error_callback(void *arg)
{
tokenize_error_callback_arg *callback_arg = (tokenize_error_callback_arg *) arg;
errcontext("line %d of configuration file \"%s\"",
callback_arg->linenum, callback_arg->filename);
}
/*
* tokenize_auth_file
* Tokenize the given file.
@ -598,6 +616,16 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
StringInfoData buf;
MemoryContext linecxt;
MemoryContext oldcxt;
ErrorContextCallback tokenerrcontext;
tokenize_error_callback_arg callback_arg;
callback_arg.filename = filename;
callback_arg.linenum = line_number;
tokenerrcontext.callback = tokenize_error_callback;
tokenerrcontext.arg = (void *) &callback_arg;
tokenerrcontext.previous = error_context_stack;
error_context_stack = &tokenerrcontext;
linecxt = AllocSetContextCreate(CurrentMemoryContext,
"tokenize_auth_file",
@ -686,10 +714,13 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
}
line_number += continuations + 1;
callback_arg.linenum = line_number;
}
MemoryContextSwitchTo(oldcxt);
error_context_stack = tokenerrcontext.previous;
return linecxt;
}

View File

@ -3723,6 +3723,7 @@ timeout_params
timerCA
tlist_vinfo
toast_compress_header
tokenize_error_callback_arg
transferMode
transfer_thread_arg
trgm