mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-01 19:45:33 +08:00
Cause pg_hba.conf file inclusion (@file stuff) to behave as documented,
that is, files are sought in the same directory as the referencing file. Also allow absolute paths in @file constructs. Improve documentation to actually say what is allowed in an included file.
This commit is contained in:
parent
6dac6b89a0
commit
370f90970d
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.69 2004/12/26 23:06:56 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.70 2004/12/27 19:19:23 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="client-authentication">
|
<chapter id="client-authentication">
|
||||||
@ -175,8 +175,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
a specific <productname>PostgreSQL</productname> database.
|
a specific <productname>PostgreSQL</productname> database.
|
||||||
Multiple database names can be supplied by separating them with
|
Multiple database names can be supplied by separating them with
|
||||||
commas. A file containing database names can be specified by
|
commas. A file containing database names can be specified by
|
||||||
preceding the file name with <literal>@</>. The file must be in
|
preceding the file name with <literal>@</>.
|
||||||
the same directory as <filename>pg_hba.conf</>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -192,8 +191,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
can be supplied by separating them with commas. Group names can
|
can be supplied by separating them with commas. Group names can
|
||||||
be specified by preceding the group name with <literal>+</>. A
|
be specified by preceding the group name with <literal>+</>. A
|
||||||
file containing user names can be specified by preceding the
|
file containing user names can be specified by preceding the
|
||||||
file name with <literal>@</>. The file must be in the same
|
file name with <literal>@</>.
|
||||||
directory as <filename>pg_hba.conf</>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -393,6 +391,16 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Files included by <literal>@</> constructs are read as lists of names,
|
||||||
|
which can be separated by either whitespace or commas. Comments are
|
||||||
|
introduced by <literal>#</literal>, just as in
|
||||||
|
<filename>pg_hba.conf</filename>, and nested <literal>@</> constructs are
|
||||||
|
allowed. Unless the file name following <literal>@</> is an absolute
|
||||||
|
path, it is taken to be relative to the directory containing the
|
||||||
|
referencing file.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Since the <filename>pg_hba.conf</filename> records are examined
|
Since the <filename>pg_hba.conf</filename> records are examined
|
||||||
sequentially for each connection attempt, the order of the records is
|
sequentially for each connection attempt, the order of the records is
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.134 2004/11/17 19:54:24 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.135 2004/12/27 19:19:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -82,8 +82,10 @@ static List **group_sorted = NULL; /* sorted group list, for
|
|||||||
static int user_length;
|
static int user_length;
|
||||||
static int group_length;
|
static int group_length;
|
||||||
|
|
||||||
static void tokenize_file(FILE *file, List **lines, List **line_nums);
|
static void tokenize_file(const char *filename, FILE *file,
|
||||||
static char *tokenize_inc_file(const char *inc_filename);
|
List **lines, List **line_nums);
|
||||||
|
static char *tokenize_inc_file(const char *outer_filename,
|
||||||
|
const char *inc_filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* isblank() exists in the ISO C99 spec, but it's not very portable yet,
|
* isblank() exists in the ISO C99 spec, but it's not very portable yet,
|
||||||
@ -212,7 +214,7 @@ next_token(FILE *fp, char *buf, int bufsz)
|
|||||||
* we have reached EOL.
|
* we have reached EOL.
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
next_token_expand(FILE *file)
|
next_token_expand(const char *filename, FILE *file)
|
||||||
{
|
{
|
||||||
char buf[MAX_TOKEN];
|
char buf[MAX_TOKEN];
|
||||||
char *comma_str = pstrdup("");
|
char *comma_str = pstrdup("");
|
||||||
@ -236,7 +238,7 @@ next_token_expand(FILE *file)
|
|||||||
|
|
||||||
/* Is this referencing a file? */
|
/* Is this referencing a file? */
|
||||||
if (buf[0] == '@')
|
if (buf[0] == '@')
|
||||||
incbuf = tokenize_inc_file(buf + 1);
|
incbuf = tokenize_inc_file(filename, buf + 1);
|
||||||
else
|
else
|
||||||
incbuf = pstrdup(buf);
|
incbuf = pstrdup(buf);
|
||||||
|
|
||||||
@ -301,23 +303,34 @@ free_lines(List **lines, List **line_nums)
|
|||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
tokenize_inc_file(const char *inc_filename)
|
tokenize_inc_file(const char *outer_filename,
|
||||||
|
const char *inc_filename)
|
||||||
{
|
{
|
||||||
char *inc_fullname;
|
char *inc_fullname;
|
||||||
FILE *inc_file;
|
FILE *inc_file;
|
||||||
List *inc_lines;
|
List *inc_lines;
|
||||||
List *inc_line_nums;
|
List *inc_line_nums;
|
||||||
ListCell *line;
|
ListCell *line;
|
||||||
char *comma_str = pstrdup("");
|
char *comma_str;
|
||||||
|
|
||||||
inc_fullname = (char *) palloc(strlen(DataDir) + 1 +
|
if (is_absolute_path(inc_filename))
|
||||||
strlen(inc_filename) + 1);
|
{
|
||||||
strcpy(inc_fullname, DataDir);
|
/* absolute path is taken as-is */
|
||||||
strcat(inc_fullname, "/");
|
inc_fullname = pstrdup(inc_filename);
|
||||||
strcat(inc_fullname, inc_filename);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* relative path is relative to dir of calling file */
|
||||||
|
inc_fullname = (char *) palloc(strlen(outer_filename) + 1 +
|
||||||
|
strlen(inc_filename) + 1);
|
||||||
|
strcpy(inc_fullname, outer_filename);
|
||||||
|
get_parent_directory(inc_fullname);
|
||||||
|
join_path_components(inc_fullname, inc_fullname, inc_filename);
|
||||||
|
canonicalize_path(inc_fullname);
|
||||||
|
}
|
||||||
|
|
||||||
inc_file = AllocateFile(inc_fullname, "r");
|
inc_file = AllocateFile(inc_fullname, "r");
|
||||||
if (!inc_file)
|
if (inc_file == NULL)
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
@ -325,16 +338,18 @@ tokenize_inc_file(const char *inc_filename)
|
|||||||
inc_filename, inc_fullname)));
|
inc_filename, inc_fullname)));
|
||||||
pfree(inc_fullname);
|
pfree(inc_fullname);
|
||||||
|
|
||||||
/* return empty string, it matches nothing */
|
/* return single space, it matches nothing */
|
||||||
return comma_str;
|
return pstrdup(" ");
|
||||||
}
|
}
|
||||||
pfree(inc_fullname);
|
|
||||||
|
|
||||||
/* There is possible recursion here if the file contains @ */
|
/* There is possible recursion here if the file contains @ */
|
||||||
tokenize_file(inc_file, &inc_lines, &inc_line_nums);
|
tokenize_file(inc_fullname, inc_file, &inc_lines, &inc_line_nums);
|
||||||
|
|
||||||
FreeFile(inc_file);
|
FreeFile(inc_file);
|
||||||
|
pfree(inc_fullname);
|
||||||
|
|
||||||
/* Create comma-separated string from List */
|
/* Create comma-separated string from List */
|
||||||
|
comma_str = pstrdup("");
|
||||||
foreach(line, inc_lines)
|
foreach(line, inc_lines)
|
||||||
{
|
{
|
||||||
List *token_list = (List *) lfirst(line);
|
List *token_list = (List *) lfirst(line);
|
||||||
@ -357,6 +372,13 @@ tokenize_inc_file(const char *inc_filename)
|
|||||||
|
|
||||||
free_lines(&inc_lines, &inc_line_nums);
|
free_lines(&inc_lines, &inc_line_nums);
|
||||||
|
|
||||||
|
/* if file is empty, return single space rather than empty string */
|
||||||
|
if (strlen(comma_str) == 0)
|
||||||
|
{
|
||||||
|
pfree(comma_str);
|
||||||
|
return pstrdup(" ");
|
||||||
|
}
|
||||||
|
|
||||||
return comma_str;
|
return comma_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,9 +387,12 @@ tokenize_inc_file(const char *inc_filename)
|
|||||||
* Tokenize the given file, storing the resulting data into two lists:
|
* Tokenize the given file, storing the resulting data into two lists:
|
||||||
* a list of sublists, each sublist containing the tokens in a line of
|
* a list of sublists, each sublist containing the tokens in a line of
|
||||||
* the file, and a list of line numbers.
|
* the file, and a list of line numbers.
|
||||||
|
*
|
||||||
|
* filename must be the absolute path to the target file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
tokenize_file(FILE *file, List **lines, List **line_nums)
|
tokenize_file(const char *filename, FILE *file,
|
||||||
|
List **lines, List **line_nums)
|
||||||
{
|
{
|
||||||
List *current_line = NIL;
|
List *current_line = NIL;
|
||||||
int line_number = 1;
|
int line_number = 1;
|
||||||
@ -377,7 +402,7 @@ tokenize_file(FILE *file, List **lines, List **line_nums)
|
|||||||
|
|
||||||
while (!feof(file))
|
while (!feof(file))
|
||||||
{
|
{
|
||||||
buf = next_token_expand(file);
|
buf = next_token_expand(filename, file);
|
||||||
|
|
||||||
/* add token to list, unless we are at EOL or comment start */
|
/* add token to list, unless we are at EOL or comment start */
|
||||||
if (buf[0])
|
if (buf[0])
|
||||||
@ -893,61 +918,13 @@ check_hba(hbaPort *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open the group file if possible (return NULL if not)
|
|
||||||
*/
|
|
||||||
static FILE *
|
|
||||||
group_openfile(void)
|
|
||||||
{
|
|
||||||
char *filename;
|
|
||||||
FILE *groupfile;
|
|
||||||
|
|
||||||
filename = group_getfilename();
|
|
||||||
groupfile = AllocateFile(filename, "r");
|
|
||||||
|
|
||||||
if (groupfile == NULL && errno != ENOENT)
|
|
||||||
ereport(LOG,
|
|
||||||
(errcode_for_file_access(),
|
|
||||||
errmsg("could not open file \"%s\": %m", filename)));
|
|
||||||
|
|
||||||
pfree(filename);
|
|
||||||
|
|
||||||
return groupfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open the password file if possible (return NULL if not)
|
|
||||||
*/
|
|
||||||
static FILE *
|
|
||||||
user_openfile(void)
|
|
||||||
{
|
|
||||||
char *filename;
|
|
||||||
FILE *pwdfile;
|
|
||||||
|
|
||||||
filename = user_getfilename();
|
|
||||||
pwdfile = AllocateFile(filename, "r");
|
|
||||||
|
|
||||||
if (pwdfile == NULL && errno != ENOENT)
|
|
||||||
ereport(LOG,
|
|
||||||
(errcode_for_file_access(),
|
|
||||||
errmsg("could not open file \"%s\": %m", filename)));
|
|
||||||
|
|
||||||
pfree(filename);
|
|
||||||
|
|
||||||
return pwdfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load group/user name mapping file
|
* Load group/user name mapping file
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
load_group(void)
|
load_group(void)
|
||||||
{
|
{
|
||||||
|
char *filename;
|
||||||
FILE *group_file;
|
FILE *group_file;
|
||||||
|
|
||||||
/* Discard any old data */
|
/* Discard any old data */
|
||||||
@ -958,11 +935,25 @@ load_group(void)
|
|||||||
group_sorted = NULL;
|
group_sorted = NULL;
|
||||||
group_length = 0;
|
group_length = 0;
|
||||||
|
|
||||||
group_file = group_openfile();
|
/* Read in the file contents */
|
||||||
if (!group_file)
|
filename = group_getfilename();
|
||||||
|
group_file = AllocateFile(filename, "r");
|
||||||
|
|
||||||
|
if (group_file == NULL)
|
||||||
|
{
|
||||||
|
/* no complaint if not there */
|
||||||
|
if (errno != ENOENT)
|
||||||
|
ereport(LOG,
|
||||||
|
(errcode_for_file_access(),
|
||||||
|
errmsg("could not open file \"%s\": %m", filename)));
|
||||||
|
pfree(filename);
|
||||||
return;
|
return;
|
||||||
tokenize_file(group_file, &group_lines, &group_line_nums);
|
}
|
||||||
|
|
||||||
|
tokenize_file(filename, group_file, &group_lines, &group_line_nums);
|
||||||
|
|
||||||
FreeFile(group_file);
|
FreeFile(group_file);
|
||||||
|
pfree(filename);
|
||||||
|
|
||||||
/* create sorted lines for binary searching */
|
/* create sorted lines for binary searching */
|
||||||
group_length = list_length(group_lines);
|
group_length = list_length(group_lines);
|
||||||
@ -990,6 +981,7 @@ load_group(void)
|
|||||||
void
|
void
|
||||||
load_user(void)
|
load_user(void)
|
||||||
{
|
{
|
||||||
|
char *filename;
|
||||||
FILE *user_file;
|
FILE *user_file;
|
||||||
|
|
||||||
/* Discard any old data */
|
/* Discard any old data */
|
||||||
@ -1000,11 +992,25 @@ load_user(void)
|
|||||||
user_sorted = NULL;
|
user_sorted = NULL;
|
||||||
user_length = 0;
|
user_length = 0;
|
||||||
|
|
||||||
user_file = user_openfile();
|
/* Read in the file contents */
|
||||||
if (!user_file)
|
filename = user_getfilename();
|
||||||
|
user_file = AllocateFile(filename, "r");
|
||||||
|
|
||||||
|
if (user_file == NULL)
|
||||||
|
{
|
||||||
|
/* no complaint if not there */
|
||||||
|
if (errno != ENOENT)
|
||||||
|
ereport(LOG,
|
||||||
|
(errcode_for_file_access(),
|
||||||
|
errmsg("could not open file \"%s\": %m", filename)));
|
||||||
|
pfree(filename);
|
||||||
return;
|
return;
|
||||||
tokenize_file(user_file, &user_lines, &user_line_nums);
|
}
|
||||||
|
|
||||||
|
tokenize_file(filename, user_file, &user_lines, &user_line_nums);
|
||||||
|
|
||||||
FreeFile(user_file);
|
FreeFile(user_file);
|
||||||
|
pfree(filename);
|
||||||
|
|
||||||
/* create sorted lines for binary searching */
|
/* create sorted lines for binary searching */
|
||||||
user_length = list_length(user_lines);
|
user_length = list_length(user_lines);
|
||||||
@ -1045,7 +1051,7 @@ load_hba(void)
|
|||||||
errmsg("could not open configuration file \"%s\": %m",
|
errmsg("could not open configuration file \"%s\": %m",
|
||||||
HbaFileName)));
|
HbaFileName)));
|
||||||
|
|
||||||
tokenize_file(file, &hba_lines, &hba_line_nums);
|
tokenize_file(HbaFileName, file, &hba_lines, &hba_line_nums);
|
||||||
FreeFile(file);
|
FreeFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1189,7 +1195,7 @@ load_ident(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tokenize_file(file, &ident_lines, &ident_line_nums);
|
tokenize_file(IdentFileName, file, &ident_lines, &ident_line_nums);
|
||||||
FreeFile(file);
|
FreeFile(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user