diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-11-12 18:05:23 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-11-12 18:05:23 -0300 |
commit | 83dec5a712af251af15effbf781ddaedc3bf6b3b (patch) | |
tree | 5d16c6f8dc40bd37a086f1d76deffd4ca80b758d /src/bin/scripts/common.c | |
parent | fe702a7b3f9f2bc5bf6d173166d7d55226af82c8 (diff) | |
download | postgresql-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.c | 39 |
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; |