Skip to content

Commit 99389cb

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 5f81a48 commit 99389cb

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
@@ -2022,12 +2022,29 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
20222022

20232023
if (active_branch)
20242024
{
2025-
char *opt0 = psql_scan_slash_option(scan_state,
2025+
char *user = psql_scan_slash_option(scan_state,
20262026
OT_SQLID, NULL, true);
20272027
char *pw1;
20282028
char *pw2;
2029+
PQExpBufferData buf;
2030+
2031+
if (user == NULL)
2032+
{
2033+
/* By default, the command applies to CURRENT_USER */
2034+
PGresult *res;
2035+
2036+
res = PSQLexec("SELECT CURRENT_USER");
2037+
if (!res)
2038+
return PSQL_CMD_ERROR;
2039+
2040+
user = pg_strdup(PQgetvalue(res, 0, 0));
2041+
PQclear(res);
2042+
}
20292043

2030-
pw1 = simple_prompt("Enter new password: ", false);
2044+
initPQExpBuffer(&buf);
2045+
printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
2046+
2047+
pw1 = simple_prompt(buf.data, false);
20312048
pw2 = simple_prompt("Enter it again: ", false);
20322049

20332050
if (strcmp(pw1, pw2) != 0)
@@ -2037,14 +2054,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
20372054
}
20382055
else
20392056
{
2040-
char *user;
20412057
char *encrypted_password;
20422058

2043-
if (opt0)
2044-
user = opt0;
2045-
else
2046-
user = PQuser(pset.db);
2047-
20482059
encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
20492060

20502061
if (!encrypted_password)
@@ -2054,15 +2065,12 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
20542065
}
20552066
else
20562067
{
2057-
PQExpBufferData buf;
20582068
PGresult *res;
20592069

2060-
initPQExpBuffer(&buf);
20612070
printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
20622071
fmtId(user));
20632072
appendStringLiteralConn(&buf, encrypted_password, pset.db);
20642073
res = PSQLexec(buf.data);
2065-
termPQExpBuffer(&buf);
20662074
if (!res)
20672075
success = false;
20682076
else
@@ -2071,10 +2079,10 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
20712079
}
20722080
}
20732081

2074-
if (opt0)
2075-
free(opt0);
2082+
free(user);
20762083
free(pw1);
20772084
free(pw2);
2085+
termPQExpBuffer(&buf);
20782086
}
20792087
else
20802088
ignore_slash_options(scan_state);

0 commit comments

Comments
 (0)