Adjust configuration-files GUC behavior as per my recent proposal.

The vars are renamed to data_directory, config_file, hba_file, and
ident_file, and are guaranteed to be set to accurate absolute paths
during postmaster startup.
This commit does not yet do anything about hiding path values from
non-superusers.
This commit is contained in:
Tom Lane 2004-10-09 23:13:22 +00:00
parent 0d069c53c3
commit 337ffcddba
8 changed files with 262 additions and 214 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.286 2004/10/08 01:36:31 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.287 2004/10/09 23:12:53 tgl Exp $
--> -->
<Chapter Id="runtime"> <Chapter Id="runtime">
@ -568,8 +568,8 @@ SET ENABLE_SEQSCAN TO OFF;
<title>File Locations</title> <title>File Locations</title>
<variablelist> <variablelist>
<varlistentry id="guc-pgdata" xreflabel="pgdata"> <varlistentry id="guc-data-directory" xreflabel="data-directory">
<term><varname>pgdata</varname> (<type>string</type>)</term> <term><varname>data_directory</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
Specifies the directory to use for data storage. Specifies the directory to use for data storage.
@ -578,36 +578,45 @@ SET ENABLE_SEQSCAN TO OFF;
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-hba-conf" xreflabel="hba-conf"> <varlistentry id="guc-config-file" xreflabel="config-file">
<term><varname>hba_conf</varname> (<type>string</type>)</term> <term><varname>config_file</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
Specifies the file name to use for configuration of host-based Specifies the main server configuration file
authentication (HBA). (customarily called <filename>postgresql.conf</>).
This option can only be set at server start or in the This option can only be set on the postmaster command line.
<filename>postgresql.conf</filename> file.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-ident-conf" xreflabel="ident-conf"> <varlistentry id="guc-hba-file" xreflabel="hba-file">
<term><varname>ident_conf</varname> (<type>string</type>)</term> <term><varname>hba_file</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
Specifies the file name to use for configuration of Specifies the configuration file for host-based authentication.
This option can only be set at server start.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-ident-file" xreflabel="ident-file">
<term><varname>ident_file</varname> (<type>string</type>)</term>
<listitem>
<para>
Specifies the configuration file for
<application>ident</> authentication. <application>ident</> authentication.
This option can only be set at server start or in the This option can only be set at server start.
<filename>postgresql.conf</filename> file.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="external-pidfile" xreflabel="external-pidfile"> <varlistentry id="external-pid-file" xreflabel="external-pid-file">
<term><varname>external_pidfile</varname> (<type>string</type>)</term> <term><varname>external_pid_file</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
Specifies the location of an additional <application>postmaster</> Specifies that the <application>postmaster</> should create an
process-id (PID) file for use by server administration programs. additional process-id (PID) file for use by server administration
programs.
This option can only be set at server start. This option can only be set at server start.
</para> </para>
</listitem> </listitem>
@ -616,11 +625,10 @@ SET ENABLE_SEQSCAN TO OFF;
<para> <para>
In a default installation, none of the above options is set explicitly In a default installation, none of the above options is set explicitly
in the <filename>postgresql.conf</filename> file. In this case, the in the <filename>postgresql.conf</filename> file. Instead, the
data directory is specified by the <option>-D</option> command-line data directory is specified by the <option>-D</option> command-line
option or the <envar>PGDATA</envar> environment variable; there is no option or the <envar>PGDATA</envar> environment variable, and the
default for it. The configuration files are all placed within the configuration files are all placed within the data directory.
data directory.
</para> </para>
<para> <para>
@ -630,27 +638,29 @@ SET ENABLE_SEQSCAN TO OFF;
when they are kept separate.) To do this, the <option>-D</option> when they are kept separate.) To do this, the <option>-D</option>
command-line option or <envar>PGDATA</envar> environment variable command-line option or <envar>PGDATA</envar> environment variable
must point to the directory containing the configuration files, must point to the directory containing the configuration files,
and the <varname>pgdata</> option is set in and the <varname>data_directory</> option is set in
<filename>postgresql.conf</filename> (or on the command line) to show <filename>postgresql.conf</filename> (or on the command line) to show
where the data directory is actually located. where the data directory is actually located. Notice that
<varname>data_directory</> overrides <option>-D</option> for the location
of the data directory, but not for the location of the configuration
files.
</para> </para>
<para> <para>
If you wish, you can also make the <option>-D</option> If you wish, you can specify the configuration file names and locations
command-line option or <envar>PGDATA</envar> environment variable individually using the options <varname>config_file</>,
point directly to the master configuration file (which then need not be <varname>hba_file</> and/or <varname>ident_file</>.
named <filename>postgresql.conf</filename>). The <varname>pgdata</> <varname>config_file</> can only be specified on the
option must be set to determine the data directory location. <command>postmaster</command> command line, but the others can be
The other configuration files will by default be sought set within the main configuration file. If all three options plus
in the data directory. <varname>data_directory</> are explicitly set, then it is not necessary
to specify <option>-D</option> or <envar>PGDATA</envar>.
</para> </para>
<para> <para>
With any of these approaches, you can specify the locations of the When setting any of these options, a relative path will be interpreted
secondary configuration files (<filename>pg_hba.conf</> and with respect to the directory in which the <command>postmaster</command>
<filename>pg_ident.conf</>) by setting <varname>hba_conf</> and/or is started.
<varname>ident_conf</> in the master configuration file. These options
override the normal locations and names of the secondary files.
</para> </para>
</sect2> </sect2>

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.131 2004/10/08 01:36:34 tgl Exp $ * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.132 2004/10/09 23:12:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -44,12 +44,6 @@
/* Standard TCP port number for Ident service. Assigned by IANA */ /* Standard TCP port number for Ident service. Assigned by IANA */
#define IDENT_PORT 113 #define IDENT_PORT 113
/* Name of the config file */
#define CONF_FILE "pg_hba.conf"
/* Name of the usermap file */
#define USERMAP_FILE "pg_ident.conf"
/* This is used to separate values in multi-valued column strings */ /* This is used to separate values in multi-valued column strings */
#define MULTI_VALUE_SEP "\001" #define MULTI_VALUE_SEP "\001"
@ -65,11 +59,11 @@
* one token, since blank lines are not entered in the data structure. * one token, since blank lines are not entered in the data structure.
*/ */
/* pre-parsed content of CONF_FILE and corresponding line #s */ /* pre-parsed content of HBA config file and corresponding line #s */
static List *hba_lines = NIL; static List *hba_lines = NIL;
static List *hba_line_nums = NIL; static List *hba_line_nums = NIL;
/* pre-parsed content of USERMAP_FILE and corresponding line #s */ /* pre-parsed content of ident usermap file and corresponding line #s */
static List *ident_lines = NIL; static List *ident_lines = NIL;
static List *ident_line_nums = NIL; static List *ident_line_nums = NIL;
@ -743,8 +737,9 @@ parse_hba(List *line, int line_num, hbaPort *port,
{ {
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid IP address \"%s\" in pg_hba.conf file line %d: %s", errmsg("invalid IP address \"%s\" in \"%s\" line %d: %s",
token, line_num, gai_strerror(ret)))); token, HbaFileName, line_num,
gai_strerror(ret))));
if (cidr_slash) if (cidr_slash)
*cidr_slash = '/'; *cidr_slash = '/';
if (gai_result) if (gai_result)
@ -777,8 +772,9 @@ parse_hba(List *line, int line_num, hbaPort *port,
{ {
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid IP mask \"%s\" in pg_hba.conf file line %d: %s", errmsg("invalid IP mask \"%s\" in \"%s\" line %d: %s",
token, line_num, gai_strerror(ret)))); token, HbaFileName, line_num,
gai_strerror(ret))));
if (gai_result) if (gai_result)
freeaddrinfo_all(hints.ai_family, gai_result); freeaddrinfo_all(hints.ai_family, gai_result);
goto hba_other_error; goto hba_other_error;
@ -791,8 +787,8 @@ parse_hba(List *line, int line_num, hbaPort *port,
{ {
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("IP address and mask do not match in pg_hba.conf file line %d", errmsg("IP address and mask do not match in \"%s\" line %d",
line_num))); HbaFileName, line_num)));
goto hba_other_error; goto hba_other_error;
} }
} }
@ -849,13 +845,14 @@ hba_syntax:
if (line_item) if (line_item)
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid entry in pg_hba.conf file at line %d, token \"%s\"", errmsg("invalid entry in \"%s\" at line %d, token \"%s\"",
line_num, (char *) lfirst(line_item)))); HbaFileName, line_num,
(char *) lfirst(line_item))));
else else
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("missing field in pg_hba.conf file at end of line %d", errmsg("missing field in \"%s\" at end of line %d",
line_num))); HbaFileName, line_num)));
/* Come here if suitable message already logged */ /* Come here if suitable message already logged */
hba_other_error: hba_other_error:
@ -1030,42 +1027,25 @@ load_user(void)
/* /*
* Read the config file and create a List of Lists of tokens in the file. * Read the config file and create a List of Lists of tokens in the file.
* If we find a file by the old name of the config file (pg_hba), we issue
* an error message because it probably needs to be converted. He didn't
* follow directions and just installed his old hba file in the new database
* system.
*/ */
void void
load_hba(void) load_hba(void)
{ {
FILE *file; /* The config file we have to read */ FILE *file;
char *conf_file; /* The name of the config file */
if (hba_lines || hba_line_nums) if (hba_lines || hba_line_nums)
free_lines(&hba_lines, &hba_line_nums); free_lines(&hba_lines, &hba_line_nums);
if (guc_hbafile) file = AllocateFile(HbaFileName, "r");
{ /* Failure is fatal since with no HBA entries we can do nothing... */
/* HBA filename specified in config file */
conf_file = pstrdup(guc_hbafile);
}
else
{
/* put together the full pathname to the config file */
conf_file = palloc(strlen(ConfigDir) + strlen(CONF_FILE) + 2);
sprintf(conf_file, "%s/%s", ConfigDir, CONF_FILE);
}
file = AllocateFile(conf_file, "r");
if (file == NULL) if (file == NULL)
ereport(FATAL, ereport(FATAL,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not open configuration file \"%s\": %m", errmsg("could not open configuration file \"%s\": %m",
conf_file))); HbaFileName)));
tokenize_file(file, &hba_lines, &hba_line_nums); tokenize_file(file, &hba_lines, &hba_line_nums);
FreeFile(file); FreeFile(file);
pfree(conf_file);
} }
@ -1121,13 +1101,14 @@ ident_syntax:
if (line_item) if (line_item)
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid entry in pg_ident.conf file at line %d, token \"%s\"", errmsg("invalid entry in \"%s\" at line %d, token \"%s\"",
line_number, (const char *) lfirst(line_item)))); IdentFileName, line_number,
(const char *) lfirst(line_item))));
else else
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("missing entry in pg_ident.conf file at end of line %d", errmsg("missing entry in \"%s\" at end of line %d",
line_number))); IdentFileName, line_number)));
*error_p = true; *error_p = true;
} }
@ -1191,38 +1172,25 @@ check_ident_usermap(const char *usermap_name,
void void
load_ident(void) load_ident(void)
{ {
FILE *file; /* The map file we have to read */ FILE *file;
char *map_file; /* The name of the map file we have to
* read */
if (ident_lines || ident_line_nums) if (ident_lines || ident_line_nums)
free_lines(&ident_lines, &ident_line_nums); free_lines(&ident_lines, &ident_line_nums);
if (guc_identfile) file = AllocateFile(IdentFileName, "r");
{
/* IDENT filename specified in config file */
map_file = pstrdup(guc_identfile);
}
else
{
map_file = palloc(strlen(ConfigDir) + strlen(USERMAP_FILE) + 2);
sprintf(map_file, "%s/%s", ConfigDir, USERMAP_FILE);
}
file = AllocateFile(map_file, "r");
if (file == NULL) if (file == NULL)
{ {
/* not fatal ... we just won't do any special ident maps */
ereport(LOG, ereport(LOG,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not open Ident usermap file \"%s\": %m", errmsg("could not open Ident usermap file \"%s\": %m",
map_file))); IdentFileName)));
} }
else else
{ {
tokenize_file(file, &ident_lines, &ident_line_nums); tokenize_file(file, &ident_lines, &ident_line_nums);
FreeFile(file); FreeFile(file);
} }
pfree(map_file);
} }

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.430 2004/10/08 01:36:34 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.431 2004/10/09 23:13:02 tgl Exp $
* *
* NOTES * NOTES
* *
@ -537,10 +537,6 @@ PostmasterMain(int argc, char *argv[])
/* Verify that DataDir looks reasonable */ /* Verify that DataDir looks reasonable */
checkDataDir(); checkDataDir();
#ifdef EXEC_BACKEND
write_nondefault_variables(PGC_POSTMASTER);
#endif
/* /*
* Check for invalid combinations of GUC settings. * Check for invalid combinations of GUC settings.
*/ */
@ -782,12 +778,16 @@ PostmasterMain(int argc, char *argv[])
if (!CreateOptsFile(argc, argv, my_exec_path)) if (!CreateOptsFile(argc, argv, my_exec_path))
ExitPostmaster(1); ExitPostmaster(1);
#ifdef EXEC_BACKEND
write_nondefault_variables(PGC_POSTMASTER);
#endif
/* /*
* Write the external PID file if requested * Write the external PID file if requested
*/ */
if (external_pidfile) if (external_pid_file)
{ {
FILE *fpidfile = fopen(external_pidfile, "w"); FILE *fpidfile = fopen(external_pid_file, "w");
if (fpidfile) if (fpidfile)
{ {
@ -797,7 +797,7 @@ PostmasterMain(int argc, char *argv[])
} }
else else
write_stderr("%s: could not write external pid file \"%s\": %s\n", write_stderr("%s: could not write external pid file \"%s\": %s\n",
progname, external_pidfile, strerror(errno)); progname, external_pid_file, strerror(errno));
} }
/* /*
@ -860,10 +860,6 @@ PostmasterMain(int argc, char *argv[])
*/ */
StartupPID = StartupDataBase(); StartupPID = StartupDataBase();
#ifdef EXEC_BACKEND
write_nondefault_variables(PGC_POSTMASTER);
#endif
status = ServerLoop(); status = ServerLoop();
/* /*
@ -3390,12 +3386,6 @@ write_backend_variables(char *filename, Port *port)
StrNCpy(str_buf, DataDir, MAXPGPATH); StrNCpy(str_buf, DataDir, MAXPGPATH);
write_array_var(str_buf, fp); write_array_var(str_buf, fp);
StrNCpy(str_buf, ConfigDir, MAXPGPATH);
write_array_var(str_buf, fp);
StrNCpy(str_buf, ConfigFileName, MAXPGPATH);
write_array_var(str_buf, fp);
write_array_var(ListenSocket, fp); write_array_var(ListenSocket, fp);
write_var(MyCancelKey, fp); write_var(MyCancelKey, fp);
@ -3470,12 +3460,6 @@ read_backend_variables(char *filename, Port *port)
read_array_var(str_buf, fp); read_array_var(str_buf, fp);
SetDataDir(str_buf); SetDataDir(str_buf);
read_array_var(str_buf, fp);
ConfigDir = strdup(str_buf);
read_array_var(str_buf, fp);
ConfigFileName = strdup(str_buf);
read_array_var(ListenSocket, fp); read_array_var(ListenSocket, fp);
read_var(MyCancelKey, fp); read_var(MyCancelKey, fp);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.134 2004/10/04 14:55:17 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.135 2004/10/09 23:13:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -171,7 +171,34 @@ SetDataDir(const char *dir)
AssertArg(dir); AssertArg(dir);
/* If presented path is relative, convert to absolute */ /* If presented path is relative, convert to absolute */
if (!is_absolute_path(dir)) new = make_absolute_path(dir);
if (DataDir)
free(DataDir);
DataDir = new;
}
/*
* If the given pathname isn't already absolute, make it so, interpreting
* it relative to the current working directory.
*
* Also canonicalizes the path. The result is always a malloc'd copy.
*
* Note: it is probably unwise to use this in running backends, since they
* have chdir'd to a database-specific subdirectory; the results would not be
* consistent across backends. Currently this is used only during postmaster
* or standalone-backend startup.
*/
char *
make_absolute_path(const char *path)
{
char *new;
/* Returning null for null input is convenient for some callers */
if (path == NULL)
return NULL;
if (!is_absolute_path(path))
{ {
char *buf; char *buf;
size_t buflen; size_t buflen;
@ -200,28 +227,27 @@ SetDataDir(const char *dir)
} }
} }
new = malloc(strlen(buf) + 1 + strlen(dir) + 1); new = malloc(strlen(buf) + strlen(path) + 2);
if (!new) if (!new)
ereport(FATAL, ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
sprintf(new, "%s/%s", buf, dir); sprintf(new, "%s/%s", buf, path);
free(buf); free(buf);
} }
else else
{ {
new = strdup(dir); new = strdup(path);
if (!new) if (!new)
ereport(FATAL, ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
} }
/* Make sure punctuation is canonical, too */
canonicalize_path(new); canonicalize_path(new);
if (DataDir) return new;
free(DataDir);
DataDir = new;
} }

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.240 2004/10/08 01:36:35 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.241 2004/10/09 23:13:10 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
@ -64,7 +64,9 @@
#define PG_KRB_SRVTAB "" #define PG_KRB_SRVTAB ""
#endif #endif
#define CONFIG_FILENAME "postgresql.conf" #define CONFIG_FILENAME "postgresql.conf"
#define HBA_FILENAME "pg_hba.conf"
#define IDENT_FILENAME "pg_ident.conf"
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
#define CONFIG_EXEC_PARAMS "global/config_exec_params" #define CONFIG_EXEC_PARAMS "global/config_exec_params"
@ -113,13 +115,6 @@ static bool assign_transaction_read_only(bool newval, bool doit, GucSource sourc
static const char *assign_canonical_path(const char *newval, bool doit, GucSource source); static const char *assign_canonical_path(const char *newval, bool doit, GucSource source);
/*
* These are initialized by SelectConfigFiles.
*/
char *ConfigDir = NULL;
char *ConfigFileName = NULL;
/* /*
* GUC option variables that are exported from this module * GUC option variables that are exported from this module
*/ */
@ -154,9 +149,10 @@ int client_min_messages = NOTICE;
int log_min_duration_statement = -1; int log_min_duration_statement = -1;
char *guc_hbafile; char *ConfigFileName;
char *guc_identfile; char *HbaFileName;
char *external_pidfile; char *IdentFileName;
char *external_pid_file;
/* /*
@ -183,7 +179,7 @@ static char *server_encoding_string;
static char *server_version_string; static char *server_version_string;
static char *timezone_string; static char *timezone_string;
static char *XactIsoLevel_string; static char *XactIsoLevel_string;
static char *guc_pgdata; static char *data_directory;
static char *custom_variable_classes; static char *custom_variable_classes;
static int max_function_args; static int max_function_args;
static int max_index_keys; static int max_index_keys;
@ -1685,11 +1681,11 @@ static struct config_string ConfigureNamesString[] =
{ {
{"log_directory", PGC_SIGHUP, LOGGING_WHERE, {"log_directory", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Sets the destination directory for log files."), gettext_noop("Sets the destination directory for log files."),
gettext_noop("May be specified as relative to the cluster directory " gettext_noop("May be specified as relative to the data directory "
"or as absolute path.") "or as absolute path.")
}, },
&Log_directory, &Log_directory,
"pg_log", NULL, NULL "pg_log", assign_canonical_path, NULL
}, },
{ {
{"log_filename", PGC_SIGHUP, LOGGING_WHERE, {"log_filename", PGC_SIGHUP, LOGGING_WHERE,
@ -1789,38 +1785,48 @@ static struct config_string ConfigureNamesString[] =
}, },
{ {
{"pgdata", PGC_POSTMASTER, FILE_LOCATIONS, {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the location of the data directory"), gettext_noop("Sets the server's data directory"),
NULL NULL
}, },
&guc_pgdata, &data_directory,
NULL, assign_canonical_path, NULL NULL, NULL, NULL
}, },
{ {
{"hba_conf", PGC_SIGHUP, FILE_LOCATIONS, {"config_file", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the location of the \"hba\" configuration file"), gettext_noop("Sets the server's main configuration file"),
NULL NULL,
GUC_DISALLOW_IN_FILE
}, },
&guc_hbafile, &ConfigFileName,
NULL, assign_canonical_path, NULL NULL, NULL, NULL
}, },
{ {
{"ident_conf", PGC_SIGHUP, FILE_LOCATIONS, {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the location of the \"ident\" configuration file"), gettext_noop("Sets the server's \"hba\" configuration file"),
NULL NULL
}, },
&guc_identfile, &HbaFileName,
NULL, assign_canonical_path, NULL NULL, NULL, NULL
}, },
{ {
{"external_pidfile", PGC_POSTMASTER, FILE_LOCATIONS, {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the server's \"ident\" configuration file"),
NULL
},
&IdentFileName,
NULL, NULL, NULL
},
{
{"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Writes the postmaster PID to the specified file"), gettext_noop("Writes the postmaster PID to the specified file"),
NULL NULL
}, },
&external_pidfile, &external_pid_file,
NULL, assign_canonical_path, NULL NULL, assign_canonical_path, NULL
}, },
@ -2453,47 +2459,52 @@ InitializeGUCOptions(void)
bool bool
SelectConfigFiles(const char *userDoption, const char *progname) SelectConfigFiles(const char *userDoption, const char *progname)
{ {
char *Doption; char *configdir;
char *fname;
struct stat stat_buf; struct stat stat_buf;
/* If user did not specify -D, it defaults to $PGDATA */ /* configdir is -D option, or $PGDATA if no -D */
if (!userDoption) if (userDoption)
userDoption = getenv("PGDATA"); configdir = make_absolute_path(userDoption);
else
configdir = make_absolute_path(getenv("PGDATA"));
/* If no PGDATA either, we are completely lost */ /*
if (!userDoption) * Find the configuration file: if config_file was specified on the
* command line, use it, else use configdir/postgresql.conf. In any
* case ensure the result is an absolute path, so that it will be
* interpreted the same way by future backends.
*/
if (ConfigFileName)
fname = make_absolute_path(ConfigFileName);
else if (!configdir)
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the server configuration file.\n"
"You must specify the -D invocation option or set the " "You must specify the --config_file or -D invocation "
"PGDATA environment variable.\n", "option or set the PGDATA environment variable.\n",
progname); progname);
return false; return false;
} }
/* Get a writable copy and canonicalize the path */
Doption = guc_strdup(FATAL, userDoption);
canonicalize_path(Doption);
/*
* If it is a directory, point ConfigDir to it, and expect to
* find postgresql.conf within. Otherwise it had better be
* the actual config file, and the file had better set "pgdata".
*/
if (stat(Doption, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode))
{
ConfigDir = Doption;
ConfigFileName = guc_malloc(FATAL,
strlen(ConfigDir) + strlen(CONFIG_FILENAME) + 2);
sprintf(ConfigFileName, "%s/%s", ConfigDir, CONFIG_FILENAME);
}
else else
{ {
ConfigFileName = Doption; fname = guc_malloc(FATAL,
strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
} }
/*
* Set the ConfigFileName GUC variable to its final value, ensuring
* that it can't be overridden later.
*/
SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
free(fname);
/*
* Now read the config file for the first time.
*/
if (stat(ConfigFileName, &stat_buf) != 0) if (stat(ConfigFileName, &stat_buf) != 0)
{ {
write_stderr("%s cannot access the data directory or configuration file \"%s\": %s\n", write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
progname, ConfigFileName, strerror(errno)); progname, ConfigFileName, strerror(errno));
return false; return false;
} }
@ -2501,32 +2512,81 @@ SelectConfigFiles(const char *userDoption, const char *progname)
ProcessConfigFile(PGC_POSTMASTER); ProcessConfigFile(PGC_POSTMASTER);
/* /*
* If the config file specified pgdata, use that as DataDir; * If the data_directory GUC variable has been set, use that as DataDir;
* otherwise use ConfigDir (the original Doption) if set; * otherwise use configdir if set; else punt.
* else punt.
* *
* Note: SetDataDir will copy and canonicalize its argument, * Note: SetDataDir will copy and absolute-ize its argument,
* so we don't have to. * so we don't have to.
*/ */
if (guc_pgdata) if (data_directory)
SetDataDir(guc_pgdata); SetDataDir(data_directory);
else if (ConfigDir) else if (configdir)
SetDataDir(ConfigDir); SetDataDir(configdir);
else else
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the database system data.\n"
"This should be specified as \"pgdata\" in \"%s\".\n", "This can be specified as \"data_directory\" in \"%s\", "
"or by the -D invocation option, or by the "
"PGDATA environment variable.\n",
progname, ConfigFileName); progname, ConfigFileName);
return false; return false;
} }
/* /*
* Set ConfigDir as DataDir unless we had another value (which is to say, * Reflect the final DataDir value back into the data_directory GUC var.
* Doption pointed to a directory). This determines the default location * (If you are wondering why we don't just make them a single variable,
* of secondary configuration files that will be read later. * it's because the EXEC_BACKEND case needs DataDir to be transmitted to
* child backends specially.)
*/ */
if (!ConfigDir) SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
ConfigDir = DataDir;
/*
* Figure out where pg_hba.conf is, and make sure the path is absolute.
*/
if (HbaFileName)
fname = make_absolute_path(HbaFileName);
else if (!configdir)
{
write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
"This can be specified as \"hba_file\" in \"%s\", "
"or by the -D invocation option, or by the "
"PGDATA environment variable.\n",
progname, ConfigFileName);
return false;
}
else
{
fname = guc_malloc(FATAL,
strlen(configdir) + strlen(HBA_FILENAME) + 2);
sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
}
SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
free(fname);
/*
* Likewise for pg_ident.conf.
*/
if (IdentFileName)
fname = make_absolute_path(IdentFileName);
else if (!configdir)
{
write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
"This can be specified as \"ident_file\" in \"%s\", "
"or by the -D invocation option, or by the "
"PGDATA environment variable.\n",
progname, ConfigFileName);
return false;
}
else
{
fname = guc_malloc(FATAL,
strlen(configdir) + strlen(IDENT_FILENAME) + 2);
sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
}
SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
free(fname);
free(configdir);
/* If timezone is not set, determine what the OS uses */ /* If timezone is not set, determine what the OS uses */
pg_timezone_initialize(); pg_timezone_initialize();
@ -5703,7 +5763,6 @@ assign_canonical_path(const char *newval, bool doit, GucSource source)
{ {
if (doit) if (doit)
{ {
/* We have to create a new pointer to force the change */
char *canon_val = guc_strdup(ERROR, newval); char *canon_val = guc_strdup(ERROR, newval);
canonicalize_path(canon_val); canonicalize_path(canon_val);
@ -5713,4 +5772,5 @@ assign_canonical_path(const char *newval, bool doit, GucSource source)
return newval; return newval;
} }
#include "guc-file.c" #include "guc-file.c"

View File

@ -30,13 +30,13 @@
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# The default values of these variables are driven from the -D command line # The default values of these variables are driven from the -D command line
# switch or PGDATA environment variable, represented here as $PGDATA. # switch or PGDATA environment variable, represented here as ConfigDir.
# pgdata = '$PGDATA' # use data in another directory # data_directory = 'ConfigDir' # use data in another directory
# hba_conf = '$PGDATA/pg_hba.conf' # the host-based authentication file # hba_file = 'ConfigDir/pg_hba.conf' # the host-based authentication file
# ident_conf = '$PGDATA/pg_ident.conf' # the IDENT configuration file # ident_file = 'ConfigDir/pg_ident.conf' # the IDENT configuration file
# If external_pidfile is not explicitly set, no extra pid file is written. # If external_pid_file is not explicitly set, no extra pid file is written.
# external_pidfile = '(none)' # write an extra pid file # external_pid_file = '(none)' # write an extra pid file
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.168 2004/09/06 23:55:34 tgl Exp $ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.169 2004/10/09 23:13:14 tgl Exp $
* *
* NOTES * NOTES
* some of the information in this file should be moved to other files. * some of the information in this file should be moved to other files.
@ -241,6 +241,7 @@ extern void InitializeSessionUserIdStandalone(void);
extern void SetSessionAuthorization(AclId userid, bool is_superuser); extern void SetSessionAuthorization(AclId userid, bool is_superuser);
extern void SetDataDir(const char *dir); extern void SetDataDir(const char *dir);
extern char *make_absolute_path(const char *path);
/* in utils/misc/superuser.c */ /* in utils/misc/superuser.c */
extern bool superuser(void); /* current user is superuser */ extern bool superuser(void); /* current user is superuser */

View File

@ -7,7 +7,7 @@
* Copyright (c) 2000-2004, PostgreSQL Global Development Group * Copyright (c) 2000-2004, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.52 2004/10/08 01:36:36 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.53 2004/10/09 23:13:22 tgl Exp $
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
#ifndef GUC_H #ifndef GUC_H
@ -135,11 +135,10 @@ extern int log_min_messages;
extern int client_min_messages; extern int client_min_messages;
extern int log_min_duration_statement; extern int log_min_duration_statement;
extern char *ConfigDir;
extern char *ConfigFileName; extern char *ConfigFileName;
extern char *guc_hbafile; extern char *HbaFileName;
extern char *guc_identfile; extern char *IdentFileName;
extern char *external_pidfile; extern char *external_pid_file;
extern void SetConfigOption(const char *name, const char *value, extern void SetConfigOption(const char *name, const char *value,