aboutsummaryrefslogtreecommitdiff
path: root/src/bin/scripts/common.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-12-23 15:45:43 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2015-12-23 15:45:43 -0500
commitff402ae11b4d33e0e46c2730f63033d3631b8010 (patch)
tree0d5613733254659db835e97d8f0cd6a0df2e3f71 /src/bin/scripts/common.c
parent1aa41e3eae3746e05d0e23286ac740a9a6cee7df (diff)
downloadpostgresql-ff402ae11b4d33e0e46c2730f63033d3631b8010.tar.gz
postgresql-ff402ae11b4d33e0e46c2730f63033d3631b8010.zip
Improve handling of password reuse in src/bin/scripts programs.
This reverts most of commit 83dec5a71 in favor of having connectDatabase() store the possibly-reusable password in a static variable, similar to the coding we've had for a long time in pg_dump's version of that function. To avoid possible problems with unwanted password reuse, make callers specify whether it's reasonable to attempt to re-use the password. This is a wash for cases where re-use isn't needed, but it is far simpler for callers that do want that. Functionally there should be no difference. Even though we're past RC1, it seems like a good idea to back-patch this into 9.5, like the prior commit. Otherwise, if there are any third-party users of connectDatabase(), they'll have to deal with an API change in 9.5 and then another one in 9.6. Michael Paquier
Diffstat (limited to 'src/bin/scripts/common.c')
-rw-r--r--src/bin/scripts/common.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index d26a4edbb68..362e748b9a7 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -54,22 +54,31 @@ handle_help_version_opts(int argc, char *argv[],
/*
* Make a database connection with the given parameters.
*
- * A password can be given, but if not (or if user forces us to) we prompt
- * interactively for one, unless caller prohibited us from doing so.
+ * An interactive password prompt is automatically issued if needed and
+ * allowed by prompt_password.
+ *
+ * If allow_password_reuse is true, we will try to re-use any password
+ * given during previous calls to this routine. (Callers should not pass
+ * allow_password_reuse=true unless reconnecting to the same database+user
+ * as before, else we might create password exposure hazards.)
*/
PGconn *
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
- const char *pguser, const char *pgpassword,
- enum trivalue prompt_password, const char *progname,
- bool fail_ok)
+ const char *pguser, enum trivalue prompt_password,
+ const char *progname, bool fail_ok, bool allow_password_reuse)
{
PGconn *conn;
- char *password;
+ static char *password = NULL;
bool new_pass;
- password = pgpassword ? strdup(pgpassword) : NULL;
+ if (!allow_password_reuse)
+ {
+ if (password)
+ free(password);
+ password = NULL;
+ }
- if (prompt_password == TRI_YES && !pgpassword)
+ if (password == NULL && prompt_password == TRI_YES)
password = simple_prompt("Password: ", 100, false);
/*
@@ -78,9 +87,8 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/
do
{
-#define PARAMS_ARRAY_SIZE 7
- const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
- const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+ const char *keywords[7];
+ const char *values[7];
keywords[0] = "host";
values[0] = pghost;
@@ -107,9 +115,6 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
exit(1);
}
- pg_free(keywords);
- pg_free(values);
-
/*
* No luck? Trying asking (again) for a password.
*/
@@ -125,9 +130,6 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
}
} while (new_pass);
- if (password)
- free(password);
-
/* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD)
{
@@ -157,15 +159,15 @@ connectMaintenanceDatabase(const char *maintenance_db, const char *pghost,
/* If a maintenance database name was specified, just connect to it. */
if (maintenance_db)
- return connectDatabase(maintenance_db, pghost, pgport, pguser, NULL,
- prompt_password, progname, false);
+ return connectDatabase(maintenance_db, pghost, pgport, pguser,
+ prompt_password, progname, false, false);
/* Otherwise, try postgres first and then template1. */
- conn = connectDatabase("postgres", pghost, pgport, pguser, NULL,
- prompt_password, progname, true);
+ conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
+ progname, true, false);
if (!conn)
- conn = connectDatabase("template1", pghost, pgport, pguser, NULL,
- prompt_password, progname, false);
+ conn = connectDatabase("template1", pghost, pgport, pguser,
+ prompt_password, progname, false, false);
return conn;
}