Commit 8331c11f authored by Tom Lane's avatar Tom Lane

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.
parent 5f7b1f8d
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * 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) ...@@ -480,15 +480,18 @@ test_postmaster_connection(bool do_checkpoint)
if (!*portstr) if (!*portstr)
snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT); 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++) for (i = 0; i < wait_seconds; i++)
{ {
if ((conn = PQconnectdb(connstr)) != NULL && if ((conn = PQconnectdb(connstr)) != NULL &&
(PQstatus(conn) == CONNECTION_OK || (PQstatus(conn) == CONNECTION_OK ||
(strcmp(PQerrorMessage(conn), PQconnectionUsedPassword(conn)))
PQnoPasswordSupplied) == 0)))
{ {
PQfinish(conn); PQfinish(conn);
success = true; success = true;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver. * Implements the basic DB functions used by the archiver.
* *
* IDENTIFICATION * 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) ...@@ -123,13 +123,11 @@ ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
static PGconn * static PGconn *
_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
{ {
int need_pass;
PGconn *newConn; PGconn *newConn;
char *password = NULL;
int badPwd = 0;
int noPwd = 0;
char *newdb; char *newdb;
char *newuser; char *newuser;
char *password = NULL;
bool new_pass;
if (!reqdb) if (!reqdb)
newdb = PQdb(AH->connection); newdb = PQdb(AH->connection);
...@@ -152,7 +150,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -152,7 +150,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
do do
{ {
need_pass = false; new_pass = false;
newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection), newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
NULL, NULL, newdb, NULL, NULL, newdb,
newuser, password); newuser, password);
...@@ -161,30 +159,23 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -161,30 +159,23 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
if (PQstatus(newConn) == CONNECTION_BAD) if (PQstatus(newConn) == CONNECTION_BAD)
{ {
noPwd = (strcmp(PQerrorMessage(newConn), if (!PQconnectionUsedPassword(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
die_horribly(AH, modulename, "could not reconnect to database: %s", die_horribly(AH, modulename, "could not reconnect to database: %s",
PQerrorMessage(newConn)); PQerrorMessage(newConn));
PQfinish(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) if (password)
free(password); free(password);
...@@ -214,7 +205,7 @@ ConnectDatabase(Archive *AHX, ...@@ -214,7 +205,7 @@ ConnectDatabase(Archive *AHX,
{ {
ArchiveHandle *AH = (ArchiveHandle *) AHX; ArchiveHandle *AH = (ArchiveHandle *) AHX;
char *password = NULL; char *password = NULL;
bool need_pass = false; bool new_pass;
if (AH->connection) if (AH->connection)
die_horribly(AH, modulename, "already connected to a database\n"); die_horribly(AH, modulename, "already connected to a database\n");
...@@ -235,7 +226,7 @@ ConnectDatabase(Archive *AHX, ...@@ -235,7 +226,7 @@ ConnectDatabase(Archive *AHX,
*/ */
do do
{ {
need_pass = false; new_pass = false;
AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL, AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL,
dbname, username, password); dbname, username, password);
...@@ -243,16 +234,15 @@ ConnectDatabase(Archive *AHX, ...@@ -243,16 +234,15 @@ ConnectDatabase(Archive *AHX,
die_horribly(AH, modulename, "failed to connect to database\n"); die_horribly(AH, modulename, "failed to connect to database\n");
if (PQstatus(AH->connection) == CONNECTION_BAD && if (PQstatus(AH->connection) == CONNECTION_BAD &&
strcmp(PQerrorMessage(AH->connection), PQnoPasswordSupplied) == 0 && PQconnectionUsedPassword(AH->connection) &&
password == NULL &&
!feof(stdin)) !feof(stdin))
{ {
PQfinish(AH->connection); PQfinish(AH->connection);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
new_pass = true;
} }
} while (need_pass); } while (new_pass);
if (password) if (password)
free(password); free(password);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -1310,7 +1310,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
const char *pguser, bool require_password, bool fail_on_error) const char *pguser, bool require_password, bool fail_on_error)
{ {
PGconn *conn; PGconn *conn;
bool need_pass = false; bool new_pass;
const char *remoteversion_str; const char *remoteversion_str;
int my_version; int my_version;
static char *password = NULL; static char *password = NULL;
...@@ -1324,7 +1324,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, ...@@ -1324,7 +1324,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/ */
do do
{ {
need_pass = false; new_pass = false;
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password); conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn) if (!conn)
...@@ -1335,17 +1335,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, ...@@ -1335,17 +1335,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
} }
if (PQstatus(conn) == CONNECTION_BAD && if (PQstatus(conn) == CONNECTION_BAD &&
strcmp(PQerrorMessage(conn), PQnoPasswordSupplied) == 0 && PQconnectionUsedPassword(conn) &&
password == NULL &&
!feof(stdin)) !feof(stdin))
{ {
PQfinish(conn); PQfinish(conn);
need_pass = true;
if (password)
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false); 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 */ /* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD) if (PQstatus(conn) == CONNECTION_BAD)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2007, PostgreSQL Global Development Group * 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 "postgres_fe.h"
#include "command.h" #include "command.h"
...@@ -1110,11 +1110,11 @@ do_connect(char *dbname, char *user, char *host, char *port) ...@@ -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 * 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 * not, use the password from the old connection, provided the username
* has not changed. Otherwise, try to connect without a password first, * 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 * XXX: this behavior leads to spurious connection attempts recorded
* in the postmaster's log, and doing a string comparison against the * in the postmaster's log. But libpq offers no API that would let us
* returned error message is pretty fragile. * obtain a password and then continue with the first connection attempt.
*/ */
if (pset.getPassword) if (pset.getPassword)
{ {
...@@ -1141,7 +1141,7 @@ do_connect(char *dbname, char *user, char *host, char *port) ...@@ -1141,7 +1141,7 @@ do_connect(char *dbname, char *user, char *host, char *port)
* Connection attempt failed; either retry the connection attempt with * Connection attempt failed; either retry the connection attempt with
* a new password, or give up. * a new password, or give up.
*/ */
if (strcmp(PQerrorMessage(n_conn), PQnoPasswordSupplied) == 0) if (!password && PQconnectionUsedPassword(n_conn))
{ {
PQfinish(n_conn); PQfinish(n_conn);
password = prompt_for_password(user); password = prompt_for_password(user);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2007, PostgreSQL Global Development Group * 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" #include "postgres_fe.h"
...@@ -108,7 +108,7 @@ main(int argc, char *argv[]) ...@@ -108,7 +108,7 @@ main(int argc, char *argv[])
char *username = NULL; char *username = NULL;
char *password = NULL; char *password = NULL;
char *password_prompt = NULL; char *password_prompt = NULL;
bool need_pass; bool new_pass;
set_pglocale_pgservice(argv[0], "psql"); set_pglocale_pgservice(argv[0], "psql");
...@@ -204,23 +204,22 @@ main(int argc, char *argv[]) ...@@ -204,23 +204,22 @@ main(int argc, char *argv[])
/* loop until we have a password if requested by backend */ /* loop until we have a password if requested by backend */
do do
{ {
need_pass = false; new_pass = false;
pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL, pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL,
options.action == ACT_LIST_DB && options.dbname == NULL ? options.action == ACT_LIST_DB && options.dbname == NULL ?
"postgres" : options.dbname, "postgres" : options.dbname,
username, password); username, password);
if (PQstatus(pset.db) == CONNECTION_BAD && if (PQstatus(pset.db) == CONNECTION_BAD &&
strcmp(PQerrorMessage(pset.db), PQnoPasswordSupplied) == 0 && PQconnectionUsedPassword(pset.db) &&
password == NULL &&
!feof(stdin)) !feof(stdin))
{ {
PQfinish(pset.db); PQfinish(pset.db);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt(password_prompt, 100, false); password = simple_prompt(password_prompt, 100, false);
new_pass = true;
} }
} while (need_pass); } while (new_pass);
free(username); free(username);
free(password); free(password);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -100,7 +100,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
{ {
PGconn *conn; PGconn *conn;
char *password = NULL; char *password = NULL;
bool need_pass = false; bool new_pass;
if (require_password) if (require_password)
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
...@@ -111,7 +111,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, ...@@ -111,7 +111,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/ */
do do
{ {
need_pass = false; new_pass = false;
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password); conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn) if (!conn)
...@@ -122,16 +122,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, ...@@ -122,16 +122,15 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
} }
if (PQstatus(conn) == CONNECTION_BAD && if (PQstatus(conn) == CONNECTION_BAD &&
strcmp(PQerrorMessage(conn), PQnoPasswordSupplied) == 0 && PQconnectionUsedPassword(conn) &&
password == NULL &&
!feof(stdin)) !feof(stdin))
{ {
PQfinish(conn); PQfinish(conn);
need_pass = true;
free(password);
password = NULL;
password = simple_prompt("Password: ", 100, false); password = simple_prompt("Password: ", 100, false);
new_pass = true;
} }
} while (need_pass); } while (new_pass);
if (password) if (password)
free(password); free(password);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment