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 4cfc3941d9c494fdaacd1ab432227fb249ea0faa..970fb391398638a7d4273f0f2ca34db6f236d03b 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 aeb34989e8a78f820f283b1c7a2087d30da78f17..5f8039e98271fcb83f69459d75815929ddb5c74e 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 a8883484276bd7f038431ccf83bf90e900d7977d..f4eb74ec34d37d7c3be262f435e2b0a2cc8844b3 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 8f103f1c2133700f03546c83732a3e6f766389c6..936c56b20316c38e0bfcb00acf78a20f6faf08ea 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 f8b9744273e6ae53a677baa4c95b09f636fa0cf0..65c2e1d906d2f7761660afa3280525ce90a98e0e 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 dfe9a52be43103203d73480d112f3e5ba954e817..6903fa6e033262992c393bab5e25d566739046bf 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);