]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make psql's \password default to CURRENT_USER, not PQuser(conn).
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 12 Nov 2021 19:55:32 +0000 (14:55 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 12 Nov 2021 19:55:32 +0000 (14:55 -0500)
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

src/bin/psql/command.c

index f22c0ee49c06c3e4bc7788baaa7d0264e72e4ff1..65509ee747c868a9d061e94f361514f8e060b464 100644 (file)
@@ -1789,12 +1789,29 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
 
        if (active_branch)
        {
-               char       *opt0 = psql_scan_slash_option(scan_state,
+               char       *user = psql_scan_slash_option(scan_state,
                                                                                                  OT_SQLID, NULL, true);
                char            pw1[100];
                char            pw2[100];
+               PQExpBufferData buf;
+
+               if (user == NULL)
+               {
+                       /* By default, the command applies to CURRENT_USER */
+                       PGresult   *res;
+
+                       res = PSQLexec("SELECT CURRENT_USER");
+                       if (!res)
+                               return PSQL_CMD_ERROR;
+
+                       user = pg_strdup(PQgetvalue(res, 0, 0));
+                       PQclear(res);
+               }
 
-               simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
+               initPQExpBuffer(&buf);
+               printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
+
+               simple_prompt(buf.data, pw1, sizeof(pw1), false);
                simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
 
                if (strcmp(pw1, pw2) != 0)
@@ -1804,14 +1821,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
                }
                else
                {
-                       char       *user;
                        char       *encrypted_password;
 
-                       if (opt0)
-                               user = opt0;
-                       else
-                               user = PQuser(pset.db);
-
                        encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
 
                        if (!encrypted_password)
@@ -1821,15 +1832,12 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
                        }
                        else
                        {
-                               PQExpBufferData buf;
                                PGresult   *res;
 
-                               initPQExpBuffer(&buf);
                                printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
                                                                  fmtId(user));
                                appendStringLiteralConn(&buf, encrypted_password, pset.db);
                                res = PSQLexec(buf.data);
-                               termPQExpBuffer(&buf);
                                if (!res)
                                        success = false;
                                else
@@ -1838,8 +1846,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch)
                        }
                }
 
-               if (opt0)
-                       free(opt0);
+               free(user);
+               termPQExpBuffer(&buf);
        }
        else
                ignore_slash_options(scan_state);