Get rid of client-code dependencies on the exact text of the no-password

error message, by using PQconnectionUsedPassword() instead.  Someday
we might be able to localize that error message, but not until this
coding technique has disappeared everywhere.
This commit is contained in:
Tom Lane 2007-07-08 19:07:38 +00:00
parent 5f7b1f8d9d
commit 8331c11f3f
6 changed files with 58 additions and 69 deletions

View File

@ -4,7 +4,7 @@
*
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.81 2007/07/02 21:58:31 mha Exp $
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.82 2007/07/08 19:07:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -480,15 +480,18 @@ test_postmaster_connection(bool do_checkpoint)
if (!*portstr)
snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
/* We need to set a connect timeout otherwise on Windows the SCM will probably timeout first */
snprintf(connstr, sizeof(connstr), "dbname=postgres port=%s connect_timeout=5", portstr);
/*
* We need to set a connect timeout otherwise on Windows the SCM will
* probably timeout first
*/
snprintf(connstr, sizeof(connstr),
"dbname=postgres port=%s connect_timeout=5", portstr);
for (i = 0; i < wait_seconds; i++)
{
if ((conn = PQconnectdb(connstr)) != NULL &&
(PQstatus(conn) == CONNECTION_OK ||
(strcmp(PQerrorMessage(conn),
PQnoPasswordSupplied) == 0)))
PQconnectionUsedPassword(conn)))
{
PQfinish(conn);
success = true;

View File

@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.75 2006/10/04 00:30:05 momjian Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.76 2007/07/08 19:07:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -123,13 +123,11 @@ ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
static PGconn *
_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
{
int need_pass;
PGconn *newConn;
char *password = NULL;
int badPwd = 0;
int noPwd = 0;
char *newdb;
char *newuser;
char *password = NULL;
bool new_pass;
if (!reqdb)
newdb = PQdb(AH->connection);
@ -152,7 +150,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
do
{
need_pass = false;
new_pass = false;
newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
NULL, NULL, newdb,
newuser, password);
@ -161,30 +159,23 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
if (PQstatus(newConn) == CONNECTION_BAD)
{
noPwd = (strcmp(PQerrorMessage(newConn),
PQnoPasswordSupplied) == 0);
badPwd = (strncmp(PQerrorMessage(newConn),
"Password authentication failed for user", 39) == 0);
if (noPwd || badPwd)
{
if (badPwd)
fprintf(stderr, "Password incorrect\n");
fprintf(stderr, "Connecting to %s as %s\n",
newdb, newuser);
need_pass = true;
if (password)
free(password);
password = simple_prompt("Password: ", 100, false);
}
else
if (!PQconnectionUsedPassword(newConn))
die_horribly(AH, modulename, "could not reconnect to database: %s",
PQerrorMessage(newConn));
PQfinish(newConn);
if (password)
fprintf(stderr, "Password incorrect\n");
fprintf(stderr, "Connecting to %s as %s\n",
newdb, newuser);
if (password)
free(password);
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
} while (need_pass);
} while (new_pass);
if (password)
free(password);
@ -214,7 +205,7 @@ ConnectDatabase(Archive *AHX,
{
ArchiveHandle *AH = (ArchiveHandle *) AHX;
char *password = NULL;
bool need_pass = false;
bool new_pass;
if (AH->connection)
die_horribly(AH, modulename, "already connected to a database\n");
@ -235,7 +226,7 @@ ConnectDatabase(Archive *AHX,
*/
do
{
need_pass = false;
new_pass = false;
AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL,
dbname, username, password);
@ -243,16 +234,15 @@ ConnectDatabase(Archive *AHX,
die_horribly(AH, modulename, "failed to connect to database\n");
if (PQstatus(AH->connection) == CONNECTION_BAD &&
strcmp(PQerrorMessage(AH->connection), PQnoPasswordSupplied) == 0 &&
PQconnectionUsedPassword(AH->connection) &&
password == NULL &&
!feof(stdin))
{
PQfinish(AH->connection);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
} while (need_pass);
} while (new_pass);
if (password)
free(password);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.91 2007/05/15 20:20:21 alvherre Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.92 2007/07/08 19:07:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1310,7 +1310,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
const char *pguser, bool require_password, bool fail_on_error)
{
PGconn *conn;
bool need_pass = false;
bool new_pass;
const char *remoteversion_str;
int my_version;
static char *password = NULL;
@ -1324,7 +1324,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/
do
{
need_pass = false;
new_pass = false;
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn)
@ -1335,17 +1335,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
}
if (PQstatus(conn) == CONNECTION_BAD &&
strcmp(PQerrorMessage(conn), PQnoPasswordSupplied) == 0 &&
PQconnectionUsedPassword(conn) &&
password == NULL &&
!feof(stdin))
{
PQfinish(conn);
need_pass = true;
if (password)
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
} while (need_pass);
} while (new_pass);
/* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD)

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.179 2007/03/03 17:19:11 momjian Exp $
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.180 2007/07/08 19:07:38 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@ -1110,11 +1110,11 @@ do_connect(char *dbname, char *user, char *host, char *port)
* If the user asked to be prompted for a password, ask for one now. If
* not, use the password from the old connection, provided the username
* has not changed. Otherwise, try to connect without a password first,
* and then ask for a password if we got the appropriate error message.
* and then ask for a password if needed.
*
* XXX: this behavior is broken. It leads to spurious connection attempts
* in the postmaster's log, and doing a string comparison against the
* returned error message is pretty fragile.
* XXX: this behavior leads to spurious connection attempts recorded
* in the postmaster's log. But libpq offers no API that would let us
* obtain a password and then continue with the first connection attempt.
*/
if (pset.getPassword)
{
@ -1141,7 +1141,7 @@ do_connect(char *dbname, char *user, char *host, char *port)
* Connection attempt failed; either retry the connection attempt with
* a new password, or give up.
*/
if (strcmp(PQerrorMessage(n_conn), PQnoPasswordSupplied) == 0)
if (!password && PQconnectionUsedPassword(n_conn))
{
PQfinish(n_conn);
password = prompt_for_password(user);

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.140 2007/02/01 19:10:29 momjian Exp $
* $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.141 2007/07/08 19:07:38 tgl Exp $
*/
#include "postgres_fe.h"
@ -108,7 +108,7 @@ main(int argc, char *argv[])
char *username = NULL;
char *password = NULL;
char *password_prompt = NULL;
bool need_pass;
bool new_pass;
set_pglocale_pgservice(argv[0], "psql");
@ -204,23 +204,22 @@ main(int argc, char *argv[])
/* loop until we have a password if requested by backend */
do
{
need_pass = false;
new_pass = false;
pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL,
options.action == ACT_LIST_DB && options.dbname == NULL ?
"postgres" : options.dbname,
username, password);
if (PQstatus(pset.db) == CONNECTION_BAD &&
strcmp(PQerrorMessage(pset.db), PQnoPasswordSupplied) == 0 &&
PQconnectionUsedPassword(pset.db) &&
password == NULL &&
!feof(stdin))
{
PQfinish(pset.db);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt(password_prompt, 100, false);
new_pass = true;
}
} while (need_pass);
} while (new_pass);
free(username);
free(password);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.26 2007/04/09 18:21:22 mha Exp $
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.27 2007/07/08 19:07:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -100,7 +100,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
{
PGconn *conn;
char *password = NULL;
bool need_pass = false;
bool new_pass;
if (require_password)
password = simple_prompt("Password: ", 100, false);
@ -111,7 +111,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/
do
{
need_pass = false;
new_pass = false;
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn)
@ -122,16 +122,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
}
if (PQstatus(conn) == CONNECTION_BAD &&
strcmp(PQerrorMessage(conn), PQnoPasswordSupplied) == 0 &&
PQconnectionUsedPassword(conn) &&
password == NULL &&
!feof(stdin))
{
PQfinish(conn);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
} while (need_pass);
} while (new_pass);
if (password)
free(password);