agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Julien Rouhaud <[email protected]>
Subject: [PATCH v2 2/4] Add a pg_ident_file_mappings view.
Date: Mon, 21 Feb 2022 17:38:34 +0800
This view is similar to pg_hba_file_rules view, and can be also helpful to help
diagnosing configuration problems.
A following commit will add the possibility to include files in pg_hba and
pg_ident configuration files, which will then make this view even more useful.
Author: Julien Rouhaud
Reviewed-by: FIXME
Discussion: https://postgr.es/m/20220223045959.35ipdsvbxcstrhya%40jrouhaud
---
doc/src/sgml/catalogs.sgml | 108 ++++++++++++++
doc/src/sgml/client-auth.sgml | 10 ++
doc/src/sgml/func.sgml | 5 +-
src/backend/catalog/system_views.sql | 6 +
src/backend/libpq/hba.c | 191 +++++++++++++------------
src/backend/utils/adt/hbafuncs.c | 164 +++++++++++++++++++++
src/include/catalog/pg_proc.dat | 7 +
src/include/libpq/hba.h | 1 +
src/test/regress/expected/rules.out | 6 +
src/test/regress/expected/sysviews.out | 7 +
src/test/regress/sql/sysviews.sql | 3 +
11 files changed, 412 insertions(+), 96 deletions(-)
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 83987a9904..0de40a9626 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -9530,6 +9530,11 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<entry>summary of client authentication configuration file contents</entry>
</row>
+ <row>
+ <entry><link linkend="view-pg-hba-file-rules"><structname>pg_ident_file_mappings</structname></link></entry>
+ <entry>summary of client user name mapping configuration file contents</entry>
+ </row>
+
<row>
<entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry>
<entry>indexes</entry>
@@ -10523,6 +10528,109 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
</para>
</sect1>
+ <sect1 id="view-pg-ident-file-mappings">
+ <title><structname>pg_ident_file_mappings</structname></title>
+
+ <indexterm zone="view-pg-ident-file-mappings">
+ <primary>pg_ident_file_mappings</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_ident_file_mappings</structname> provides a summary
+ of the contents of the client user name mapping configuration file,
+ <link linkend="auth-username-maps"><filename>pg_ident.conf</filename></link>.
+ A row appears in this view for each
+ non-empty, non-comment line in the file, with annotations indicating
+ whether the rule could be applied successfully.
+ </para>
+
+ <para>
+ This view can be helpful for checking whether planned changes in the
+ authentication configuration file will work, or for diagnosing a previous
+ failure. Note that this view reports on the <emphasis>current</emphasis>
+ contents of the file, not on what was last loaded by the server.
+ </para>
+
+ <para>
+ By default, the <structname>pg_ident_file_mappings</structname> view can be
+ read only by superusers.
+ </para>
+
+ <table>
+ <title><structname>pg_ident_file_mappings</structname> Columns</title> <tgroup
+ cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>line_number</structfield> <type>int4</type>
+ </para>
+ <para>
+ Line number of this rule in <filename>pg_ident.conf</filename>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>map_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the map
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sys_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Detected user name of the client
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pg_username</structfield> <type>text</type>
+ </para>
+ <para>
+ Requested PostgreSQL user name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>error</structfield> <type>text</type>
+ </para>
+ <para>
+ If not null, an error message indicating why this line could not be
+ processed
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Usually, a row reflecting an incorrect entry will have values for only
+ the <structfield>line_number</structfield> and <structfield>error</structfield> fields.
+ </para>
+
+ <para>
+ See <xref linkend="client-authentication"/> for more information about
+ client authentication configuration.
+ </para>
+ </sect1>
+
<sect1 id="view-pg-indexes">
<title><structname>pg_indexes</structname></title>
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 02f0489112..142b0affcb 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -896,6 +896,16 @@ mymap /^(.*)@otherdomain\.com$ guest
-HUP</literal>) to make it re-read the file.
</para>
+ <para>
+ The system view
+ <link linkend="view-pg-ident-file-mappings"><structname>pg_ident_file_mappings</structname></link>
+ can be helpful for pre-testing changes to the
+ <filename>pg_ident.conf</filename> file, or for diagnosing problems if
+ loading of the file did not have the desired effects. Rows in the view with
+ non-null <structfield>error</structfield> fields indicate problems in the
+ corresponding lines of the file.
+ </para>
+
<para>
A <filename>pg_ident.conf</filename> file that could be used in
conjunction with the <filename>pg_hba.conf</filename> file in <xref
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index df3cd5987b..bbac492043 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -25475,8 +25475,9 @@ SELECT collation for ('foo' COLLATE "de_DE");
sending a <systemitem>SIGHUP</systemitem> signal to the postmaster
process, which in turn sends <systemitem>SIGHUP</systemitem> to each
of its children.) You can use the
- <link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link> and
- <link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link> views
+ <link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link>,
+ <link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link> and
+ <link linkend="view-pg-hba-file-rules"><structname>pg_ident_file_mappings</structname></link> views
to check the configuration files for possible errors, before reloading.
</para></entry>
</row>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 3cb69b1f87..ef13f470b3 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -607,6 +607,12 @@ CREATE VIEW pg_hba_file_rules AS
REVOKE ALL ON pg_hba_file_rules FROM PUBLIC;
REVOKE EXECUTE ON FUNCTION pg_hba_file_rules() FROM PUBLIC;
+CREATE VIEW pg_ident_file_mappings AS
+ SELECT * FROM pg_ident_file_mappings() AS A;
+
+REVOKE ALL ON pg_ident_file_mappings FROM PUBLIC;
+REVOKE EXECUTE ON FUNCTION pg_ident_file_mappings() FROM PUBLIC;
+
CREATE VIEW pg_timezone_abbrevs AS
SELECT * FROM pg_timezone_abbrevs();
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 184df4942a..e673ff5474 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -766,25 +766,22 @@ do { \
} while (0)
/*
- * Macros for handling pg_ident problems.
- * Much as above, but currently the message level is hardwired as LOG
- * and there is no provision for an err_msg string.
+ * Macros for handling pg_ident problems, similar as above.
*
* IDENT_FIELD_ABSENT:
- * Log a message and exit the function if the given ident field ListCell is
- * not populated.
+ * Reports when the given ident field ListCell is not populated.
*
* IDENT_MULTI_VALUE:
- * Log a message and exit the function if the given ident token List has more
- * than one element.
+ * Report when the given ident token List has more than one element.
*/
#define IDENT_FIELD_ABSENT(field) \
do { \
if (!field) { \
- ereport(LOG, \
+ ereport(elevel, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
errmsg("missing entry in file \"%s\" at end of line %d", \
IdentFileName, line_num))); \
+ *err_msg = psprintf("missing entry at end of line"); \
return NULL; \
} \
} while (0)
@@ -792,11 +789,12 @@ do { \
#define IDENT_MULTI_VALUE(tokens) \
do { \
if (tokens->length > 1) { \
- ereport(LOG, \
+ ereport(elevel, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
errmsg("multiple values in ident field"), \
errcontext("line %d of configuration file \"%s\"", \
line_num, IdentFileName))); \
+ *err_msg = psprintf("multiple values in ident field"); \
return NULL; \
} \
} while (0)
@@ -1436,90 +1434,6 @@ load_hba(void)
return true;
}
-/*
- * Parse one tokenised line from the ident config file and store the result in
- * an IdentLine structure.
- *
- * If parsing fails, log a message and return NULL.
- *
- * If ident_user is a regular expression (ie. begins with a slash), it is
- * compiled and stored in IdentLine structure.
- *
- * Note: this function leaks memory when an error occurs. Caller is expected
- * to have set a memory context that will be reset if this function returns
- * NULL.
- */
-static IdentLine *
-parse_ident_line(TokenizedAuthLine *tok_line)
-{
- int line_num = tok_line->line_num;
- ListCell *field;
- List *tokens;
- HbaToken *token;
- IdentLine *parsedline;
-
- Assert(tok_line->fields != NIL);
- field = list_head(tok_line->fields);
-
- parsedline = palloc0(sizeof(IdentLine));
- parsedline->linenumber = line_num;
-
- /* Get the map token (must exist) */
- tokens = lfirst(field);
- IDENT_MULTI_VALUE(tokens);
- token = linitial(tokens);
- parsedline->usermap = pstrdup(token->string);
-
- /* Get the ident user token */
- field = lnext(tok_line->fields, field);
- IDENT_FIELD_ABSENT(field);
- tokens = lfirst(field);
- IDENT_MULTI_VALUE(tokens);
- token = linitial(tokens);
- parsedline->ident_user = pstrdup(token->string);
-
- /* Get the PG rolename token */
- field = lnext(tok_line->fields, field);
- IDENT_FIELD_ABSENT(field);
- tokens = lfirst(field);
- IDENT_MULTI_VALUE(tokens);
- token = linitial(tokens);
- parsedline->pg_role = pstrdup(token->string);
-
- if (parsedline->ident_user[0] == '/')
- {
- /*
- * When system username starts with a slash, treat it as a regular
- * expression. Pre-compile it.
- */
- int r;
- pg_wchar *wstr;
- int wlen;
-
- wstr = palloc((strlen(parsedline->ident_user + 1) + 1) * sizeof(pg_wchar));
- wlen = pg_mb2wchar_with_len(parsedline->ident_user + 1,
- wstr, strlen(parsedline->ident_user + 1));
-
- r = pg_regcomp(&parsedline->re, wstr, wlen, REG_ADVANCED, C_COLLATION_OID);
- if (r)
- {
- char errstr[100];
-
- pg_regerror(r, &parsedline->re, errstr, sizeof(errstr));
- ereport(LOG,
- (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
- errmsg("invalid regular expression \"%s\": %s",
- parsedline->ident_user + 1, errstr)));
-
- pfree(wstr);
- return NULL;
- }
- pfree(wstr);
- }
-
- return parsedline;
-}
-
/*
* Process one line from the parsed ident config lines.
*
@@ -1761,7 +1675,7 @@ load_ident(void)
continue;
}
- if ((newline = parse_ident_line(tok_line)) == NULL)
+ if ((newline = parse_ident_line(tok_line, LOG)) == NULL)
{
/* Parse error; remember there's trouble */
ok = false;
@@ -2596,6 +2510,95 @@ parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
return parsedline;
}
+/*
+ * Parse one tokenised line from the ident config file and store the result in
+ * an IdentLine structure.
+ *
+ * If parsing fails, log a message at ereport level elevel, store an error
+ * string in tok_line->err_msg and return NULL.
+ *
+ * If ident_user is a regular expression (ie. begins with a slash), it is
+ * compiled and stored in IdentLine structure.
+ *
+ * Note: this function leaks memory when an error occurs. Caller is expected
+ * to have set a memory context that will be reset if this function returns
+ * NULL.
+ */
+IdentLine *
+parse_ident_line(TokenizedAuthLine *tok_line, int elevel)
+{
+ int line_num = tok_line->line_num;
+ char **err_msg = &tok_line->err_msg;
+ ListCell *field;
+ List *tokens;
+ HbaToken *token;
+ IdentLine *parsedline;
+
+ Assert(tok_line->fields != NIL);
+ field = list_head(tok_line->fields);
+
+ parsedline = palloc0(sizeof(IdentLine));
+ parsedline->linenumber = line_num;
+
+ /* Get the map token (must exist) */
+ tokens = lfirst(field);
+ IDENT_MULTI_VALUE(tokens);
+ token = linitial(tokens);
+ parsedline->usermap = pstrdup(token->string);
+
+ /* Get the ident user token */
+ field = lnext(tok_line->fields, field);
+ IDENT_FIELD_ABSENT(field);
+ tokens = lfirst(field);
+ IDENT_MULTI_VALUE(tokens);
+ token = linitial(tokens);
+ parsedline->ident_user = pstrdup(token->string);
+
+ /* Get the PG rolename token */
+ field = lnext(tok_line->fields, field);
+ IDENT_FIELD_ABSENT(field);
+ tokens = lfirst(field);
+ IDENT_MULTI_VALUE(tokens);
+ token = linitial(tokens);
+ parsedline->pg_role = pstrdup(token->string);
+
+ if (parsedline->ident_user[0] == '/')
+ {
+ /*
+ * When system username starts with a slash, treat it as a regular
+ * expression. Pre-compile it.
+ */
+ int r;
+ pg_wchar *wstr;
+ int wlen;
+
+ wstr = palloc((strlen(parsedline->ident_user + 1) + 1) * sizeof(pg_wchar));
+ wlen = pg_mb2wchar_with_len(parsedline->ident_user + 1,
+ wstr, strlen(parsedline->ident_user + 1));
+
+ r = pg_regcomp(&parsedline->re, wstr, wlen, REG_ADVANCED, C_COLLATION_OID);
+ if (r)
+ {
+ char errstr[100];
+
+ pg_regerror(r, &parsedline->re, errstr, sizeof(errstr));
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
+ errmsg("invalid regular expression \"%s\": %s",
+ parsedline->ident_user + 1, errstr)));
+
+ *err_msg = psprintf("invalid regular expression \"%s\": %s",
+ parsedline->ident_user + 1, errstr);
+
+ pfree(wstr);
+ return NULL;
+ }
+ pfree(wstr);
+ }
+
+ return parsedline;
+}
+
/*
* Tokenize the given file.
*
diff --git a/src/backend/utils/adt/hbafuncs.c b/src/backend/utils/adt/hbafuncs.c
index 2bcaebe99e..2189c298b8 100644
--- a/src/backend/utils/adt/hbafuncs.c
+++ b/src/backend/utils/adt/hbafuncs.c
@@ -28,6 +28,9 @@
static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
int lineno, HbaLine *hba, const char *err_msg);
static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
+static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
+ int lineno, IdentLine *ident, const char *err_msg);
+static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
static ArrayType *gethba_options(HbaLine *hba);
@@ -277,6 +280,116 @@ fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
MemoryContextDelete(hbacxt);
}
+/* Number of columns in pg_hba_file_mappings view */
+#define NUM_PG_IDENT_FILE_MAPPINGS_ATTS 5
+
+/*
+ * fill_ident_line: build one row of pg_ident_file_mappings view, add it to
+ * tuplestore
+ *
+ * tuple_store: where to store data
+ * tupdesc: tuple descriptor for the view
+ * lineno: pg_hba.conf line number (must always be valid)
+ * ident: parsed line data (can be NULL, in which case err_msg should be set)
+ * err_msg: error message (NULL if none)
+ *
+ * Note: leaks memory, but we don't care since this is run in a short-lived
+ * memory context.
+ */
+static void
+fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
+ int lineno, IdentLine *ident, const char *err_msg)
+{
+ Datum values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
+ bool nulls[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
+ HeapTuple tuple;
+ int index;
+
+ Assert(tupdesc->natts == NUM_PG_IDENT_FILE_MAPPINGS_ATTS);
+
+ memset(values, 0, sizeof(values));
+ memset(nulls, 0, sizeof(nulls));
+ index = 0;
+
+ /* line_number */
+ values[index++] = Int32GetDatum(lineno);
+
+ if (ident != NULL)
+ {
+ values[index++] = CStringGetTextDatum(ident->usermap);
+ values[index++] = CStringGetTextDatum(ident->ident_user);
+ values[index++] = CStringGetTextDatum(ident->pg_role);
+ }
+ else
+ {
+ /* no parsing result, so set relevant fields to nulls */
+ memset(&nulls[1], true, (NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 2) * sizeof(bool));
+ }
+
+ /* error */
+ if (err_msg)
+ values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 1] = CStringGetTextDatum(err_msg);
+ else
+ nulls[NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 1] = true;
+
+ tuple = heap_form_tuple(tupdesc, values, nulls);
+ tuplestore_puttuple(tuple_store, tuple);
+}
+
+/*
+ * Read the pg_ident.conf file and fill the tuplestore with view records.
+ */
+static void
+fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
+{
+ FILE *file;
+ List *ident_lines = NIL;
+ ListCell *line;
+ MemoryContext linecxt;
+ MemoryContext identcxt;
+ MemoryContext oldcxt;
+
+ /*
+ * In the unlikely event that we can't open pg_hba.conf, we throw an
+ * error, rather than trying to report it via some sort of view entry.
+ * (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(HbaFileName, file, &ident_lines, DEBUG3);
+ FreeFile(file);
+
+ /* Now parse all the lines */
+ identcxt = AllocSetContextCreate(CurrentMemoryContext,
+ "ident parser context",
+ ALLOCSET_SMALL_SIZES);
+ oldcxt = MemoryContextSwitchTo(identcxt);
+ foreach(line, ident_lines)
+ {
+ TokenizedAuthLine *tok_line = (TokenizedAuthLine *) lfirst(line);
+ IdentLine *identline = NULL;
+
+ /* don't parse lines that already have errors */
+ if (tok_line->err_msg == NULL)
+ identline = parse_ident_line(tok_line, DEBUG3);
+
+ fill_ident_line(tuple_store, tupdesc, tok_line->line_num, identline,
+ tok_line->err_msg);
+ }
+
+ /* Free tokenizer memory */
+ MemoryContextDelete(linecxt);
+ /* Free parse_ident_line memory */
+ MemoryContextSwitchTo(oldcxt);
+ MemoryContextDelete(identcxt);
+}
+
/*
* This macro specifies the maximum number of authentication options
* that are possible with any given authentication method that is supported.
@@ -450,3 +563,54 @@ pg_hba_file_rules(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
+
+/*
+ * SQL-accessible SRF to return all the entries in the pg_ident.conf file.
+ */
+Datum
+pg_ident_file_mappings(PG_FUNCTION_ARGS)
+{
+ Tuplestorestate *tuple_store;
+ TupleDesc tupdesc;
+ MemoryContext old_cxt;
+ ReturnSetInfo *rsi;
+
+ /*
+ * We must use the Materialize mode to be safe against ident file changes
+ * while the cursor is open. It's also more efficient than having to look
+ * up our current position in the parsed list every time.
+ */
+ rsi = (ReturnSetInfo *) fcinfo->resultinfo;
+
+ /* Check to see if caller supports us returning a tuplestore */
+ if (rsi == NULL || !IsA(rsi, ReturnSetInfo))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("set-valued function called in context that cannot accept a set")));
+ if (!(rsi->allowedModes & SFRM_Materialize))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("materialize mode required, but it is not allowed in this context")));
+
+ rsi->returnMode = SFRM_Materialize;
+
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+
+ /* Build tuplestore to hold the result rows */
+ old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
+
+ tuple_store =
+ tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
+ false, work_mem);
+ rsi->setDesc = tupdesc;
+ rsi->setResult = tuple_store;
+
+ MemoryContextSwitchTo(old_cxt);
+
+ /* Fill the tuplestore */
+ fill_ident_view(tuple_store, tupdesc);
+
+ PG_RETURN_NULL();
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7de8cfc7e9..04d4edb228 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6120,6 +6120,13 @@
proargmodes => '{o,o,o,o,o,o,o,o,o}',
proargnames => '{line_number,type,database,user_name,address,netmask,auth_method,options,error}',
prosrc => 'pg_hba_file_rules' },
+{ oid => '9556', descr => 'show pg_ident.conf mappings',
+ proname => 'pg_ident_file_mappings', prorows => '1000', proretset => 't',
+ provolatile => 'v', prorettype => 'record', proargtypes => '',
+ proallargtypes => '{int4,text,text,text,text}',
+ proargmodes => '{o,o,o,o,o}',
+ proargnames => '{line_number,map_name,sys_name,pg_usernamee,error}',
+ prosrc => 'pg_ident_file_mappings' },
{ oid => '1371', descr => 'view system lock information',
proname => 'pg_lock_status', prorows => '1000', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => '',
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 19924dca67..fce7db248b 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -169,6 +169,7 @@ extern int check_usermap(const char *usermap_name,
const char *pg_role, const char *auth_user,
bool case_sensitive);
extern HbaLine *parse_hba_line(TokenizedAuthLine *tok_line, int elevel);
+extern IdentLine *parse_ident_line(TokenizedAuthLine *tok_line, int elevel);
extern bool pg_isblank(const char c);
extern MemoryContext tokenize_auth_file(const char *filename, FILE *file,
List **tok_lines, int elevel);
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 1420288d67..62cf0d8674 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1347,6 +1347,12 @@ pg_hba_file_rules| SELECT a.line_number,
a.options,
a.error
FROM pg_hba_file_rules() a(line_number, type, database, user_name, address, netmask, auth_method, options, error);
+pg_ident_file_mappings| SELECT a.line_number,
+ a.map_name,
+ a.sys_name,
+ a.pg_usernamee,
+ a.error
+ FROM pg_ident_file_mappings() a(line_number, map_name, sys_name, pg_usernamee, error);
pg_indexes| SELECT n.nspname AS schemaname,
c.relname AS tablename,
i.relname AS indexname,
diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out
index 442eeb1e3f..d8a7df9498 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -55,6 +55,13 @@ select count(*) > 0 as ok from pg_hba_file_rules;
t
(1 row)
+-- We expect no user mapping in this test
+select count(*) = 0 as ok from pg_ident_file_mappings;
+ ok
+----
+ t
+(1 row)
+
-- There will surely be at least one active lock
select count(*) > 0 as ok from pg_locks;
ok
diff --git a/src/test/regress/sql/sysviews.sql b/src/test/regress/sql/sysviews.sql
index 4980f07be2..4c1129e787 100644
--- a/src/test/regress/sql/sysviews.sql
+++ b/src/test/regress/sql/sysviews.sql
@@ -28,6 +28,9 @@ select count(*) >= 0 as ok from pg_file_settings;
-- There will surely be at least one rule
select count(*) > 0 as ok from pg_hba_file_rules;
+-- We expect no user mapping in this test
+select count(*) = 0 as ok from pg_ident_file_mappings;
+
-- There will surely be at least one active lock
select count(*) > 0 as ok from pg_locks;
--
2.33.1
--uqjaptwdgaq4xou6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename="v2-0003-Allow-file-inclusion-in-pg_hba-and-pg_ident-files.patch"
view thread (67+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v2 2/4] Add a pg_ident_file_mappings view.
In-Reply-To: <no-message-id-1860164@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox