mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Add libpq warning message if the .pgpass-retrieved password fails.
Add ERRCODE_INVALID_PASSWORD sqlstate error code.
This commit is contained in:
parent
8b2ae44dc8
commit
a6c1cea2b7
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.28 2009/12/07 05:22:21 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.29 2010/03/13 14:55:57 momjian Exp $ -->
|
||||||
|
|
||||||
<appendix id="errcodes-appendix">
|
<appendix id="errcodes-appendix">
|
||||||
<title><productname>PostgreSQL</productname> Error Codes</title>
|
<title><productname>PostgreSQL</productname> Error Codes</title>
|
||||||
@ -761,6 +761,12 @@
|
|||||||
<entry>invalid_authorization_specification</entry>
|
<entry>invalid_authorization_specification</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>28P01</literal></entry>
|
||||||
|
<entry>INVALID PASSWORD</entry>
|
||||||
|
<entry>invalid_password</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry spanname="span13"><emphasis role="bold">Class 2B — Dependent Privilege Descriptors Still Exist</></entry>
|
<entry spanname="span13"><emphasis role="bold">Class 2B — Dependent Privilege Descriptors Still Exist</></entry>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.195 2010/02/26 02:00:42 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.196 2010/03/13 14:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -232,6 +232,7 @@ static void
|
|||||||
auth_failed(Port *port, int status)
|
auth_failed(Port *port, int status)
|
||||||
{
|
{
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we failed due to EOF from client, just quit; there's no point in
|
* If we failed due to EOF from client, just quit; there's no point in
|
||||||
@ -269,6 +270,8 @@ auth_failed(Port *port, int status)
|
|||||||
case uaMD5:
|
case uaMD5:
|
||||||
case uaPassword:
|
case uaPassword:
|
||||||
errstr = gettext_noop("password authentication failed for user \"%s\"");
|
errstr = gettext_noop("password authentication failed for user \"%s\"");
|
||||||
|
/* We use it to indicate if a .pgpass password failed. */
|
||||||
|
errcode_return = ERRCODE_INVALID_PASSWORD;
|
||||||
break;
|
break;
|
||||||
case uaPAM:
|
case uaPAM:
|
||||||
errstr = gettext_noop("PAM authentication failed for user \"%s\"");
|
errstr = gettext_noop("PAM authentication failed for user \"%s\"");
|
||||||
@ -285,7 +288,7 @@ auth_failed(Port *port, int status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
(errcode(errcode_return),
|
||||||
errmsg(errstr, port->user_name)));
|
errmsg(errstr, port->user_name)));
|
||||||
/* doesn't return */
|
/* doesn't return */
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2010, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2010, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.31 2010/01/02 16:58:10 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.32 2010/03/13 14:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -194,6 +194,7 @@
|
|||||||
|
|
||||||
/* Class 28 - Invalid Authorization Specification */
|
/* Class 28 - Invalid Authorization Specification */
|
||||||
#define ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION MAKE_SQLSTATE('2','8', '0','0','0')
|
#define ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION MAKE_SQLSTATE('2','8', '0','0','0')
|
||||||
|
#define ERRCODE_INVALID_PASSWORD MAKE_SQLSTATE('2','8', 'P','0','1')
|
||||||
|
|
||||||
/* Class 2B - Dependent Privilege Descriptors Still Exist */
|
/* Class 2B - Dependent Privilege Descriptors Still Exist */
|
||||||
#define ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST MAKE_SQLSTATE('2','B', '0','0','0')
|
#define ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST MAKE_SQLSTATE('2','B', '0','0','0')
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.389 2010/03/03 20:31:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.390 2010/03/13 14:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -91,6 +91,9 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
|
|||||||
*/
|
*/
|
||||||
#define ERRCODE_APPNAME_UNKNOWN "42704"
|
#define ERRCODE_APPNAME_UNKNOWN "42704"
|
||||||
|
|
||||||
|
/* This is part of the protocol so just define it */
|
||||||
|
#define ERRCODE_INVALID_PASSWORD "28P01"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fall back options if they are not specified by arguments or defined
|
* fall back options if they are not specified by arguments or defined
|
||||||
* by environment variables
|
* by environment variables
|
||||||
@ -284,6 +287,8 @@ static int parseServiceFile(const char *serviceFile,
|
|||||||
static char *pwdfMatchesString(char *buf, char *token);
|
static char *pwdfMatchesString(char *buf, char *token);
|
||||||
static char *PasswordFromFile(char *hostname, char *port, char *dbname,
|
static char *PasswordFromFile(char *hostname, char *port, char *dbname,
|
||||||
char *username);
|
char *username);
|
||||||
|
static bool getPgPassFilename(char *pgpassfile);
|
||||||
|
static void dot_pg_pass_warning(PGconn *conn);
|
||||||
static void default_threadlock(int acquire);
|
static void default_threadlock(int acquire);
|
||||||
|
|
||||||
|
|
||||||
@ -652,6 +657,8 @@ connectOptions2(PGconn *conn)
|
|||||||
conn->dbName, conn->pguser);
|
conn->dbName, conn->pguser);
|
||||||
if (conn->pgpass == NULL)
|
if (conn->pgpass == NULL)
|
||||||
conn->pgpass = strdup(DefaultPassword);
|
conn->pgpass = strdup(DefaultPassword);
|
||||||
|
else
|
||||||
|
conn->dot_pgpass_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2133,6 +2140,8 @@ keep_going: /* We will come back to here until there is
|
|||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
|
|
||||||
|
dot_pg_pass_warning(conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We used to close the socket at this point, but that makes it awkward
|
* We used to close the socket at this point, but that makes it awkward
|
||||||
* for those above us if they wish to remove this socket from their own
|
* for those above us if they wish to remove this socket from their own
|
||||||
@ -2191,6 +2200,7 @@ makeEmptyPGconn(void)
|
|||||||
conn->verbosity = PQERRORS_DEFAULT;
|
conn->verbosity = PQERRORS_DEFAULT;
|
||||||
conn->sock = -1;
|
conn->sock = -1;
|
||||||
conn->password_needed = false;
|
conn->password_needed = false;
|
||||||
|
conn->dot_pgpass_used = false;
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
conn->allow_ssl_try = true;
|
conn->allow_ssl_try = true;
|
||||||
conn->wait_ssl_try = false;
|
conn->wait_ssl_try = false;
|
||||||
@ -4323,7 +4333,6 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
char pgpassfile[MAXPGPATH];
|
char pgpassfile[MAXPGPATH];
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
char *passfile_env;
|
|
||||||
|
|
||||||
#define LINELEN NAMEDATALEN*5
|
#define LINELEN NAMEDATALEN*5
|
||||||
char buf[LINELEN];
|
char buf[LINELEN];
|
||||||
@ -4349,17 +4358,8 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
|
|||||||
if (port == NULL)
|
if (port == NULL)
|
||||||
port = DEF_PGPORT_STR;
|
port = DEF_PGPORT_STR;
|
||||||
|
|
||||||
if ((passfile_env = getenv("PGPASSFILE")) != NULL)
|
if (!getPgPassFilename(pgpassfile))
|
||||||
/* use the literal path from the environment, if set */
|
|
||||||
strlcpy(pgpassfile, passfile_env, sizeof(pgpassfile));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char homedir[MAXPGPATH];
|
|
||||||
|
|
||||||
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
snprintf(pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If password file cannot be opened, ignore it. */
|
/* If password file cannot be opened, ignore it. */
|
||||||
if (stat(pgpassfile, &stat_buf) != 0)
|
if (stat(pgpassfile, &stat_buf) != 0)
|
||||||
@ -4426,6 +4426,51 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
|
|||||||
#undef LINELEN
|
#undef LINELEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool getPgPassFilename(char *pgpassfile)
|
||||||
|
{
|
||||||
|
char *passfile_env;
|
||||||
|
|
||||||
|
if ((passfile_env = getenv("PGPASSFILE")) != NULL)
|
||||||
|
/* use the literal path from the environment, if set */
|
||||||
|
strlcpy(pgpassfile, passfile_env, MAXPGPATH);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char homedir[MAXPGPATH];
|
||||||
|
|
||||||
|
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
|
||||||
|
return false;
|
||||||
|
snprintf(pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the connection failed, we should mention if
|
||||||
|
* we got the password from .pgpass in case that
|
||||||
|
* password is wrong.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dot_pg_pass_warning(PGconn *conn)
|
||||||
|
{
|
||||||
|
/* If it was 'invalid authorization', add .pgpass mention */
|
||||||
|
if (conn->dot_pgpass_used && conn->password_needed && conn->result &&
|
||||||
|
/* only works with >= 9.0 servers */
|
||||||
|
strcmp(PQresultErrorField(conn->result, PG_DIAG_SQLSTATE),
|
||||||
|
ERRCODE_INVALID_PASSWORD) == 0)
|
||||||
|
{
|
||||||
|
char pgpassfile[MAXPGPATH];
|
||||||
|
|
||||||
|
if (!getPgPassFilename(pgpassfile))
|
||||||
|
return;
|
||||||
|
appendPQExpBufferStr(&conn->errorMessage,
|
||||||
|
libpq_gettext("password retrieved from "));
|
||||||
|
appendPQExpBufferStr(&conn->errorMessage, pgpassfile);
|
||||||
|
appendPQExpBufferChar(&conn->errorMessage, '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain user's home directory, return in given buffer
|
* Obtain user's home directory, return in given buffer
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.149 2010/02/26 02:01:33 momjian Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.150 2010/03/13 14:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -343,6 +343,7 @@ struct pg_conn
|
|||||||
ProtocolVersion pversion; /* FE/BE protocol version in use */
|
ProtocolVersion pversion; /* FE/BE protocol version in use */
|
||||||
int sversion; /* server version, e.g. 70401 for 7.4.1 */
|
int sversion; /* server version, e.g. 70401 for 7.4.1 */
|
||||||
bool password_needed; /* true if server demanded a password */
|
bool password_needed; /* true if server demanded a password */
|
||||||
|
bool dot_pgpass_used; /* true if used .pgpass */
|
||||||
bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */
|
bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */
|
||||||
bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */
|
bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2010, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2010, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.20 2010/01/02 16:58:13 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.21 2010/03/13 14:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -367,6 +367,10 @@
|
|||||||
"invalid_authorization_specification", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION
|
"invalid_authorization_specification", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"invalid_password", ERRCODE_INVALID_PASSWORD
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"dependent_privilege_descriptors_still_exist", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST
|
"dependent_privilege_descriptors_still_exist", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user