Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3f59a05

Browse filesBrowse files
committed
Fix recently-introduced breakage in psql's \connect command.
Through my misreading of what the existing code actually did, commits 85c5428 et al. broke psql's behavior for the case where "\c connstring" provides a password in the connstring. We should use that password in such a case, but as of 85c5428 we ignored it (and instead, prompted for a password). Commit 94929f1 fixed that in HEAD, but since I thought it was cleaning up a longstanding misbehavior and not one I'd just created, I didn't back-patch it. Hence, back-patch the portions of 94929f1 having to do with password management. In addition to fixing the introduced bug, this means that "\c -reuse-previous=on connstring" will allow re-use of an existing connection's password if the connstring doesn't change user/host/port. That didn't happen before, but it seems like a bug fix, and anyway I'm loath to have significant differences in this code across versions. Also fix an error with the same root cause about whether or not to override a connstring's setting of client_encoding. As of 85c5428 we always did so; restore the previous behavior of overriding only when stdin/stdout are a terminal and there's no environment setting of PGCLIENTENCODING. (I find that definition a bit surprising, but right now doesn't seem like the time to revisit it.) Per bug #16746 from Krzysztof Gradek. As with the previous patch, back-patch to all supported branches. Discussion: https://postgr.es/m/16746-44b30e2edf4335d4@postgresql.org
1 parent 7fbd144 commit 3f59a05
Copy full SHA for 3f59a05

File tree

Expand file treeCollapse file tree

2 files changed

+51
-17
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+51
-17
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Copy file name to clipboardExpand all lines: doc/src/sgml/ref/psql-ref.sgml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,8 @@ testdb=>
870870
is changed from its previous value using the positional syntax,
871871
any <replaceable>hostaddr</replaceable> setting present in the
872872
existing connection's parameters is dropped.
873+
Also, any password used for the existing connection will be re-used
874+
only if the user, host, and port settings are not changed.
873875
When the command neither specifies nor reuses a particular parameter,
874876
the <application>libpq</application> default is used.
875877
</para>

‎src/bin/psql/command.c

Copy file name to clipboardExpand all lines: src/bin/psql/command.c
+49-17Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,7 @@ do_connect(enum trivalue reuse_previous_specification,
17971797
int nconnopts = 0;
17981798
bool same_host = false;
17991799
char *password = NULL;
1800+
char *client_encoding;
18001801
bool success = true;
18011802
bool keep_password = true;
18021803
bool has_connection_string;
@@ -1867,6 +1868,7 @@ do_connect(enum trivalue reuse_previous_specification,
18671868
{
18681869
PQconninfoOption *ci;
18691870
PQconninfoOption *replci;
1871+
bool have_password = false;
18701872

18711873
for (ci = cinfo, replci = replcinfo;
18721874
ci->keyword && replci->keyword;
@@ -1885,6 +1887,26 @@ do_connect(enum trivalue reuse_previous_specification,
18851887

18861888
replci->val = ci->val;
18871889
ci->val = swap;
1890+
1891+
/*
1892+
* Check whether connstring provides options affecting
1893+
* password re-use. While any change in user, host,
1894+
* hostaddr, or port causes us to ignore the old
1895+
* connection's password, we don't force that for
1896+
* dbname, since passwords aren't database-specific.
1897+
*/
1898+
if (replci->val == NULL ||
1899+
strcmp(ci->val, replci->val) != 0)
1900+
{
1901+
if (strcmp(replci->keyword, "user") == 0 ||
1902+
strcmp(replci->keyword, "host") == 0 ||
1903+
strcmp(replci->keyword, "hostaddr") == 0 ||
1904+
strcmp(replci->keyword, "port") == 0)
1905+
keep_password = false;
1906+
}
1907+
/* Also note whether connstring contains a password. */
1908+
if (strcmp(replci->keyword, "password") == 0)
1909+
have_password = true;
18881910
}
18891911
}
18901912
Assert(ci->keyword == NULL && replci->keyword == NULL);
@@ -1894,8 +1916,13 @@ do_connect(enum trivalue reuse_previous_specification,
18941916

18951917
PQconninfoFree(replcinfo);
18961918

1897-
/* We never re-use a password with a conninfo string. */
1898-
keep_password = false;
1919+
/*
1920+
* If the connstring contains a password, tell the loop below
1921+
* that we may use it, regardless of other settings (i.e.,
1922+
* cinfo's password is no longer an "old" password).
1923+
*/
1924+
if (have_password)
1925+
keep_password = true;
18991926

19001927
/* Don't let code below try to inject dbname into params. */
19011928
dbname = NULL;
@@ -1976,14 +2003,16 @@ do_connect(enum trivalue reuse_previous_specification,
19762003
{
19772004
password = prompt_for_password(user);
19782005
}
1979-
else if (o_conn && keep_password)
1980-
{
1981-
password = PQpass(o_conn);
1982-
if (password && *password)
1983-
password = pg_strdup(password);
1984-
else
1985-
password = NULL;
1986-
}
2006+
2007+
/*
2008+
* Consider whether to force client_encoding to "auto" (overriding
2009+
* anything in the connection string). We do so if we have a terminal
2010+
* connection and there is no PGCLIENTENCODING environment setting.
2011+
*/
2012+
if (pset.notty || getenv("PGCLIENTENCODING"))
2013+
client_encoding = NULL;
2014+
else
2015+
client_encoding = "auto";
19872016

19882017
/* Loop till we have a connection or fail, which we might've already */
19892018
while (success)
@@ -1995,12 +2024,12 @@ do_connect(enum trivalue reuse_previous_specification,
19952024

19962025
/*
19972026
* Copy non-default settings into the PQconnectdbParams parameter
1998-
* arrays; but override any values specified old-style, as well as the
1999-
* password and a couple of fields we want to set forcibly.
2027+
* arrays; but inject any values specified old-style, as well as any
2028+
* interactively-obtained password, and a couple of fields we want to
2029+
* set forcibly.
20002030
*
20012031
* If you change this code, see also the initial-connection code in
2002-
* main(). For no good reason, a connection string password= takes
2003-
* precedence in main() but not here.
2032+
* main().
20042033
*/
20052034
for (ci = cinfo; ci->keyword; ci++)
20062035
{
@@ -2019,12 +2048,15 @@ do_connect(enum trivalue reuse_previous_specification,
20192048
}
20202049
else if (port && strcmp(ci->keyword, "port") == 0)
20212050
values[paramnum++] = port;
2022-
else if (strcmp(ci->keyword, "password") == 0)
2051+
/* If !keep_password, we unconditionally drop old password */
2052+
else if ((password || !keep_password) &&
2053+
strcmp(ci->keyword, "password") == 0)
20232054
values[paramnum++] = password;
20242055
else if (strcmp(ci->keyword, "fallback_application_name") == 0)
20252056
values[paramnum++] = pset.progname;
2026-
else if (strcmp(ci->keyword, "client_encoding") == 0)
2027-
values[paramnum++] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
2057+
else if (client_encoding &&
2058+
strcmp(ci->keyword, "client_encoding") == 0)
2059+
values[paramnum++] = client_encoding;
20282060
else if (ci->val)
20292061
values[paramnum++] = ci->val;
20302062
/* else, don't bother making libpq parse this keyword */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.