Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit15be274

Browse files
committed
Avoid misleading psql password prompt when username is multiply specified.
When a password is needed, cases such aspsql -d "postgresql://alice@localhost/testdb" -U bobwould incorrectly prompt for "Password for user bob: ", when actually theconnection will be attempted with username alice. The priority order ofwhich name to use isn't that important here, but the misleading prompt is.When we are prompting for a password after initial connection failure,we can fix this reliably by looking at PQuser(conn) to see how libpqinterpreted the connection arguments. But when we're doing a forcedpassword prompt because of a -W switch, we can't use that solution.Fortunately, because the main use of -W is for noninteractive situations,it's less critical to produce a helpful prompt in such cases. I madethe startup prompt for -W just say "Password: " all the time, ratherthan expending extra code on trying to identify which username to use.In the case of a \c command (after -W has been given), there's alreadylogic in do_connect that determines whether the "dbname" is a connstringor URI, so we can avoid lobotomizing the prompt except in cases thatare actually dubious. (We could do similarly in startup.c if anyonecomplains, but for now it seems not worthwhile, especially since thatwould still be only a partial solution.)Per bug #15025 from Akos Vandra. Although this is arguably a bug fix,it doesn't seem worth back-patching. The case where it matters seemslike a very corner-case usage, and someone might complain that we'dchanged the behavior of -W in a minor release.Discussion:https://postgr.es/m/20180123130013.7407.24749@wrigleys.postgresql.org
1 parent35a5280 commit15be274

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

‎src/bin/psql/command.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,7 +2829,7 @@ prompt_for_password(const char *username)
28292829
{
28302830
charbuf[100];
28312831

2832-
if (username==NULL)
2832+
if (username==NULL||username[0]=='\0')
28332833
simple_prompt("Password: ",buf,sizeof(buf), false);
28342834
else
28352835
{
@@ -2960,7 +2960,14 @@ do_connect(enum trivalue reuse_previous_specification,
29602960
*/
29612961
if (pset.getPassword==TRI_YES)
29622962
{
2963-
password=prompt_for_password(user);
2963+
/*
2964+
* If a connstring or URI is provided, we can't be sure we know which
2965+
* username will be used, since we haven't parsed that argument yet.
2966+
* Don't risk issuing a misleading prompt. As in startup.c, it does
2967+
* not seem worth working harder, since this getPassword option is
2968+
* normally only used in noninteractive cases.
2969+
*/
2970+
password=prompt_for_password(has_connection_string ?NULL :user);
29642971
}
29652972
elseif (o_conn&&keep_password)
29662973
{
@@ -3026,8 +3033,12 @@ do_connect(enum trivalue reuse_previous_specification,
30263033
*/
30273034
if (!password&&PQconnectionNeedsPassword(n_conn)&&pset.getPassword!=TRI_NO)
30283035
{
3036+
/*
3037+
* Prompt for password using the username we actually connected
3038+
* with --- it might've come out of "dbname" rather than "user".
3039+
*/
3040+
password=prompt_for_password(PQuser(n_conn));
30293041
PQfinish(n_conn);
3030-
password=prompt_for_password(user);
30313042
continue;
30323043
}
30333044

‎src/bin/psql/startup.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ main(int argc, char *argv[])
101101
intsuccessResult;
102102
boolhave_password= false;
103103
charpassword[100];
104-
char*password_prompt=NULL;
105104
boolnew_pass;
106105

107106
set_pglocale_pgservice(argv[0],PG_TEXTDOMAIN("psql"));
@@ -205,15 +204,14 @@ main(int argc, char *argv[])
205204
pset.popt.topt.recordSep.separator_zero= false;
206205
}
207206

208-
if (options.username==NULL)
209-
password_prompt=pg_strdup(_("Password: "));
210-
else
211-
password_prompt=psprintf(_("Password for user %s: "),
212-
options.username);
213-
214207
if (pset.getPassword==TRI_YES)
215208
{
216-
simple_prompt(password_prompt,password,sizeof(password), false);
209+
/*
210+
* We can't be sure yet of the username that will be used, so don't
211+
* offer a potentially wrong one. Typical uses of this option are
212+
* noninteractive anyway.
213+
*/
214+
simple_prompt("Password: ",password,sizeof(password), false);
217215
have_password= true;
218216
}
219217

@@ -252,15 +250,28 @@ main(int argc, char *argv[])
252250
!have_password&&
253251
pset.getPassword!=TRI_NO)
254252
{
253+
/*
254+
* Before closing the old PGconn, extract the user name that was
255+
* actually connected with --- it might've come out of a URI or
256+
* connstring "database name" rather than options.username.
257+
*/
258+
constchar*realusername=PQuser(pset.db);
259+
char*password_prompt;
260+
261+
if (realusername&&realusername[0])
262+
password_prompt=psprintf(_("Password for user %s: "),
263+
realusername);
264+
else
265+
password_prompt=pg_strdup(_("Password: "));
255266
PQfinish(pset.db);
267+
256268
simple_prompt(password_prompt,password,sizeof(password), false);
269+
free(password_prompt);
257270
have_password= true;
258271
new_pass= true;
259272
}
260273
}while (new_pass);
261274

262-
free(password_prompt);
263-
264275
if (PQstatus(pset.db)==CONNECTION_BAD)
265276
{
266277
fprintf(stderr,"%s: %s",pset.progname,PQerrorMessage(pset.db));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp