Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7f4981f

Browse files
committed
I'm giving a try at some TODO items. Currently it's the turn of the
PGPASSWORDFILE environment variable. I have modified libpq to make use of this variable. I present the first cut here. Currently the format for the file should be host:port:database:user:password Alvaro Herrera
1 parent 46aaa5d commit 7f4981f

File tree

4 files changed

+148
-28
lines changed

4 files changed

+148
-28
lines changed

doc/src/sgml/libpq++.sgml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.41 2002/03/22 19:20:12 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.42 2002/08/15 02:56:19 momjian Exp $
33
-->
44

55
<chapter id="libpqplusplus">
@@ -117,11 +117,14 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.41 2002/03/22 19:20:
117117
</listitem>
118118
<listitem>
119119
<para>
120-
<envar>PGPASSWORD</envar>
121-
sets the password used if the backend demands password
122-
authentication. This is not recommended because the password can
123-
be read by others using the <command>ps</command> command with special options
124-
on some platforms.
120+
<envar>PGPASSWORD</envar>
121+
sets the password used if the backend demands password
122+
authentication. This is deprecated; use <envar>PGPASSWORDFILE</envar> instead.
123+
<listitem>
124+
<para>
125+
<envar>PGPASSWORDFILE</envar>
126+
sets the password file used if the backend demands password
127+
authentication. Refer to the libpq documentation for more details.
125128
</para>
126129
</listitem>
127130
<listitem>

doc/src/sgml/libpq.sgml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.90 2002/03/22 19:20:13 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.91 2002/08/15 02:56:19 momjian Exp $
33
-->
44

55
<chapter id="libpq">
@@ -2038,9 +2038,25 @@ sets the user name used to connect to the database and for authentication.
20382038
</indexterm>
20392039
<envar>PGPASSWORD</envar>
20402040
sets the password used if the backend demands password
2041-
authentication. This is not recommended because the password can
2042-
be read by others using the <command>ps</command> command with special options
2043-
on some platforms.
2041+
authentication. This functionality is deprecated for security
2042+
reasons; consider migrating to <envar>PGPASSWORDFILE</envar>.
2043+
</para>
2044+
</listitem>
2045+
<listitem>
2046+
<para>
2047+
<indexterm>
2048+
<primary><envar>PGPASSWORDFILE</envar></primary>
2049+
</indexterm>
2050+
<envar>PGPASSWORDFILE</envar>
2051+
sets the password file used if the backend demands password authentication.
2052+
This file should have the format
2053+
<screen>
2054+
<replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
2055+
</screen>
2056+
Any of these may be a literal name, or a <literal>*</literal> that matches
2057+
anything. The first match will be the one used, so put more specific entries first.
2058+
Entries with <literal>:</literal> or <literal>\</literal> should be escaped
2059+
with <literal>\</literal>.
20442060
</para>
20452061
</listitem>
20462062
<listitem>

src/interfaces/libpq/fe-connect.c

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.190 2002/07/20 05:43:31 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.191 2002/08/15 02:56:19 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -182,6 +182,9 @@ static char *conninfo_getval(PQconninfoOption *connOptions,
182182
static void defaultNoticeProcessor(void *arg, const char *message);
183183
static int parseServiceInfo(PQconninfoOption *options,
184184
PQExpBuffer errorMessage);
185+
char *pwdfMatchesString(char *buf, char *token);
186+
char *PasswordFromFile(char *hostname, char *port, char *dbname,
187+
char *username, char *pwdfile);
185188

186189
/*
187190
* Connecting to a Database
@@ -388,6 +391,10 @@ PQconndefaults(void)
388391
*
389392
* PGPASSWORD The user's password.
390393
*
394+
* PGPASSWORDFILE
395+
* A file that contains host:port:database:user:password
396+
* for authentication
397+
*
391398
* PGDATABASE name of database to which to connect if <pgdatabase>
392399
* argument is NULL or a null string
393400
*
@@ -476,13 +483,6 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
476483
libpq_gettext("could not determine the PostgreSQL user name to use\n"));
477484
}
478485

479-
if (pwd)
480-
conn->pgpass = strdup(pwd);
481-
else if ((tmp = getenv("PGPASSWORD")) != NULL)
482-
conn->pgpass = strdup(tmp);
483-
else
484-
conn->pgpass = strdup(DefaultPassword);
485-
486486
if (dbName == NULL)
487487
{
488488
if ((tmp = getenv("PGDATABASE")) != NULL)
@@ -493,6 +493,17 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
493493
else
494494
conn->dbName = strdup(dbName);
495495

496+
/* getPasswordFromFile mallocs its result, so we don't need strdup here */
497+
if (pwd)
498+
conn->pgpass = strdup(pwd);
499+
else if ((tmp = getenv("PGPASSWORD")) != NULL)
500+
conn->pgpass = strdup(tmp);
501+
else if ((tmp = PasswordFromFile(conn->pghost, conn->pgport,
502+
conn->dbName, conn->pguser,
503+
getenv("PGPASSWORDFILE"))) != NULL)
504+
conn->pgpass = tmp;
505+
else
506+
conn->pgpass = strdup(DefaultPassword);
496507

497508
#ifdef USE_SSL
498509
if ((tmp = getenv("PGREQUIRESSL")) != NULL)
@@ -2810,3 +2821,92 @@ defaultNoticeProcessor(void *arg, const char *message)
28102821
/* Note: we expect the supplied string to end with a newline already. */
28112822
fprintf(stderr, "%s", message);
28122823
}
2824+
2825+
/* returns a pointer to the next token or NULL if the current
2826+
* token doesn't match */
2827+
char *
2828+
pwdfMatchesString(char *buf, char *token)
2829+
{
2830+
char *tbuf,
2831+
*ttok;
2832+
bool bslash = false;
2833+
if (buf == NULL || token == NULL)
2834+
return NULL;
2835+
tbuf = buf;
2836+
ttok = token;
2837+
if (*tbuf == '*')
2838+
return tbuf + 2;
2839+
while (*tbuf != 0)
2840+
{
2841+
if (*tbuf == '\\' && !bslash)
2842+
{
2843+
tbuf++;
2844+
bslash = true;
2845+
}
2846+
if (*tbuf == ':' && *ttok == 0 && !bslash)
2847+
return tbuf+1;
2848+
bslash = false;
2849+
if (*ttok == 0)
2850+
return NULL;
2851+
if (*tbuf == *ttok)
2852+
{
2853+
tbuf++;
2854+
ttok++;
2855+
}
2856+
else
2857+
return NULL;
2858+
}
2859+
return NULL;
2860+
}
2861+
2862+
/* get a password from the password file. */
2863+
char *
2864+
PasswordFromFile(char *hostname, char *port, char *dbname,
2865+
char *username, char *pwdfile)
2866+
{
2867+
FILE *fp;
2868+
#define LINELEN NAMEDATALEN*5
2869+
char buf[LINELEN];
2870+
2871+
if (pwdfile == NULL || strcmp(pwdfile, "") == 0)
2872+
return NULL;
2873+
2874+
if (dbname == NULL || strcmp(dbname, "") == 0)
2875+
return NULL;
2876+
2877+
if (username == NULL || strcmp(username, "") == 0)
2878+
return NULL;
2879+
2880+
if (hostname == NULL)
2881+
hostname = DefaultHost;
2882+
2883+
if (port == NULL)
2884+
port = DEF_PGPORT_STR;
2885+
2886+
fp = fopen(pwdfile, "r");
2887+
if (fp == NULL)
2888+
return NULL;
2889+
2890+
while (!feof(fp)) {
2891+
char *t = buf,
2892+
*ret;
2893+
fgets(buf, LINELEN - 1, fp);
2894+
if (strlen(buf) == 0)
2895+
continue;
2896+
2897+
buf[strlen(buf) - 1] = 0;
2898+
if ((t = pwdfMatchesString(t, hostname)) == NULL ||
2899+
(t = pwdfMatchesString(t, port)) == NULL ||
2900+
(t = pwdfMatchesString(t, dbname)) == NULL ||
2901+
(t = pwdfMatchesString(t, username)) == NULL)
2902+
continue;
2903+
ret=(char *)malloc(sizeof(char)*strlen(t));
2904+
strncpy(ret, t, strlen(t));
2905+
fclose(fp);
2906+
return ret;
2907+
}
2908+
fclose(fp);
2909+
return NULL;
2910+
2911+
#undef LINELEN
2912+
}

src/interfaces/perl5/Pg.pm

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#-------------------------------------------------------
22
#
3-
# $Id: Pg.pm,v 1.10 2001/09/10 04:19:19 momjian Exp $
3+
# $Id: Pg.pm,v 1.11 2002/08/15 02:56:19 momjian Exp $
44
#
55
# Copyright (c) 1997, 1998 Edmund Mergl
66
#
@@ -260,15 +260,16 @@ When opening a connection a given database name is always converted to
260260
lower-case, unless it is surrounded by double quotes. All unspecified
261261
parameters are replaced by environment variables or by hard coded defaults:
262262
263-
parameter environment variable hard coded default
264-
--------------------------------------------------
265-
host PGHOST localhost
266-
port PGPORT 5432
267-
options PGOPTIONS ""
268-
tty PGTTY ""
269-
dbname PGDATABASE current userid
270-
user PGUSER current userid
271-
password PGPASSWORD ""
263+
parameter environment variable hard coded default
264+
------------------------------------------------------
265+
host PGHOST localhost
266+
port PGPORT 5432
267+
options PGOPTIONS ""
268+
tty PGTTY ""
269+
dbname PGDATABASE current userid
270+
user PGUSER current userid
271+
password PGPASSWORD ""
272+
passwordfile PGPASSWORDFILE ""
272273
273274
Using appropriate methods you can access almost all fields of the
274275
returned PGconn structure.

0 commit comments

Comments
 (0)