Skip to content

Commit 843925f

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 a691a22 commit 843925f

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

19641964
if (active_branch)
19651965
{
1966-
char *opt0 = psql_scan_slash_option(scan_state,
1966+
char *user = psql_scan_slash_option(scan_state,
19671967
OT_SQLID, NULL, true);
19681968
char pw1[100];
19691969
char pw2[100];
1970+
PQExpBufferData buf;
1971+
1972+
if (user == NULL)
1973+
{
1974+
/* By default, the command applies to CURRENT_USER */
1975+
PGresult *res;
1976+
1977+
res = PSQLexec("SELECT CURRENT_USER");
1978+
if (!res)
1979+
return PSQL_CMD_ERROR;
1980+
1981+
user = pg_strdup(PQgetvalue(res, 0, 0));
1982+
PQclear(res);
1983+
}
19701984

1971-
simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
1985+
initPQExpBuffer(&buf);
1986+
printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
1987+
1988+
simple_prompt(buf.data, pw1, sizeof(pw1), false);
19721989
simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
19731990

19741991
if (strcmp(pw1, pw2) != 0)
@@ -1978,14 +1995,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
19781995
}
19791996
else
19801997
{
1981-
char *user;
19821998
char *encrypted_password;
19831999

1984-
if (opt0)
1985-
user = opt0;
1986-
else
1987-
user = PQuser(pset.db);
1988-
19892000
encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
19902001

19912002
if (!encrypted_password)
@@ -1995,15 +2006,12 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
19952006
}
19962007
else
19972008
{
1998-
PQExpBufferData buf;
19992009
PGresult *res;
20002010

2001-
initPQExpBuffer(&buf);
20022011
printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
20032012
fmtId(user));
20042013
appendStringLiteralConn(&buf, encrypted_password, pset.db);
20052014
res = PSQLexec(buf.data);
2006-
termPQExpBuffer(&buf);
20072015
if (!res)
20082016
success = false;
20092017
else
@@ -2012,8 +2020,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
20122020
}
20132021
}
20142022

2015-
if (opt0)
2016-
free(opt0);
2023+
free(user);
2024+
termPQExpBuffer(&buf);
20172025
}
20182026
else
20192027
ignore_slash_options(scan_state);

0 commit comments

Comments
 (0)