Skip to content

Commit b062ca5

Browse files
committed
Make psql's \password default to CURRENT_USER, not PQuser(conn).
The documentation says plainly that \password acts on "the current user" by default. What it actually acted on, or tried to, was the username used to log into the current session. This is not the same thing if one has since done SET ROLE or SET SESSION AUTHENTICATION. Aside from the possible surprise factor, it's quite likely that the current role doesn't have permissions to set the password of the original role. To fix, use "SELECT CURRENT_USER" to get the role name to act on. (This syntax works with servers at least back to 7.0.) Also, in hopes of reducing confusion, include the role name that will be acted on in the password prompt. The discrepancy from the documentation makes this a bug, so back-patch to all supported branches. Patch by me; thanks to Nathan Bossart for review. Discussion: https://postgr.es/m/747443.1635536754@sss.pgh.pa.us
1 parent cae393f commit b062ca5

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

src/bin/psql/command.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,12 +1789,29 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
17891789

17901790
if (active_branch)
17911791
{
1792-
char *opt0 = psql_scan_slash_option(scan_state,
1792+
char *user = psql_scan_slash_option(scan_state,
17931793
OT_SQLID, NULL, true);
17941794
char pw1[100];
17951795
char pw2[100];
1796+
PQExpBufferData buf;
1797+
1798+
if (user == NULL)
1799+
{
1800+
/* By default, the command applies to CURRENT_USER */
1801+
PGresult *res;
1802+
1803+
res = PSQLexec("SELECT CURRENT_USER");
1804+
if (!res)
1805+
return PSQL_CMD_ERROR;
1806+
1807+
user = pg_strdup(PQgetvalue(res, 0, 0));
1808+
PQclear(res);
1809+
}
17961810

1797-
simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
1811+
initPQExpBuffer(&buf);
1812+
printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
1813+
1814+
simple_prompt(buf.data, pw1, sizeof(pw1), false);
17981815
simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
17991816

18001817
if (strcmp(pw1, pw2) != 0)
@@ -1804,14 +1821,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
18041821
}
18051822
else
18061823
{
1807-
char *user;
18081824
char *encrypted_password;
18091825

1810-
if (opt0)
1811-
user = opt0;
1812-
else
1813-
user = PQuser(pset.db);
1814-
18151826
encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
18161827

18171828
if (!encrypted_password)
@@ -1821,15 +1832,12 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
18211832
}
18221833
else
18231834
{
1824-
PQExpBufferData buf;
18251835
PGresult *res;
18261836

1827-
initPQExpBuffer(&buf);
18281837
printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
18291838
fmtId(user));
18301839
appendStringLiteralConn(&buf, encrypted_password, pset.db);
18311840
res = PSQLexec(buf.data);
1832-
termPQExpBuffer(&buf);
18331841
if (!res)
18341842
success = false;
18351843
else
@@ -1838,8 +1846,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
18381846
}
18391847
}
18401848

1841-
if (opt0)
1842-
free(opt0);
1849+
free(user);
1850+
termPQExpBuffer(&buf);
18431851
}
18441852
else
18451853
ignore_slash_options(scan_state);

0 commit comments

Comments
 (0)