Hello psql-hackers!
We thought it would be advantageous to be able to specify a 'custom'
pgpassfile within the connection string along the lines of the existing
parameters sslkey and sslcert.
Which is exactly what this very compact patch does.
The patch is minimally invasive - when no pgpassfile attribute is
provided in the connection string, the regular pgpassfile is used.
The security-measures (which are limited to checking the permissions for
0600) are kept, however we could loosen that restriciton to allow group
access as well along the lines of the ssl key file , if this is
preferred. (in case multiple users belonging to the same group would
like to connect using the same file).
The patch applies cleanly to master and compiles and runs as expected
(as there are no critical alterations).
I've not written any documentation as of now, but I'll follow up closely
if there is any interest for this patch.
notes:
- using ~ to denote the user's home directory in the path does not
work, however $HOME works (as this is translated by bash beforehand).
- the notation in the custom pgpassfile should follow the notation of
the 'default' pgpass files:
hostname:port:database:username:password
- this has only been tested on linux so far, however due to the nature
of the changes I suspect that there is nothing that could go wrong in
other environments, although I could test that as well, if deemed necessary.
I'm looking forward to any feedback,
Julian
--
Julian Markwort
Westphalian Wilhelms-University in Münster
julian.markw...@uni-muenster.de
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 9b2839b..5c0d88a 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -184,6 +184,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"Database-Password", "*", 20,
offsetof(struct pg_conn, pgpass)},
+ {"pgpassfile", "PGPASSFILE", NULL, NULL,
+ "Database-Password-File", "", 64,
+ offsetof(struct pg_conn, pgpassfile)},
+
{"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
"Connect-timeout", "", 10, /* strlen(INT32_MAX) == 10 */
offsetof(struct pg_conn, connect_timeout)},
@@ -375,7 +379,7 @@ static int parseServiceFile(const char *serviceFile,
bool *group_found);
static char *pwdfMatchesString(char *buf, char *token);
static char *PasswordFromFile(char *hostname, char *port, char *dbname,
- char *username);
+ char *username, char *pgpassfile);
static bool getPgPassFilename(char *pgpassfile);
static void dot_pg_pass_warning(PGconn *conn);
static void default_threadlock(int acquire);
@@ -806,8 +810,9 @@ connectOptions2(PGconn *conn)
{
if (conn->pgpass)
free(conn->pgpass);
+ /* We'll pass conn->pgpassfile regardless of it's contents - checks happen in PasswordFromFile() */
conn->pgpass = PasswordFromFile(conn->pghost, conn->pgport,
- conn->dbName, conn->pguser);
+ conn->dbName, conn->pguser, conn->pgpassfile);
if (conn->pgpass == NULL)
{
conn->pgpass = strdup(DefaultPassword);
@@ -5699,14 +5704,15 @@ pwdfMatchesString(char *buf, char *token)
return NULL;
}
-/* Get a password from the password file. Return value is malloc'd. */
+/* Get a password from the password file or the user-specified pgpassfile. Return value is malloc'd. */
static char *
-PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
+PasswordFromFile(char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
{
FILE *fp;
- char pgpassfile[MAXPGPATH];
+ char temp_path[MAXPGPATH];
struct stat stat_buf;
+
#define LINELEN NAMEDATALEN*5
char buf[LINELEN];
@@ -5731,8 +5737,13 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
if (port == NULL)
port = DEF_PGPORT_STR;
- if (!getPgPassFilename(pgpassfile))
- return NULL;
+ if(!pgpassfile || pgpassfile[0]=='\0')
+ {
+ /* If no pgpassfile was supplied by the user or it is empty, we try to get a global pgpassfile */
+ if (!getPgPassFilename(temp_path))
+ return NULL;
+ pgpassfile = temp_path;
+ }
/* If password file cannot be opened, ignore it. */
if (stat(pgpassfile, &stat_buf) != 0)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 1183323..ae9317f 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -317,6 +317,7 @@ struct pg_conn
char *replication; /* connect as the replication standby? */
char *pguser; /* Postgres username and password, if any */
char *pgpass;
+ char *pgpassfile; /* path to a file containing the password */
char *keepalives; /* use TCP keepalives? */
char *keepalives_idle; /* time between TCP keepalives */
char *keepalives_interval; /* time between TCP keepalive
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers