Remove the -P options of oid2name and pgbench, as they are security
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 11 Dec 2007 02:31:49 +0000 (02:31 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 11 Dec 2007 02:31:49 +0000 (02:31 +0000)
hazards.  Instead teach these programs to prompt for a password when
necessary, just like all our other programs.
I did not bother to invent -W switches for them, since the return on
investment seems so low.

contrib/oid2name/oid2name.c
contrib/pgbench/pgbench.c
doc/src/sgml/oid2name.sgml
doc/src/sgml/pgbench.sgml

index 357797988756f2242b7078956d14d69373cd1ff0..86c2ead377279e92802598030dc0bae33f4db471 100644 (file)
@@ -4,7 +4,8 @@
  *
  * Originally by
  * B. Palmer, bpalmer@crimelabs.net 1-17-2001
- * $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.32 2007/07/25 22:16:17 tgl Exp $
+ *
+ * $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.33 2007/12/11 02:31:49 tgl Exp $
  */
 #include "postgres_fe.h"
 
@@ -43,7 +44,6 @@ struct options
        char       *hostname;
        char       *port;
        char       *username;
-       char       *password;
 };
 
 /* function prototypes */
@@ -76,10 +76,9 @@ get_opts(int argc, char **argv, struct options * my_opts)
        my_opts->hostname = NULL;
        my_opts->port = NULL;
        my_opts->username = NULL;
-       my_opts->password = NULL;
 
        /* get opts */
-       while ((c = getopt(argc, argv, "H:p:U:P:d:t:o:f:qSxish?")) != -1)
+       while ((c = getopt(argc, argv, "H:p:U:d:t:o:f:qSxish?")) != -1)
        {
                switch (c)
                {
@@ -123,11 +122,6 @@ get_opts(int argc, char **argv, struct options * my_opts)
                                my_opts->username = mystrdup(optarg);
                                break;
 
-                               /* password */
-                       case 'P':
-                               my_opts->password = mystrdup(optarg);
-                               break;
-
                                /* display system tables */
                        case 'S':
                                my_opts->systables = true;
@@ -166,8 +160,6 @@ get_opts(int argc, char **argv, struct options * my_opts)
                                         "        -H host               connect to remote host\n"
                                        "        -p port               host port to connect to\n"
                                   "        -U username           username to connect with\n"
-                                         "        -P password           password for username\n"
-                                               "                              (see also $PGPASSWORD and ~/.pgpass)\n"
                                        );
                                exit(1);
                                break;
@@ -275,22 +267,49 @@ PGconn *
 sql_conn(struct options * my_opts)
 {
        PGconn     *conn;
+       char       *password = NULL;
+       bool            new_pass;
 
-       /* login */
-       conn = PQsetdbLogin(my_opts->hostname,
-                                               my_opts->port,
-                                               NULL,   /* options */
-                                               NULL,   /* tty */
-                                               my_opts->dbname,
-                                               my_opts->username,
-                                               my_opts->password);
-
-       /* deal with errors */
-       if (PQstatus(conn) != CONNECTION_OK)
+       /*
+        * Start the connection.  Loop until we have a password if requested by
+        * backend.
+        */
+       do
        {
-               fprintf(stderr, "%s: connection to database '%s' failed.\n", "oid2name", my_opts->dbname);
-               fprintf(stderr, "%s", PQerrorMessage(conn));
+               new_pass = false;
+               conn = PQsetdbLogin(my_opts->hostname,
+                                                       my_opts->port,
+                                                       NULL,   /* options */
+                                                       NULL,   /* tty */
+                                                       my_opts->dbname,
+                                                       my_opts->username,
+                                                       password);
+               if (!conn)
+               {
+                       fprintf(stderr, "%s: could not connect to database %s\n",
+                                       "oid2name", my_opts->dbname);
+                       exit(1);
+               }
+
+               if (PQstatus(conn) == CONNECTION_BAD &&
+                       PQconnectionNeedsPassword(conn) &&
+                       password == NULL &&
+                       !feof(stdin))
+               {
+                       PQfinish(conn);
+                       password = simple_prompt("Password: ", 100, false);
+                       new_pass = true;
+               }
+       } while (new_pass);
+
+       if (password)
+               free(password);
 
+       /* check to see that the backend connection was successfully made */
+       if (PQstatus(conn) == CONNECTION_BAD)
+       {
+               fprintf(stderr, "%s: could not connect to database %s: %s",
+                               "oid2name", my_opts->dbname, PQerrorMessage(conn));
                PQfinish(conn);
                exit(1);
        }
index 5fe48b96a3d642fcadd0de6bc0dd1400c73f2d75..ce35bd3dff57a1fae98731550b6787c1c01356bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.74 2007/11/15 21:14:31 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.75 2007/12/11 02:31:49 tgl Exp $
  *
  * pgbench: a simple benchmark program for PostgreSQL
  * written by Tatsuo Ishii
@@ -94,7 +94,6 @@ char     *pgport = "";
 char      *pgoptions = NULL;
 char      *pgtty = NULL;
 char      *login = NULL;
-char      *pwd = NULL;
 char      *dbName;
 
 /* variable definitions */
@@ -188,8 +187,8 @@ static char *select_only = {
 static void
 usage(void)
 {
-       fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-D varname=value][-n][-C][-v][-S][-N][-f filename][-l][-U login][-P password][-d][dbname]\n");
-       fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor] [-F fillfactor] [-U login][-P password][-d][dbname]\n");
+       fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-D varname=value][-n][-C][-v][-S][-N][-f filename][-l][-U login][-d][dbname]\n");
+       fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor] [-F fillfactor] [-U login][-d][dbname]\n");
 }
 
 /* random number generator */
@@ -218,32 +217,50 @@ executeStatement(PGconn *con, const char *sql)
 static PGconn *
 doConnect(void)
 {
-       PGconn     *con;
+       PGconn     *conn;
+       static char *password = NULL;
+       bool            new_pass;
 
-       con = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
-                                          login, pwd);
-       if (con == NULL)
+       /*
+        * Start the connection.  Loop until we have a password if requested by
+        * backend.
+        */
+       do
        {
-               fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
-               fprintf(stderr, "Memory allocatin problem?\n");
-               return (NULL);
-       }
+               new_pass = false;
 
-       if (PQstatus(con) == CONNECTION_BAD)
-       {
-               fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+               conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
+                                                       login, password);
+               if (!conn)
+               {
+                       fprintf(stderr, "Connection to database \"%s\" failed\n",
+                                       dbName);
+                       return NULL;
+               }
 
-               if (PQerrorMessage(con))
-                       fprintf(stderr, "%s", PQerrorMessage(con));
-               else
-                       fprintf(stderr, "No explanation from the backend\n");
+               if (PQstatus(conn) == CONNECTION_BAD &&
+                       PQconnectionNeedsPassword(conn) &&
+                       password == NULL &&
+                       !feof(stdin))
+               {
+                       PQfinish(conn);
+                       password = simple_prompt("Password: ", 100, false);
+                       new_pass = true;
+               }
+       } while (new_pass);
 
-               return (NULL);
+       /* check to see that the backend connection was successfully made */
+       if (PQstatus(conn) == CONNECTION_BAD)
+       {
+               fprintf(stderr, "Connection to database \"%s\" failed:\n%s",
+                               dbName, PQerrorMessage(conn));
+               PQfinish(conn);
+               return NULL;
        }
 
-       executeStatement(con, "SET search_path = public");
+       executeStatement(conn, "SET search_path = public");
 
-       return (con);
+       return conn;
 }
 
 /* throw away response from backend */
@@ -1258,7 +1275,7 @@ main(int argc, char **argv)
 
        memset(state, 0, sizeof(*state));
 
-       while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSlf:D:F:")) != -1)
+       while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:CNSlf:D:F:")) != -1)
        {
                switch (c)
                {
@@ -1333,9 +1350,6 @@ main(int argc, char **argv)
                        case 'U':
                                login = optarg;
                                break;
-                       case 'P':
-                               pwd = optarg;
-                               break;
                        case 'l':
                                use_log = true;
                                break;
index eb91827c7bf0c2d85899dc9e49be81f8c9dd399c..d2ab3f4c2261debb3310f634d8d895acfedf3daa 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/oid2name.sgml,v 1.3 2007/12/10 05:32:51 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/oid2name.sgml,v 1.4 2007/12/11 02:31:49 tgl Exp $ -->
 
 <sect1 id="oid2name">
  <title>oid2name</title>
       <entry><literal>-U</literal> <replaceable>username</></entry>
       <entry>username to connect as</entry>
      </row>
-
-     <row>
-      <entry><literal>-P</literal> <replaceable>password</></entry>
-      <entry>password (deprecated &mdash; putting this on the command line
-       is a security hazard)</entry>
-     </row>
     </tbody>
    </tgroup>
   </table>
index be089f8836da6f71ef91ca0d83e828e19f111267..61d159e6d8d4c50c4938b487a6483359904cb847 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.4 2007/12/10 05:32:51 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbench.sgml,v 1.5 2007/12/11 02:31:49 tgl Exp $ -->
 
 <sect1 id="pgbench">
  <title>pgbench</title>
@@ -282,11 +282,6 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
       <entry><literal>-U</literal> <replaceable>login</></entry>
       <entry>username to connect as</entry>
      </row>
-     <row>
-      <entry><literal>-P</literal> <replaceable>password</></entry>
-      <entry>password (deprecated &mdash; putting this on the command line
-       is a security hazard)</entry>
-     </row>
     </tbody>
    </tgroup>
   </table>