aboutsummaryrefslogtreecommitdiff
path: root/src/bin/scripts/common.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2015-11-12 18:05:23 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2015-11-12 18:05:23 -0300
commit83dec5a712af251af15effbf781ddaedc3bf6b3b (patch)
tree5d16c6f8dc40bd37a086f1d76deffd4ca80b758d /src/bin/scripts/common.c
parentfe702a7b3f9f2bc5bf6d173166d7d55226af82c8 (diff)
downloadpostgresql-83dec5a712af251af15effbf781ddaedc3bf6b3b.tar.gz
postgresql-83dec5a712af251af15effbf781ddaedc3bf6b3b.zip
vacuumdb: don't prompt for passwords over and over
Having the script prompt for passwords over and over was a preexisting problem when it processed multiple databases or when it processed multiple analyze stages, but the parallel mode introduced in commit a179232047 made it worse. Fix the annoyance by keeping a copy of the password used by the first connection that requires one. Since users can (currently) only have a single password, there's no need for more complex arrangements (such as remembering one password per database). Per bug #13741 reported by Eric Brown. Patch authored and cross-reviewed by Haribabu Kommi and Michael Paquier, slightly tweaked by Álvaro Herrera. Discussion: http://www.postgresql.org/message-id/20151027193919.931.54948@wrigleys.postgresql.org Backpatch to 9.5, where parallel vacuumdb was introduced.
Diffstat (limited to 'src/bin/scripts/common.c')
-rw-r--r--src/bin/scripts/common.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index 0deadec0975..d26a4edbb68 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -52,19 +52,24 @@ handle_help_version_opts(int argc, char *argv[],
/*
- * Make a database connection with the given parameters. An
- * interactive password prompt is automatically issued if required.
+ * 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.
*/
PGconn *
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
- const char *pguser, enum trivalue prompt_password,
- const char *progname, bool fail_ok)
+ const char *pguser, const char *pgpassword,
+ enum trivalue prompt_password, const char *progname,
+ bool fail_ok)
{
PGconn *conn;
- char *password = NULL;
+ char *password;
bool new_pass;
- if (prompt_password == TRI_YES)
+ password = pgpassword ? strdup(pgpassword) : NULL;
+
+ if (prompt_password == TRI_YES && !pgpassword)
password = simple_prompt("Password: ", 100, false);
/*
@@ -95,22 +100,26 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
new_pass = false;
conn = PQconnectdbParams(keywords, values, true);
- free(keywords);
- free(values);
-
if (!conn)
{
- fprintf(stderr, _("%s: could not connect to database %s\n"),
+ fprintf(stderr, _("%s: could not connect to database %s: out of memory\n"),
progname, dbname);
exit(1);
}
+ pg_free(keywords);
+ pg_free(values);
+
+ /*
+ * No luck? Trying asking (again) for a password.
+ */
if (PQstatus(conn) == CONNECTION_BAD &&
PQconnectionNeedsPassword(conn) &&
- password == NULL &&
prompt_password != TRI_NO)
{
PQfinish(conn);
+ if (password)
+ free(password);
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
@@ -148,14 +157,14 @@ 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,
+ return connectDatabase(maintenance_db, pghost, pgport, pguser, NULL,
prompt_password, progname, false);
/* Otherwise, try postgres first and then template1. */
- conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
- progname, true);
+ conn = connectDatabase("postgres", pghost, pgport, pguser, NULL,
+ prompt_password, progname, true);
if (!conn)
- conn = connectDatabase("template1", pghost, pgport, pguser,
+ conn = connectDatabase("template1", pghost, pgport, pguser, NULL,
prompt_password, progname, false);
return conn;