diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 4e34f00..1bd5597 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -930,7 +930,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname Note that authentication is likely to fail if host is not the name of the server at network address hostaddr. Also, note that host rather than hostaddr - is used to identify the connection in ~/.pgpass (see + is used to identify the connection in a password file (see ). @@ -986,6 +986,16 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname + + pgpassfile + + + Specifies the name of the file used to lookup passwords. + Defaults to the password file (see ). + + + + connect_timeout @@ -6862,9 +6872,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) PGPASSFILE - PGPASSFILE specifies the name of the password file to - use for lookups. If not set, it defaults to ~/.pgpass - (see ). + PGPASSFILE behaves the same as the connection parameter. @@ -7136,13 +7145,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - The file .pgpass in a user's home directory or the - file referenced by PGPASSFILE can contain passwords to + The file .pgpass in a user's home directory can contain passwords to be used if the connection requires a password (and no password has been specified otherwise). On Microsoft Windows the file is named %APPDATA%\postgresql\pgpass.conf (where %APPDATA% refers to the Application Data subdirectory in the user's profile). + Alternatively, a password file can be specified + using the connection parameter + or the environment variable PGPASSFILE. diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index f3a9e5a..db1de26 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); @@ -5703,12 +5708,12 @@ 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 @@ -5735,8 +5740,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) @@ -5858,11 +5868,14 @@ dot_pg_pass_warning(PGconn *conn) { char pgpassfile[MAXPGPATH]; - if (!getPgPassFilename(pgpassfile)) - return; + /* If no pgpassfile was specified with the connection, we try to get the default one */ + if (!conn->pgpassfile){ + if(!getPgPassFilename(pgpassfile)) + return; + } appendPQExpBuffer(&conn->errorMessage, libpq_gettext("password retrieved from file \"%s\"\n"), - pgpassfile); + (conn->pgpassfile)?(conn->pgpassfile):pgpassfile); } } diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 7007692..9f5c2f9 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