8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.389 2010/03/03 20:31:09 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.390 2010/03/13 14:55:57 momjian Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -91,6 +91,9 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
91
91
*/
92
92
#define ERRCODE_APPNAME_UNKNOWN "42704"
93
93
94
+ /* This is part of the protocol so just define it */
95
+ #define ERRCODE_INVALID_PASSWORD "28P01"
96
+
94
97
/*
95
98
* fall back options if they are not specified by arguments or defined
96
99
* by environment variables
@@ -284,6 +287,8 @@ static int parseServiceFile(const char *serviceFile,
284
287
static char * pwdfMatchesString (char * buf , char * token );
285
288
static char * PasswordFromFile (char * hostname , char * port , char * dbname ,
286
289
char * username );
290
+ static bool getPgPassFilename (char * pgpassfile );
291
+ static void dot_pg_pass_warning (PGconn * conn );
287
292
static void default_threadlock (int acquire );
288
293
289
294
@@ -652,6 +657,8 @@ connectOptions2(PGconn *conn)
652
657
conn -> dbName , conn -> pguser );
653
658
if (conn -> pgpass == NULL )
654
659
conn -> pgpass = strdup (DefaultPassword );
660
+ else
661
+ conn -> dot_pgpass_used = true;
655
662
}
656
663
657
664
/*
@@ -2133,6 +2140,8 @@ PQconnectPoll(PGconn *conn)
2133
2140
2134
2141
error_return :
2135
2142
2143
+ dot_pg_pass_warning (conn );
2144
+
2136
2145
/*
2137
2146
* We used to close the socket at this point, but that makes it awkward
2138
2147
* for those above us if they wish to remove this socket from their own
@@ -2191,6 +2200,7 @@ makeEmptyPGconn(void)
2191
2200
conn -> verbosity = PQERRORS_DEFAULT ;
2192
2201
conn -> sock = -1 ;
2193
2202
conn -> password_needed = false;
2203
+ conn -> dot_pgpass_used = false;
2194
2204
#ifdef USE_SSL
2195
2205
conn -> allow_ssl_try = true;
2196
2206
conn -> wait_ssl_try = false;
@@ -4323,7 +4333,6 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
4323
4333
FILE * fp ;
4324
4334
char pgpassfile [MAXPGPATH ];
4325
4335
struct stat stat_buf ;
4326
- char * passfile_env ;
4327
4336
4328
4337
#define LINELEN NAMEDATALEN*5
4329
4338
char buf [LINELEN ];
@@ -4349,17 +4358,8 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
4349
4358
if (port == NULL )
4350
4359
port = DEF_PGPORT_STR ;
4351
4360
4352
- if ((passfile_env = getenv ("PGPASSFILE" )) != NULL )
4353
- /* use the literal path from the environment, if set */
4354
- strlcpy (pgpassfile , passfile_env , sizeof (pgpassfile ));
4355
- else
4356
- {
4357
- char homedir [MAXPGPATH ];
4358
-
4359
- if (!pqGetHomeDirectory (homedir , sizeof (homedir )))
4360
- return NULL ;
4361
- snprintf (pgpassfile , MAXPGPATH , "%s/%s" , homedir , PGPASSFILE );
4362
- }
4361
+ if (!getPgPassFilename (pgpassfile ))
4362
+ return NULL ;
4363
4363
4364
4364
/* If password file cannot be opened, ignore it. */
4365
4365
if (stat (pgpassfile , & stat_buf ) != 0 )
@@ -4426,6 +4426,51 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
4426
4426
#undef LINELEN
4427
4427
}
4428
4428
4429
+
4430
+ static bool getPgPassFilename (char * pgpassfile )
4431
+ {
4432
+ char * passfile_env ;
4433
+
4434
+ if ((passfile_env = getenv ("PGPASSFILE" )) != NULL )
4435
+ /* use the literal path from the environment, if set */
4436
+ strlcpy (pgpassfile , passfile_env , MAXPGPATH );
4437
+ else
4438
+ {
4439
+ char homedir [MAXPGPATH ];
4440
+
4441
+ if (!pqGetHomeDirectory (homedir , sizeof (homedir )))
4442
+ return false;
4443
+ snprintf (pgpassfile , MAXPGPATH , "%s/%s" , homedir , PGPASSFILE );
4444
+ }
4445
+ return true;
4446
+ }
4447
+
4448
+ /*
4449
+ * If the connection failed, we should mention if
4450
+ * we got the password from .pgpass in case that
4451
+ * password is wrong.
4452
+ */
4453
+ static void
4454
+ dot_pg_pass_warning (PGconn * conn )
4455
+ {
4456
+ /* If it was 'invalid authorization', add .pgpass mention */
4457
+ if (conn -> dot_pgpass_used && conn -> password_needed && conn -> result &&
4458
+ /* only works with >= 9.0 servers */
4459
+ strcmp (PQresultErrorField (conn -> result , PG_DIAG_SQLSTATE ),
4460
+ ERRCODE_INVALID_PASSWORD ) == 0 )
4461
+ {
4462
+ char pgpassfile [MAXPGPATH ];
4463
+
4464
+ if (!getPgPassFilename (pgpassfile ))
4465
+ return ;
4466
+ appendPQExpBufferStr (& conn -> errorMessage ,
4467
+ libpq_gettext ("password retrieved from " ));
4468
+ appendPQExpBufferStr (& conn -> errorMessage , pgpassfile );
4469
+ appendPQExpBufferChar (& conn -> errorMessage , '\n' );
4470
+ }
4471
+ }
4472
+
4473
+
4429
4474
/*
4430
4475
* Obtain user's home directory, return in given buffer
4431
4476
*
0 commit comments