mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-01 19:45:33 +08:00
Add support for file inclusions in HBA and ident configuration files
pg_hba.conf and pg_ident.conf gain support for three record keywords: - "include", to include a file. - "include_if_exists", to include a file, ignoring it if missing. - "include_dir", to include a directory of files. These are classified by name (C locale, mostly) and need to be prefixed by ".conf", hence following the same rules as GUCs. This commit relies on the refactoring pieces done inefc9816
,ad6c528
,783e8c6
and1b73d0b
, adding a small wrapper to build a list of TokenizedAuthLines (tokenize_include_file), and the code is shaped to offer some symmetry with what is done for GUCs with the same options. pg_hba_file_rules and pg_ident_file_mappings gain a new field called file_name, to track from which file a record is located, taking advantage of the addition of rule_number inc591300
to offer an organized view of the HBA or ident records loaded. Bump catalog version. Author: Julien Rouhaud Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/20220223045959.35ipdsvbxcstrhya@jrouhaud
This commit is contained in:
parent
d09dbeb9bd
commit
a54b658ce7
@ -89,8 +89,8 @@
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Each record specifies a connection type, a client IP address range
|
Each authentication record specifies a connection type, a client IP address
|
||||||
(if relevant for the connection type), a database name, a user name,
|
range (if relevant for the connection type), a database name, a user name,
|
||||||
and the authentication method to be used for connections matching
|
and the authentication method to be used for connections matching
|
||||||
these parameters. The first record with a matching connection type,
|
these parameters. The first record with a matching connection type,
|
||||||
client address, requested database, and user name is used to perform
|
client address, requested database, and user name is used to perform
|
||||||
@ -100,20 +100,38 @@
|
|||||||
access is denied.
|
access is denied.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Each record can be an include directive or an authentication record.
|
||||||
|
Include directives specify files that can be included, that contain
|
||||||
|
additional records. The records will be inserted in place of the
|
||||||
|
include records. These records only contain two fields:
|
||||||
|
<literal>include</literal>, <literal>include_if_exists</literal> or
|
||||||
|
<literal>include_dir</literal> directive and the file or directory to be
|
||||||
|
included. The file or directory can be a relative of absolute path, and can
|
||||||
|
be double-quoted. For the <literal>include_dir</literal> form, all files
|
||||||
|
not starting with a <literal>.</literal> and ending with
|
||||||
|
<literal>.conf</literal> will be included. Multiple files within an include
|
||||||
|
directory are processed in file name order (according to C locale rules,
|
||||||
|
i.e., numbers before letters, and uppercase letters before lowercase ones).
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A record can have several formats:
|
A record can have several formats:
|
||||||
<synopsis>
|
<synopsis>
|
||||||
local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
|
||||||
|
include <replaceable>file</replaceable>
|
||||||
|
include_if_exists <replaceable>file</replaceable>
|
||||||
|
include_dir <replaceable>directory</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
The meaning of the fields is as follows:
|
The meaning of the fields is as follows:
|
||||||
|
|
||||||
@ -655,6 +673,39 @@ openssl x509 -in myclient.crt -noout --subject -nameopt RFC2253 | sed "s/^subjec
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>include</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This line will be replaced by the contents of the given file.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>include_if_exists</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This line will be replaced by the content of the given file if the
|
||||||
|
file exists. Otherwise, a message is logged to indicate that the file
|
||||||
|
has been skipped.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>include_dir</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This line will be replaced by the contents of all the files found in
|
||||||
|
the directory, if they don't start with a <literal>.</literal> and end
|
||||||
|
with <literal>.conf</literal>, processed in file name order (according
|
||||||
|
to C locale rules, i.e., numbers before letters, and uppercase letters
|
||||||
|
before lowercase ones).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -863,9 +914,12 @@ local db1,db2,@demodbs all md5
|
|||||||
cluster's data directory. (It is possible to place the map file
|
cluster's data directory. (It is possible to place the map file
|
||||||
elsewhere, however; see the <xref linkend="guc-ident-file"/>
|
elsewhere, however; see the <xref linkend="guc-ident-file"/>
|
||||||
configuration parameter.)
|
configuration parameter.)
|
||||||
The ident map file contains lines of the general form:
|
The ident map file contains lines of the general forms:
|
||||||
<synopsis>
|
<synopsis>
|
||||||
<replaceable>map-name</replaceable> <replaceable>system-username</replaceable> <replaceable>database-username</replaceable>
|
<replaceable>map-name</replaceable> <replaceable>system-username</replaceable> <replaceable>database-username</replaceable>
|
||||||
|
<replaceable>include</replaceable> <replaceable>file</replaceable>
|
||||||
|
<replaceable>include_if_exists</replaceable> <replaceable>file</replaceable>
|
||||||
|
<replaceable>include_dir</replaceable> <replaceable>directory</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
Comments, whitespace and line continuations are handled in the same way as in
|
Comments, whitespace and line continuations are handled in the same way as in
|
||||||
<filename>pg_hba.conf</filename>. The
|
<filename>pg_hba.conf</filename>. The
|
||||||
@ -875,6 +929,10 @@ local db1,db2,@demodbs all md5
|
|||||||
database user name. The same <replaceable>map-name</replaceable> can be
|
database user name. The same <replaceable>map-name</replaceable> can be
|
||||||
used repeatedly to specify multiple user-mappings within a single map.
|
used repeatedly to specify multiple user-mappings within a single map.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
As for <filename>pg_hba.conf</filename>, the lines in this file can
|
||||||
|
be include directives, following the same rules.
|
||||||
|
</para>
|
||||||
<para>
|
<para>
|
||||||
There is no restriction regarding how many database users a given
|
There is no restriction regarding how many database users a given
|
||||||
operating system user can correspond to, nor vice versa. Thus, entries
|
operating system user can correspond to, nor vice versa. Thus, entries
|
||||||
|
@ -1002,12 +1002,21 @@
|
|||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
|
<structfield>file_name</structfield> <type>text</type>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Name of the file containing this rule
|
||||||
|
</para></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry role="catalog_table_entry"><para role="column_definition">
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
<structfield>line_number</structfield> <type>int4</type>
|
<structfield>line_number</structfield> <type>int4</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Line number of this rule in <filename>pg_hba.conf</filename>
|
Line number of this rule in <literal>file_name</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -1152,12 +1161,21 @@
|
|||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
|
<structfield>file_name</structfield> <type>text</type>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Name of the file containing this map
|
||||||
|
</para></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry role="catalog_table_entry"><para role="column_definition">
|
<entry role="catalog_table_entry"><para role="column_definition">
|
||||||
<structfield>line_number</structfield> <type>int4</type>
|
<structfield>line_number</structfield> <type>int4</type>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Line number of this map in <filename>pg_ident.conf</filename>
|
Line number of this map in <literal>file_name</literal>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -463,16 +463,74 @@ next_field_expand(const char *filename, char **lineptr,
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tokenize_include_file
|
||||||
|
* Include a file from another file into an hba "field".
|
||||||
|
*
|
||||||
|
* Opens and tokenises a file included from another authentication file
|
||||||
|
* with one of the include records ("include", "include_if_exists" or
|
||||||
|
* "include_dir"), and assign all values found to an existing list of
|
||||||
|
* list of AuthTokens.
|
||||||
|
*
|
||||||
|
* All new tokens are allocated in the memory context dedicated to the
|
||||||
|
* tokenization, aka tokenize_context.
|
||||||
|
*
|
||||||
|
* If missing_ok is true, ignore a missing file.
|
||||||
|
*
|
||||||
|
* In event of an error, log a message at ereport level elevel, and also
|
||||||
|
* set *err_msg to a string describing the error. Note that the result
|
||||||
|
* may be non-NIL anyway, so *err_msg must be tested to determine whether
|
||||||
|
* there was an error.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tokenize_include_file(const char *outer_filename,
|
||||||
|
const char *inc_filename,
|
||||||
|
List **tok_lines,
|
||||||
|
int elevel,
|
||||||
|
int depth,
|
||||||
|
bool missing_ok,
|
||||||
|
char **err_msg)
|
||||||
|
{
|
||||||
|
char *inc_fullname;
|
||||||
|
FILE *inc_file;
|
||||||
|
|
||||||
|
inc_fullname = AbsoluteConfigLocation(inc_filename, outer_filename);
|
||||||
|
inc_file = open_auth_file(inc_fullname, elevel, depth, err_msg);
|
||||||
|
|
||||||
|
if (!inc_file)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT && missing_ok)
|
||||||
|
{
|
||||||
|
ereport(elevel,
|
||||||
|
(errmsg("skipping missing authentication file \"%s\"",
|
||||||
|
inc_fullname)));
|
||||||
|
*err_msg = NULL;
|
||||||
|
pfree(inc_fullname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* error in err_msg, so leave and report */
|
||||||
|
pfree(inc_fullname);
|
||||||
|
Assert(err_msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenize_auth_file(inc_fullname, inc_file, tok_lines, elevel,
|
||||||
|
depth);
|
||||||
|
free_auth_file(inc_file, depth);
|
||||||
|
pfree(inc_fullname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tokenize_expand_file
|
* tokenize_expand_file
|
||||||
* Expand a file included from another file into an hba "field"
|
* Expand a file included from another file into an hba "field"
|
||||||
*
|
*
|
||||||
* Opens and tokenises a file included from another HBA config file with @,
|
* Opens and tokenises a file included from another HBA config file with @,
|
||||||
* and returns all values found therein as a flat list of AuthTokens. If a
|
* and returns all values found therein as a flat list of AuthTokens. If a
|
||||||
* @-token is found, recursively expand it. The newly read tokens are
|
* @-token or include record is found, recursively expand it. The newly
|
||||||
* appended to "tokens" (so that foo,bar,@baz does what you expect).
|
* read tokens are appended to "tokens" (so that foo,bar,@baz does what you
|
||||||
* All new tokens are allocated in the memory context dedicated to the
|
* expect). All new tokens are allocated in the memory context dedicated
|
||||||
* list of TokenizedAuthLines, aka tokenize_context.
|
* to the list of TokenizedAuthLines, aka tokenize_context.
|
||||||
*
|
*
|
||||||
* In event of an error, log a message at ereport level elevel, and also
|
* In event of an error, log a message at ereport level elevel, and also
|
||||||
* set *err_msg to a string describing the error. Note that the result
|
* set *err_msg to a string describing the error. Note that the result
|
||||||
@ -502,7 +560,10 @@ tokenize_expand_file(List *tokens,
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is possible recursion here if the file contains @ */
|
/*
|
||||||
|
* There is possible recursion here if the file contains @ or an include
|
||||||
|
* records.
|
||||||
|
*/
|
||||||
tokenize_auth_file(inc_fullname, inc_file, &inc_lines, elevel,
|
tokenize_auth_file(inc_fullname, inc_file, &inc_lines, elevel,
|
||||||
depth);
|
depth);
|
||||||
|
|
||||||
@ -706,6 +767,8 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
|
|||||||
|
|
||||||
while (!feof(file) && !ferror(file))
|
while (!feof(file) && !ferror(file))
|
||||||
{
|
{
|
||||||
|
TokenizedAuthLine *tok_line;
|
||||||
|
MemoryContext oldcxt;
|
||||||
char *lineptr;
|
char *lineptr;
|
||||||
List *current_line = NIL;
|
List *current_line = NIL;
|
||||||
char *err_msg = NULL;
|
char *err_msg = NULL;
|
||||||
@ -763,8 +826,6 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
|
|||||||
/* 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)
|
||||||
{
|
{
|
||||||
MemoryContext oldcxt;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lappend() may do its own allocations, so move to the
|
* lappend() may do its own allocations, so move to the
|
||||||
* context for the list of tokens.
|
* context for the list of tokens.
|
||||||
@ -776,24 +837,115 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reached EOL; emit line to TokenizedAuthLine list unless it's boring
|
* Reached EOL; no need to emit line to TokenizedAuthLine list if it's
|
||||||
|
* boring.
|
||||||
*/
|
*/
|
||||||
if (current_line != NIL || err_msg != NULL)
|
if (current_line == NIL && err_msg == NULL)
|
||||||
{
|
goto next_line;
|
||||||
TokenizedAuthLine *tok_line;
|
|
||||||
MemoryContext oldcxt;
|
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(tokenize_context);
|
/* If the line is valid, check if that's an include directive */
|
||||||
tok_line = (TokenizedAuthLine *) palloc(sizeof(TokenizedAuthLine));
|
if (err_msg == NULL && list_length(current_line) == 2)
|
||||||
tok_line->fields = current_line;
|
{
|
||||||
tok_line->file_name = pstrdup(filename);
|
AuthToken *first,
|
||||||
tok_line->line_num = line_number;
|
*second;
|
||||||
tok_line->raw_line = pstrdup(buf.data);
|
|
||||||
tok_line->err_msg = err_msg ? pstrdup(err_msg) : NULL;
|
first = linitial(linitial_node(List, current_line));
|
||||||
*tok_lines = lappend(*tok_lines, tok_line);
|
second = linitial(lsecond_node(List, current_line));
|
||||||
MemoryContextSwitchTo(oldcxt);
|
|
||||||
|
if (strcmp(first->string, "include") == 0)
|
||||||
|
{
|
||||||
|
tokenize_include_file(filename, second->string, tok_lines,
|
||||||
|
elevel, depth + 1, false, &err_msg);
|
||||||
|
|
||||||
|
if (err_msg)
|
||||||
|
goto process_line;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tokenize_auth_file() has taken care of creating the
|
||||||
|
* TokenizedAuthLines.
|
||||||
|
*/
|
||||||
|
goto next_line;
|
||||||
|
}
|
||||||
|
else if (strcmp(first->string, "include_dir") == 0)
|
||||||
|
{
|
||||||
|
char **filenames;
|
||||||
|
char *dir_name = second->string;
|
||||||
|
int num_filenames;
|
||||||
|
StringInfoData err_buf;
|
||||||
|
|
||||||
|
filenames = GetConfFilesInDir(dir_name, filename, elevel,
|
||||||
|
&num_filenames, &err_msg);
|
||||||
|
|
||||||
|
if (!filenames)
|
||||||
|
{
|
||||||
|
/* the error is in err_msg, so create an entry */
|
||||||
|
goto process_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
initStringInfo(&err_buf);
|
||||||
|
for (int i = 0; i < num_filenames; i++)
|
||||||
|
{
|
||||||
|
tokenize_include_file(filename, filenames[i], tok_lines,
|
||||||
|
elevel, depth + 1, false, &err_msg);
|
||||||
|
/* cumulate errors if any */
|
||||||
|
if (err_msg)
|
||||||
|
{
|
||||||
|
if (err_buf.len > 0)
|
||||||
|
appendStringInfoChar(&err_buf, '\n');
|
||||||
|
appendStringInfoString(&err_buf, err_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up things */
|
||||||
|
for (int i = 0; i < num_filenames; i++)
|
||||||
|
pfree(filenames[i]);
|
||||||
|
pfree(filenames);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there were no errors, the line is fully processed,
|
||||||
|
* bypass the general TokenizedAuthLine processing.
|
||||||
|
*/
|
||||||
|
if (err_buf.len == 0)
|
||||||
|
goto next_line;
|
||||||
|
|
||||||
|
/* Otherwise, process the cumulated errors, if any. */
|
||||||
|
err_msg = err_buf.data;
|
||||||
|
goto process_line;
|
||||||
|
}
|
||||||
|
else if (strcmp(first->string, "include_if_exists") == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
tokenize_include_file(filename, second->string, tok_lines,
|
||||||
|
elevel, depth + 1, true, &err_msg);
|
||||||
|
if (err_msg)
|
||||||
|
goto process_line;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tokenize_auth_file() has taken care of creating the
|
||||||
|
* TokenizedAuthLines.
|
||||||
|
*/
|
||||||
|
goto next_line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_line:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General processing: report the error if any and emit line to the
|
||||||
|
* TokenizedAuthLine. This is saved in the memory context dedicated
|
||||||
|
* to this list.
|
||||||
|
*/
|
||||||
|
oldcxt = MemoryContextSwitchTo(tokenize_context);
|
||||||
|
tok_line = (TokenizedAuthLine *) palloc0(sizeof(TokenizedAuthLine));
|
||||||
|
tok_line->fields = current_line;
|
||||||
|
tok_line->file_name = pstrdup(filename);
|
||||||
|
tok_line->line_num = line_number;
|
||||||
|
tok_line->raw_line = pstrdup(buf.data);
|
||||||
|
tok_line->err_msg = err_msg ? pstrdup(err_msg) : NULL;
|
||||||
|
*tok_lines = lappend(*tok_lines, tok_line);
|
||||||
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
|
||||||
|
next_line:
|
||||||
line_number += continuations + 1;
|
line_number += continuations + 1;
|
||||||
callback_arg.linenum = line_number;
|
callback_arg.linenum = line_number;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
# documentation for a complete description of this file. A short
|
# documentation for a complete description of this file. A short
|
||||||
# synopsis follows.
|
# synopsis follows.
|
||||||
#
|
#
|
||||||
|
# ----------------------
|
||||||
|
# Authentication Records
|
||||||
|
# ----------------------
|
||||||
|
#
|
||||||
# This file controls: which hosts are allowed to connect, how clients
|
# This file controls: which hosts are allowed to connect, how clients
|
||||||
# are authenticated, which PostgreSQL user names they can use, which
|
# are authenticated, which PostgreSQL user names they can use, which
|
||||||
# databases they can access. Records take one of these forms:
|
# databases they can access. Records take one of these forms:
|
||||||
@ -64,11 +68,34 @@
|
|||||||
# its special character, and just match a database or username with
|
# its special character, and just match a database or username with
|
||||||
# that name.
|
# that name.
|
||||||
#
|
#
|
||||||
|
# ---------------
|
||||||
|
# Include Records
|
||||||
|
# ---------------
|
||||||
|
#
|
||||||
|
# This file allows the inclusion of external files or directories holding
|
||||||
|
# more records, using the following keywords:
|
||||||
|
#
|
||||||
|
# include FILE
|
||||||
|
# include_if_exists FILE
|
||||||
|
# include_dir DIRECTORY
|
||||||
|
#
|
||||||
|
# FILE is the file name to include, and DIR is the directory name containing
|
||||||
|
# the file(s) to include. Any file in a directory will be loaded if suffixed
|
||||||
|
# with ".conf". The files of a directory are ordered by name.
|
||||||
|
# include_if_exists ignores missing files. FILE and DIRECTORY can be
|
||||||
|
# specified as a relative or an absolute path, and can be double-quoted if
|
||||||
|
# they contain spaces.
|
||||||
|
#
|
||||||
|
# -------------
|
||||||
|
# Miscellaneous
|
||||||
|
# -------------
|
||||||
|
#
|
||||||
# This file is read on server startup and when the server receives a
|
# This file is read on server startup and when the server receives a
|
||||||
# SIGHUP signal. If you edit the file on a running system, you have to
|
# SIGHUP signal. If you edit the file on a running system, you have to
|
||||||
# SIGHUP the server for the changes to take effect, run "pg_ctl reload",
|
# SIGHUP the server for the changes to take effect, run "pg_ctl reload",
|
||||||
# or execute "SELECT pg_reload_conf()".
|
# or execute "SELECT pg_reload_conf()".
|
||||||
#
|
#
|
||||||
|
# ----------------------------------
|
||||||
# Put your actual configuration here
|
# Put your actual configuration here
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
#
|
#
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# PostgreSQL User Name Maps
|
# PostgreSQL User Name Maps
|
||||||
# =========================
|
# =========================
|
||||||
#
|
#
|
||||||
|
# ---------------
|
||||||
|
# Mapping Records
|
||||||
|
# ---------------
|
||||||
|
#
|
||||||
# Refer to the PostgreSQL documentation, chapter "Client
|
# Refer to the PostgreSQL documentation, chapter "Client
|
||||||
# Authentication" for a complete description. A short synopsis
|
# Authentication" for a complete description. A short synopsis
|
||||||
# follows.
|
# follows.
|
||||||
@ -31,6 +35,28 @@
|
|||||||
# system user names and PostgreSQL user names are the same, you don't
|
# system user names and PostgreSQL user names are the same, you don't
|
||||||
# need anything in this file.
|
# need anything in this file.
|
||||||
#
|
#
|
||||||
|
# ---------------
|
||||||
|
# Include Records
|
||||||
|
# ---------------
|
||||||
|
#
|
||||||
|
# This file allows the inclusion of external files or directories holding
|
||||||
|
# more records, using the following keywords:
|
||||||
|
#
|
||||||
|
# include FILE
|
||||||
|
# include_if_exists FILE
|
||||||
|
# include_dir DIRECTORY
|
||||||
|
#
|
||||||
|
# FILE is the file name to include, and DIR is the directory name containing
|
||||||
|
# the file(s) to include. Any file in a directory will be loaded if suffixed
|
||||||
|
# with ".conf". The files of a directory are ordered by name.
|
||||||
|
# include_if_exists ignores missing files. FILE and DIRECTORY can be
|
||||||
|
# specified as a relative or an absolute path, and can be double-quoted if
|
||||||
|
# they contain spaces.
|
||||||
|
#
|
||||||
|
# -------------------------------
|
||||||
|
# Miscellaneous
|
||||||
|
# -------------------------------
|
||||||
|
#
|
||||||
# This file is read on server startup and when the postmaster receives
|
# This file is read on server startup and when the postmaster receives
|
||||||
# a SIGHUP signal. If you edit the file on a running system, you have
|
# a SIGHUP signal. If you edit the file on a running system, you have
|
||||||
# to SIGHUP the postmaster for the changes to take effect. You can
|
# to SIGHUP the postmaster for the changes to take effect. You can
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
|
|
||||||
static ArrayType *get_hba_options(HbaLine *hba);
|
static ArrayType *get_hba_options(HbaLine *hba);
|
||||||
static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
||||||
int rule_number, int lineno, HbaLine *hba,
|
int rule_number, char *filename, int lineno,
|
||||||
const char *err_msg);
|
HbaLine *hba, const char *err_msg);
|
||||||
static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
|
static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
|
||||||
static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
||||||
int map_number, int lineno, IdentLine *ident,
|
int map_number, char *filename, int lineno,
|
||||||
const char *err_msg);
|
IdentLine *ident, const char *err_msg);
|
||||||
static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
|
static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
|
||||||
|
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ get_hba_options(HbaLine *hba)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Number of columns in pg_hba_file_rules view */
|
/* Number of columns in pg_hba_file_rules view */
|
||||||
#define NUM_PG_HBA_FILE_RULES_ATTS 10
|
#define NUM_PG_HBA_FILE_RULES_ATTS 11
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill_hba_line
|
* fill_hba_line
|
||||||
@ -168,7 +168,8 @@ get_hba_options(HbaLine *hba)
|
|||||||
* tuple_store: where to store data
|
* tuple_store: where to store data
|
||||||
* tupdesc: tuple descriptor for the view
|
* tupdesc: tuple descriptor for the view
|
||||||
* rule_number: unique identifier among all valid rules
|
* rule_number: unique identifier among all valid rules
|
||||||
* lineno: pg_hba.conf line number (must always be valid)
|
* filename: configuration file name (must always be valid)
|
||||||
|
* lineno: line number of configuration file (must always be valid)
|
||||||
* hba: parsed line data (can be NULL, in which case err_msg should be set)
|
* hba: parsed line data (can be NULL, in which case err_msg should be set)
|
||||||
* err_msg: error message (NULL if none)
|
* err_msg: error message (NULL if none)
|
||||||
*
|
*
|
||||||
@ -177,7 +178,7 @@ get_hba_options(HbaLine *hba)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
||||||
int rule_number, int lineno, HbaLine *hba,
|
int rule_number, char *filename, int lineno, HbaLine *hba,
|
||||||
const char *err_msg)
|
const char *err_msg)
|
||||||
{
|
{
|
||||||
Datum values[NUM_PG_HBA_FILE_RULES_ATTS];
|
Datum values[NUM_PG_HBA_FILE_RULES_ATTS];
|
||||||
@ -203,6 +204,9 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
|||||||
else
|
else
|
||||||
values[index++] = Int32GetDatum(rule_number);
|
values[index++] = Int32GetDatum(rule_number);
|
||||||
|
|
||||||
|
/* file_name */
|
||||||
|
values[index++] = CStringGetTextDatum(filename);
|
||||||
|
|
||||||
/* line_number */
|
/* line_number */
|
||||||
values[index++] = Int32GetDatum(lineno);
|
values[index++] = Int32GetDatum(lineno);
|
||||||
|
|
||||||
@ -346,7 +350,7 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no parsing result, so set relevant fields to nulls */
|
/* no parsing result, so set relevant fields to nulls */
|
||||||
memset(&nulls[2], true, (NUM_PG_HBA_FILE_RULES_ATTS - 3) * sizeof(bool));
|
memset(&nulls[3], true, (NUM_PG_HBA_FILE_RULES_ATTS - 4) * sizeof(bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error */
|
/* error */
|
||||||
@ -402,7 +406,8 @@ fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
|
|||||||
rule_number++;
|
rule_number++;
|
||||||
|
|
||||||
fill_hba_line(tuple_store, tupdesc, rule_number,
|
fill_hba_line(tuple_store, tupdesc, rule_number,
|
||||||
tok_line->line_num, hbaline, tok_line->err_msg);
|
tok_line->file_name, tok_line->line_num, hbaline,
|
||||||
|
tok_line->err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free tokenizer memory */
|
/* Free tokenizer memory */
|
||||||
@ -439,7 +444,7 @@ pg_hba_file_rules(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Number of columns in pg_ident_file_mappings view */
|
/* Number of columns in pg_ident_file_mappings view */
|
||||||
#define NUM_PG_IDENT_FILE_MAPPINGS_ATTS 6
|
#define NUM_PG_IDENT_FILE_MAPPINGS_ATTS 7
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill_ident_line: build one row of pg_ident_file_mappings view, add it to
|
* fill_ident_line: build one row of pg_ident_file_mappings view, add it to
|
||||||
@ -448,7 +453,8 @@ pg_hba_file_rules(PG_FUNCTION_ARGS)
|
|||||||
* tuple_store: where to store data
|
* tuple_store: where to store data
|
||||||
* tupdesc: tuple descriptor for the view
|
* tupdesc: tuple descriptor for the view
|
||||||
* map_number: unique identifier among all valid maps
|
* map_number: unique identifier among all valid maps
|
||||||
* lineno: pg_ident.conf line number (must always be valid)
|
* filename: configuration file name (must always be valid)
|
||||||
|
* lineno: line number of configuration file (must always be valid)
|
||||||
* ident: parsed line data (can be NULL, in which case err_msg should be set)
|
* ident: parsed line data (can be NULL, in which case err_msg should be set)
|
||||||
* err_msg: error message (NULL if none)
|
* err_msg: error message (NULL if none)
|
||||||
*
|
*
|
||||||
@ -457,7 +463,7 @@ pg_hba_file_rules(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
||||||
int map_number, int lineno, IdentLine *ident,
|
int map_number, char *filename, int lineno, IdentLine *ident,
|
||||||
const char *err_msg)
|
const char *err_msg)
|
||||||
{
|
{
|
||||||
Datum values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
|
Datum values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
|
||||||
@ -477,6 +483,9 @@ fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
|||||||
else
|
else
|
||||||
values[index++] = Int32GetDatum(map_number);
|
values[index++] = Int32GetDatum(map_number);
|
||||||
|
|
||||||
|
/* file_name */
|
||||||
|
values[index++] = CStringGetTextDatum(filename);
|
||||||
|
|
||||||
/* line_number */
|
/* line_number */
|
||||||
values[index++] = Int32GetDatum(lineno);
|
values[index++] = Int32GetDatum(lineno);
|
||||||
|
|
||||||
@ -489,7 +498,7 @@ fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no parsing result, so set relevant fields to nulls */
|
/* no parsing result, so set relevant fields to nulls */
|
||||||
memset(&nulls[2], true, (NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 3) * sizeof(bool));
|
memset(&nulls[3], true, (NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 4) * sizeof(bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error */
|
/* error */
|
||||||
@ -544,8 +553,8 @@ fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
|
|||||||
map_number++;
|
map_number++;
|
||||||
|
|
||||||
fill_ident_line(tuple_store, tupdesc, map_number,
|
fill_ident_line(tuple_store, tupdesc, map_number,
|
||||||
tok_line->line_num, identline,
|
tok_line->file_name, tok_line->line_num,
|
||||||
tok_line->err_msg);
|
identline, tok_line->err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free tokenizer memory */
|
/* Free tokenizer memory */
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202211221
|
#define CATALOG_VERSION_NO 202211241
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6161,16 +6161,16 @@
|
|||||||
{ oid => '3401', descr => 'show pg_hba.conf rules',
|
{ oid => '3401', descr => 'show pg_hba.conf rules',
|
||||||
proname => 'pg_hba_file_rules', prorows => '1000', proretset => 't',
|
proname => 'pg_hba_file_rules', prorows => '1000', proretset => 't',
|
||||||
provolatile => 'v', prorettype => 'record', proargtypes => '',
|
provolatile => 'v', prorettype => 'record', proargtypes => '',
|
||||||
proallargtypes => '{int4,int4,text,_text,_text,text,text,text,_text,text}',
|
proallargtypes => '{int4,text,int4,text,_text,_text,text,text,text,_text,text}',
|
||||||
proargmodes => '{o,o,o,o,o,o,o,o,o,o}',
|
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o}',
|
||||||
proargnames => '{rule_number,line_number,type,database,user_name,address,netmask,auth_method,options,error}',
|
proargnames => '{rule_number,file_name,line_number,type,database,user_name,address,netmask,auth_method,options,error}',
|
||||||
prosrc => 'pg_hba_file_rules' },
|
prosrc => 'pg_hba_file_rules' },
|
||||||
{ oid => '6250', descr => 'show pg_ident.conf mappings',
|
{ oid => '6250', descr => 'show pg_ident.conf mappings',
|
||||||
proname => 'pg_ident_file_mappings', prorows => '1000', proretset => 't',
|
proname => 'pg_ident_file_mappings', prorows => '1000', proretset => 't',
|
||||||
provolatile => 'v', prorettype => 'record', proargtypes => '',
|
provolatile => 'v', prorettype => 'record', proargtypes => '',
|
||||||
proallargtypes => '{int4,int4,text,text,text,text}',
|
proallargtypes => '{int4,text,int4,text,text,text,text}',
|
||||||
proargmodes => '{o,o,o,o,o,o}',
|
proargmodes => '{o,o,o,o,o,o,o}',
|
||||||
proargnames => '{map_number,line_number,map_name,sys_name,pg_username,error}',
|
proargnames => '{map_number,file_name,line_number,map_name,sys_name,pg_username,error}',
|
||||||
prosrc => 'pg_ident_file_mappings' },
|
prosrc => 'pg_ident_file_mappings' },
|
||||||
{ oid => '1371', descr => 'view system lock information',
|
{ oid => '1371', descr => 'view system lock information',
|
||||||
proname => 'pg_lock_status', prorows => '1000', proretset => 't',
|
proname => 'pg_lock_status', prorows => '1000', proretset => 't',
|
||||||
|
@ -1339,6 +1339,7 @@ pg_group| SELECT pg_authid.rolname AS groname,
|
|||||||
FROM pg_authid
|
FROM pg_authid
|
||||||
WHERE (NOT pg_authid.rolcanlogin);
|
WHERE (NOT pg_authid.rolcanlogin);
|
||||||
pg_hba_file_rules| SELECT a.rule_number,
|
pg_hba_file_rules| SELECT a.rule_number,
|
||||||
|
a.file_name,
|
||||||
a.line_number,
|
a.line_number,
|
||||||
a.type,
|
a.type,
|
||||||
a.database,
|
a.database,
|
||||||
@ -1348,14 +1349,15 @@ pg_hba_file_rules| SELECT a.rule_number,
|
|||||||
a.auth_method,
|
a.auth_method,
|
||||||
a.options,
|
a.options,
|
||||||
a.error
|
a.error
|
||||||
FROM pg_hba_file_rules() a(rule_number, line_number, type, database, user_name, address, netmask, auth_method, options, error);
|
FROM pg_hba_file_rules() a(rule_number, file_name, line_number, type, database, user_name, address, netmask, auth_method, options, error);
|
||||||
pg_ident_file_mappings| SELECT a.map_number,
|
pg_ident_file_mappings| SELECT a.map_number,
|
||||||
|
a.file_name,
|
||||||
a.line_number,
|
a.line_number,
|
||||||
a.map_name,
|
a.map_name,
|
||||||
a.sys_name,
|
a.sys_name,
|
||||||
a.pg_username,
|
a.pg_username,
|
||||||
a.error
|
a.error
|
||||||
FROM pg_ident_file_mappings() a(map_number, line_number, map_name, sys_name, pg_username, error);
|
FROM pg_ident_file_mappings() a(map_number, file_name, line_number, map_name, sys_name, pg_username, error);
|
||||||
pg_indexes| SELECT n.nspname AS schemaname,
|
pg_indexes| SELECT n.nspname AS schemaname,
|
||||||
c.relname AS tablename,
|
c.relname AS tablename,
|
||||||
i.relname AS indexname,
|
i.relname AS indexname,
|
||||||
|
Loading…
Reference in New Issue
Block a user