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,13 +153,16 @@ GetConnection(void) ...@@ -150,13 +153,16 @@ 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); PQfinish(tmpconn);
continue; need_password = true;
}
else
break;
} }
if (PQstatus(tmpconn) != CONNECTION_OK) if (PQstatus(tmpconn) != CONNECTION_OK)
...@@ -178,8 +184,8 @@ GetConnection(void) ...@@ -178,8 +184,8 @@ GetConnection(void)
PQconninfoFree(conn_opts); PQconninfoFree(conn_opts);
/* /*
* Ensure we have the same value of integer timestamps as the server * Ensure we have the same value of integer timestamps as the server we
* we are connecting to. * are connecting to.
*/ */
tmpparam = PQparameterStatus(tmpconn, "integer_datetimes"); tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
if (!tmpparam) if (!tmpparam)
...@@ -204,9 +210,5 @@ GetConnection(void) ...@@ -204,9 +210,5 @@ GetConnection(void)
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