Commit 3172eea0 authored by Tom Lane's avatar Tom Lane

Clean up password prompting logic in streamutil.c.

The previous coding was fairly unreadable and drew double-free warnings
from clang.  I believe the double free was actually not reachable, because
PQconnectionNeedsPassword is coded to not return true if a password was
provided, so that the loop can't iterate more than twice.  Nonetheless
it seems worth rewriting.  No back-patch since this is just cosmetic.
parent f3b3b8d5
...@@ -40,8 +40,8 @@ GetConnection(void) ...@@ -40,8 +40,8 @@ GetConnection(void)
int i; int i;
const char **keywords; const char **keywords;
const char **values; const char **values;
char *password = NULL;
const char *tmpparam; const char *tmpparam;
bool need_password;
PQconninfoOption *conn_opts = NULL; PQconninfoOption *conn_opts = NULL;
PQconninfoOption *conn_opt; PQconninfoOption *conn_opt;
char *err_msg = NULL; char *err_msg = NULL;
...@@ -114,27 +114,30 @@ GetConnection(void) ...@@ -114,27 +114,30 @@ GetConnection(void)
i++; i++;
} }
/* If -W was given, force prompt for password, but only the first time */
need_password = (dbgetpassword == 1 && dbpassword == NULL);
while (true) while (true)
{ {
if (password) /* Get a new password if appropriate */
free(password); if (need_password)
{
if (dbpassword)
free(dbpassword);
dbpassword = simple_prompt(_("Password: "), 100, false);
need_password = false;
}
/* Use (or reuse, on a subsequent connection) password if we have it */
if (dbpassword) if (dbpassword)
{ {
/*
* We've saved a password when a previous connection succeeded,
* meaning this is the call for a second session to the same
* database, so just forcibly reuse that password.
*/
keywords[i] = "password"; keywords[i] = "password";
values[i] = dbpassword; values[i] = dbpassword;
dbgetpassword = -1; /* Don't try again if this fails */
} }
else if (dbgetpassword == 1) else
{ {
password = simple_prompt(_("Password: "), 100, false); keywords[i] = NULL;
keywords[i] = "password"; values[i] = NULL;
values[i] = password;
} }
tmpconn = PQconnectdbParams(keywords, values, true); tmpconn = PQconnectdbParams(keywords, values, true);
...@@ -150,63 +153,62 @@ GetConnection(void) ...@@ -150,63 +153,62 @@ GetConnection(void)
exit(1); exit(1);
} }
/* If we need a password and -w wasn't given, loop back and get one */
if (PQstatus(tmpconn) == CONNECTION_BAD && if (PQstatus(tmpconn) == CONNECTION_BAD &&
PQconnectionNeedsPassword(tmpconn) && PQconnectionNeedsPassword(tmpconn) &&
dbgetpassword != -1) dbgetpassword != -1)
{ {
dbgetpassword = 1; /* ask for password next time */
PQfinish(tmpconn);
continue;
}
if (PQstatus(tmpconn) != CONNECTION_OK)
{
fprintf(stderr, _("%s: could not connect to server: %s\n"),
progname, PQerrorMessage(tmpconn));
PQfinish(tmpconn); PQfinish(tmpconn);
free(values); need_password = true;
free(keywords);
if (conn_opts)
PQconninfoFree(conn_opts);
return NULL;
} }
else
break;
}
/* Connection ok! */ if (PQstatus(tmpconn) != CONNECTION_OK)
{
fprintf(stderr, _("%s: could not connect to server: %s\n"),
progname, PQerrorMessage(tmpconn));
PQfinish(tmpconn);
free(values); free(values);
free(keywords); free(keywords);
if (conn_opts) if (conn_opts)
PQconninfoFree(conn_opts); PQconninfoFree(conn_opts);
return NULL;
}
/* /* Connection ok! */
* Ensure we have the same value of integer timestamps as the server free(values);
* we are connecting to. free(keywords);
*/ if (conn_opts)
tmpparam = PQparameterStatus(tmpconn, "integer_datetimes"); PQconninfoFree(conn_opts);
if (!tmpparam)
{ /*
fprintf(stderr, * Ensure we have the same value of integer timestamps as the server we
_("%s: could not determine server setting for integer_datetimes\n"), * are connecting to.
progname); */
PQfinish(tmpconn); tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
exit(1); if (!tmpparam)
} {
fprintf(stderr,
_("%s: could not determine server setting for integer_datetimes\n"),
progname);
PQfinish(tmpconn);
exit(1);
}
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
if (strcmp(tmpparam, "on") != 0) if (strcmp(tmpparam, "on") != 0)
#else #else
if (strcmp(tmpparam, "off") != 0) if (strcmp(tmpparam, "off") != 0)
#endif #endif
{ {
fprintf(stderr, fprintf(stderr,
_("%s: integer_datetimes compile flag does not match server\n"), _("%s: integer_datetimes compile flag does not match server\n"),
progname); progname);
PQfinish(tmpconn); PQfinish(tmpconn);
exit(1); exit(1);
}
/* Store the password for next run */
if (password)
dbpassword = password;
return tmpconn;
} }
return tmpconn;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment