mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Add user-specific .pg_service.conf file
This extends the existing pg_service.conf facility to first look for a service definition file in the user's home directory.
This commit is contained in:
parent
e8aae273d4
commit
41a4e45957
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.293 2010/01/20 00:42:28 rhaas Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.294 2010/01/20 21:15:21 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="libpq">
|
<chapter id="libpq">
|
||||||
<title><application>libpq</application> - C Library</title>
|
<title><application>libpq</application> - C Library</title>
|
||||||
@ -5791,6 +5791,18 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<indexterm>
|
||||||
|
<primary><envar>PGSERVICEFILE</envar></primary>
|
||||||
|
</indexterm>
|
||||||
|
<envar>PGSERVICEFILE</envar> specifies the name of the per-user
|
||||||
|
connection service file. If not set, it defaults
|
||||||
|
to <filename>~/.pg_service.conf</>
|
||||||
|
(see <xref linkend="libpq-pgservice">).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -5987,7 +5999,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
<primary><envar>PGSYSCONFDIR</envar></primary>
|
<primary><envar>PGSYSCONFDIR</envar></primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
<envar>PGSYSCONFDIR</envar> sets the directory containing the
|
<envar>PGSYSCONFDIR</envar> sets the directory containing the
|
||||||
<filename>pg_service.conf</> file.
|
<filename>pg_service.conf</> file and in a future version
|
||||||
|
possibly other system-wide configuration files.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@ -6063,6 +6076,9 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
<indexterm zone="libpq-pgservice">
|
<indexterm zone="libpq-pgservice">
|
||||||
<primary>pg_service.conf</primary>
|
<primary>pg_service.conf</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
<indexterm zone="libpq-pgservice">
|
||||||
|
<primary>.pg_service.conf</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The connection service file allows libpq connection parameters to be
|
The connection service file allows libpq connection parameters to be
|
||||||
@ -6074,12 +6090,31 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To use this feature, copy
|
The connection service file can be a per-user service file
|
||||||
<filename>share/pg_service.conf.sample</filename> to
|
at <filename>~/.pg_service.conf</filename> or the location
|
||||||
<filename>etc/pg_service.conf</filename> and edit the file to add
|
specified by the environment variable <envar>PGSERVICEFILE</envar>,
|
||||||
service names and parameters. This file can be used for client-only
|
or it can be a system-wide file
|
||||||
installs too. The file's location can also be specified by the
|
at <filename>etc/pg_service.conf</filename> or in the directory
|
||||||
<envar>PGSYSCONFDIR</envar> environment variable.
|
specified by the environment variable
|
||||||
|
<envar>PGSYSCONFDIR</envar>. If service definitions with the same
|
||||||
|
name exist in the user and the system file, the user file takes
|
||||||
|
precedence.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The file uses an <quote>INI file</quote> format where the section
|
||||||
|
name is the service name and the parameters are connection
|
||||||
|
parameters; see <xref linkend="libpq-connect"> for a list. For
|
||||||
|
example:
|
||||||
|
<programlisting>
|
||||||
|
# comment
|
||||||
|
[mydb]
|
||||||
|
host=somehost
|
||||||
|
port=5433
|
||||||
|
user=admin
|
||||||
|
</programlisting>
|
||||||
|
An example file is provided at
|
||||||
|
<filename>share/pg_service.conf.sample</filename>.
|
||||||
</para>
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.383 2010/01/15 09:19:10 heikki Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.384 2010/01/20 21:15:21 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -272,6 +272,11 @@ static void defaultNoticeReceiver(void *arg, const PGresult *res);
|
|||||||
static void defaultNoticeProcessor(void *arg, const char *message);
|
static void defaultNoticeProcessor(void *arg, const char *message);
|
||||||
static int parseServiceInfo(PQconninfoOption *options,
|
static int parseServiceInfo(PQconninfoOption *options,
|
||||||
PQExpBuffer errorMessage);
|
PQExpBuffer errorMessage);
|
||||||
|
static int parseServiceFile(const char *serviceFile,
|
||||||
|
const char *service,
|
||||||
|
PQconninfoOption *options,
|
||||||
|
PQExpBuffer errorMessage,
|
||||||
|
bool *group_found);
|
||||||
static char *pwdfMatchesString(char *buf, char *token);
|
static char *pwdfMatchesString(char *buf, char *token);
|
||||||
static char *PasswordFromFile(char *hostname, char *port, char *dbname,
|
static char *PasswordFromFile(char *hostname, char *port, char *dbname,
|
||||||
char *username);
|
char *username);
|
||||||
@ -3095,9 +3100,10 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
|||||||
{
|
{
|
||||||
char *service = conninfo_getval(options, "service");
|
char *service = conninfo_getval(options, "service");
|
||||||
char serviceFile[MAXPGPATH];
|
char serviceFile[MAXPGPATH];
|
||||||
|
char *env;
|
||||||
bool group_found = false;
|
bool group_found = false;
|
||||||
int linenr = 0,
|
int status;
|
||||||
i;
|
struct stat stat_buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to special-case the environment variable PGSERVICE here, since
|
* We have to special-case the environment variable PGSERVICE here, since
|
||||||
@ -3107,15 +3113,65 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
|||||||
if (service == NULL)
|
if (service == NULL)
|
||||||
service = getenv("PGSERVICE");
|
service = getenv("PGSERVICE");
|
||||||
|
|
||||||
|
if (service == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((env = getenv("PGSERVICEFILE")) != NULL)
|
||||||
|
strlcpy(serviceFile, env, sizeof(serviceFile));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char homedir[MAXPGPATH];
|
||||||
|
|
||||||
|
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
|
||||||
|
{
|
||||||
|
printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
|
||||||
|
errno = 0;
|
||||||
|
if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
|
||||||
|
goto next_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
|
||||||
|
if (group_found || status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
next_file:
|
||||||
/*
|
/*
|
||||||
* This could be used by any application so we can't use the binary
|
* This could be used by any application so we can't use the binary
|
||||||
* location to find our config files.
|
* location to find our config files.
|
||||||
*/
|
*/
|
||||||
snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
|
snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
|
||||||
getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
|
getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
|
||||||
|
errno = 0;
|
||||||
|
if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
|
||||||
|
goto last_file;
|
||||||
|
|
||||||
if (service != NULL)
|
status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
last_file:
|
||||||
|
if (!group_found)
|
||||||
{
|
{
|
||||||
|
printfPQExpBuffer(errorMessage,
|
||||||
|
libpq_gettext("definition of service \"%s\" not found\n"), service);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parseServiceFile(const char *serviceFile,
|
||||||
|
const char *service,
|
||||||
|
PQconninfoOption *options,
|
||||||
|
PQExpBuffer errorMessage,
|
||||||
|
bool *group_found)
|
||||||
|
{
|
||||||
|
int linenr = 0,
|
||||||
|
i;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char buf[MAXBUFSIZE],
|
char buf[MAXBUFSIZE],
|
||||||
*line;
|
*line;
|
||||||
@ -3157,7 +3213,7 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
|||||||
/* Check for right groupname */
|
/* Check for right groupname */
|
||||||
if (line[0] == '[')
|
if (line[0] == '[')
|
||||||
{
|
{
|
||||||
if (group_found)
|
if (*group_found)
|
||||||
{
|
{
|
||||||
/* group info already read */
|
/* group info already read */
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@ -3166,17 +3222,17 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
|||||||
|
|
||||||
if (strncmp(line + 1, service, strlen(service)) == 0 &&
|
if (strncmp(line + 1, service, strlen(service)) == 0 &&
|
||||||
line[strlen(service) + 1] == ']')
|
line[strlen(service) + 1] == ']')
|
||||||
group_found = true;
|
*group_found = true;
|
||||||
else
|
else
|
||||||
group_found = false;
|
*group_found = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (group_found)
|
if (*group_found)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Finally, we are in the right group and can parse the
|
* Finally, we are in the right group and can parse
|
||||||
* line
|
* the line
|
||||||
*/
|
*/
|
||||||
char *key,
|
char *key,
|
||||||
*val;
|
*val;
|
||||||
@ -3247,14 +3303,6 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
|
|||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (!group_found)
|
|
||||||
{
|
|
||||||
printfPQExpBuffer(errorMessage,
|
|
||||||
libpq_gettext("definition of service \"%s\" not found\n"), service);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user