Fix regression in .pgpass support. From Neil Conway.

This commit is contained in:
Tom Lane 2003-01-30 19:49:54 +00:00
parent 887edf4ff7
commit 4ec457ad58
2 changed files with 64 additions and 32 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.106 2003/01/19 00:13:28 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.107 2003/01/30 19:49:54 tgl Exp $
--> -->
<chapter id="libpq"> <chapter id="libpq">
@ -203,9 +203,12 @@ PGconn *PQconnectdb(const char *conninfo)
<term><literal>requiressl</literal></term> <term><literal>requiressl</literal></term>
<listitem> <listitem>
<para> <para>
Set to 1 to require SSL connection to the backend. <application>Libpq</> Set to 1 to require <acronym>SSL</acronym> connection to the server.
will then refuse to connect if the server does not support <application>Libpq</> will then refuse to connect if the server does not
SSL. Set to 0 (default) to negotiate with server. accept an <acronym>SSL</acronym> connection.
Set to 0 (default) to negotiate with server.
This option is only available if
<productname>PostgreSQL</> is compiled with SSL support.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2010,10 +2013,11 @@ routines like <function>PQgetvalue</function>.
<para> <para>
The following environment variables can be used to select default The following environment variables can be used to select default
connection parameter values, which will be used by <function>PQconnectdb</function> or connection parameter values, which will be used by
<function>PQsetdbLogin</function> if no value is directly specified by the calling code. <function>PQconnectdb</>, <function>PQsetdbLogin</> and
These are useful to avoid hard-coding database names into simple <function>PQsetdb</> if no value is directly specified by the calling
application programs. code. These are useful to avoid hard-coding database connection
information into simple client applications.
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -2091,6 +2095,25 @@ the <productname>PostgreSQL</productname> backend.
messages from the backend server are displayed. messages from the backend server are displayed.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<envar>PGREQUIRESSL</envar> sets whether or not the connection must be
made over <acronym>SSL</acronym>. If set to
<quote>1</quote>, <application>libpq</>
will refuse to connect if the server does not accept
an <acronym>SSL</acronym> connection.
This option is only available if
<productname>PostgreSQL</> is compiled with SSL support.
</para>
</listitem>
<listitem>
<para>
<envar>PGCONNECT_TIMEOUT</envar> sets the maximum number of seconds
that <application>libpq</application> will wait when attempting to
connect to the <productname>PostgreSQL</productname> server. This
option should be set to at least 2 seconds.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
@ -2161,10 +2184,10 @@ a password. This file should have the format:
<synopsis> <synopsis>
<replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable> <replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
</synopsis> </synopsis>
Any of these may be a literal name, or <literal>*</literal>, which matches Any of these may be a literal name, or <literal>*</literal>, which
anything. The first match will be used so put more specific entries first. matches anything. The first matching entry will be used, so put more-specific
Entries with <literal>:</literal> or <literal>\</literal> should be escaped entries first. When an entry contains <literal>:</literal> or
with <literal>\</literal>. <literal>\</literal>, it must be escaped with <literal>\</literal>.
</para> </para>
<para> <para>
The permissions on <filename>.pgpass</filename> must disallow any The permissions on <filename>.pgpass</filename> must disallow any

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.221 2003/01/08 21:33:27 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.222 2003/01/30 19:49:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -123,7 +123,7 @@ static const PQconninfoOption PQconninfoOptions[] = {
"Database-Password", "*", 20}, "Database-Password", "*", 20},
{"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL, {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
"Connect-timeout", "", 10}, /* strlen( INT32_MAX) == 10 */ "Connect-timeout", "", 10}, /* strlen(INT32_MAX) == 10 */
{"dbname", "PGDATABASE", NULL, NULL, {"dbname", "PGDATABASE", NULL, NULL,
"Database-Name", "", 20}, "Database-Name", "", 20},
@ -315,8 +315,14 @@ PQconnectStart(const char *conninfo)
tmp = conninfo_getval(connOptions, "password"); tmp = conninfo_getval(connOptions, "password");
conn->pgpass = tmp ? strdup(tmp) : NULL; conn->pgpass = tmp ? strdup(tmp) : NULL;
if (conn->pgpass == NULL || conn->pgpass[0] == '\0') if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
{
if (conn->pgpass)
free(conn->pgpass);
conn->pgpass = PasswordFromFile(conn->pghost, conn->pgport, conn->pgpass = PasswordFromFile(conn->pghost, conn->pgport,
conn->dbName, conn->pguser); conn->dbName, conn->pguser);
if (conn->pgpass == NULL)
conn->pgpass = strdup(DefaultPassword);
}
tmp = conninfo_getval(connOptions, "connect_timeout"); tmp = conninfo_getval(connOptions, "connect_timeout");
conn->connect_timeout = tmp ? strdup(tmp) : NULL; conn->connect_timeout = tmp ? strdup(tmp) : NULL;
#ifdef USE_SSL #ifdef USE_SSL
@ -506,14 +512,13 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
else else
conn->dbName = strdup(dbName); conn->dbName = strdup(dbName);
/*
* getPasswordFromFile mallocs its result, so we don't need strdup
* here
*/
if (pwd) if (pwd)
conn->pgpass = strdup(pwd); conn->pgpass = strdup(pwd);
else if ((tmp = getenv("PGPASSWORD")) != NULL) else if ((tmp = getenv("PGPASSWORD")) != NULL)
conn->pgpass = strdup(tmp); conn->pgpass = strdup(tmp);
else if ((tmp = PasswordFromFile(conn->pghost, conn->pgport,
conn->dbName, conn->pguser)) != NULL)
conn->pgpass = tmp;
else else
conn->pgpass = strdup(DefaultPassword); conn->pgpass = strdup(DefaultPassword);
@ -2946,7 +2951,7 @@ pwdfMatchesString(char *buf, char *token)
return NULL; return NULL;
} }
/* get a password from the password file. */ /* Get a password from the password file. Return value is malloc'd. */
char * char *
PasswordFromFile(char *hostname, char *port, char *dbname, char *username) PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
{ {
@ -2972,18 +2977,16 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
/* Look for it in the home dir */ /* Look for it in the home dir */
home = getenv("HOME"); home = getenv("HOME");
if (home) if (!home)
{
pgpassfile = malloc(strlen(home) + 1 + strlen(PGPASSFILE) + 1);
if (!pgpassfile)
{
fprintf(stderr, libpq_gettext("out of memory\n"));
return NULL;
}
}
else
return NULL; return NULL;
pgpassfile = malloc(strlen(home) + 1 + strlen(PGPASSFILE) + 1);
if (!pgpassfile)
{
fprintf(stderr, libpq_gettext("out of memory\n"));
return NULL;
}
sprintf(pgpassfile, "%s/%s", home, PGPASSFILE); sprintf(pgpassfile, "%s/%s", home, PGPASSFILE);
/* If password file cannot be opened, ignore it. */ /* If password file cannot be opened, ignore it. */
@ -3014,12 +3017,18 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
{ {
char *t = buf, char *t = buf,
*ret; *ret;
int len;
fgets(buf, LINELEN - 1, fp); fgets(buf, LINELEN - 1, fp);
if (strlen(buf) == 0)
len = strlen(buf);
if (len == 0)
continue; continue;
buf[strlen(buf) - 1] = 0; /* Remove trailing newline */
if (buf[len - 1] == '\n')
buf[len - 1] = 0;
if ((t = pwdfMatchesString(t, hostname)) == NULL || if ((t = pwdfMatchesString(t, hostname)) == NULL ||
(t = pwdfMatchesString(t, port)) == NULL || (t = pwdfMatchesString(t, port)) == NULL ||
(t = pwdfMatchesString(t, dbname)) == NULL || (t = pwdfMatchesString(t, dbname)) == NULL ||