OSDN Git Service

Get rid of client-code dependencies on the exact text of the no-password
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 8 Jul 2007 19:07:38 +0000 (19:07 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 8 Jul 2007 19:07:38 +0000 (19:07 +0000)
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.

src/bin/pg_ctl/pg_ctl.c
src/bin/pg_dump/pg_backup_db.c
src/bin/pg_dump/pg_dumpall.c
src/bin/psql/command.c
src/bin/psql/startup.c
src/bin/scripts/common.c

index 4cfc394..970fb39 100644 (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;
index aeb3498..5f8039e 100644 (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);
index a888348..f4eb74e 100644 (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)
index 8f103f1..936c56b 100644 (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);
index f8b9744..65c2e1d 100644 (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);
index dfe9a52..6903fa6 100644 (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);